A practical guide to making your infrastructure pipeline the hardest thing to breach in your organization
Introduction: Why Security as Code, and Why Now
At re:Invent in December 2025, AWS announced a family of autonomous AI services aimed squarely at software delivery and operations: Kiro, an agent that turns specifications into working code; the AWS Security Agent, which performs design and code reviews and runs penetration tests on demand; and the AWS DevOps Agent, which investigates incidents and drafts mitigation plans. The direction of travel is unmistakable: code will increasingly be written, reviewed, and operated by machines — at machine speed.
That is exhilarating for velocity and terrifying for security. When an agent can open a pull request that provisions a new VPC at 3 a.m., the only thing standing between "autonomous productivity" and "autonomous incident" is whether your guardrails are as automated as the agents themselves.
This is exactly where Security as Code (SaC) comes in. Security as Code is the discipline of expressing security controls, compliance rules, and governance policies as version-controlled, testable, machine-enforceable code — embedded directly into the Infrastructure as Code (IaC) lifecycle. If Terraform is how you build on AWS, then Security as Code is how you make sure everything Terraform builds is safe by construction.
And the fleet keeps growing. AgentCore payments reached general availability in August 2026, giving agents the ability to pay for APIs, MCP servers, and content through wallets built with Coinbase and Stripe, over the open x402 protocol and the Machine Payments Protocol (MPP), with configurable spending limits. Weeks later, in October 2026, AWS announced the preview of the AWS Well-Architected Agent — an AI that continuously analyzes your environment, and even your Terraform code, against the Well-Architected Framework and hands back ready-to-apply fixes. Agents can now write code, review code, operate systems, spend money, and audit architecture.
This article walks through the full operating model: the layered architecture, the Terraform pipeline, policy-as-code tooling, AWS-native detection, drift management, how this expanding AWS agent fleet fits into a Security-as-Code world, and — just as important — where the agents still fall short.
1. What Security as Code Actually Means — and Who It Serves
Security as Code applies the same engineering rigor to security that IaC applied to infrastructure:
| Traditional Security | Security as Code |
|---|---|
| PDF policy documents | Version-controlled policy files (Rego, Sentinel, YAML) |
| Manual review before go-live | Automated gates in CI/CD on every plan |
| Quarterly audits | Continuous compliance evaluation |
| Security team as bottleneck | Security team as policy authors and platform owners |
| Findings discovered post-incident | Violations blocked pre-deployment |
The core idea: the pipeline is the control plane. Every Terraform plan passes through automated inspection before any human or agent is allowed to apply it. Security stops being a department you visit and becomes a property of the delivery system itself.
Notably, AWS itself has codified this direction. In the latest refresh of the AWS Well-Architected Framework's Security pillar, best practice SEC11-BP04 was renamed from "Manual code reviews" to "Conduct code reviews" — explicitly recognizing automated static/dynamic analysis, vulnerability scanning, and programmatic CI/CD checks as first-class review mechanisms. Shift-left is no longer a suggestion; it is the reference architecture.
1.1 The customer lens: every policy is a promise
Your customers will never read a Rego policy — but they experience every single one. The discipline that separates mature teams is being able to name, for each policy in the repo, the customer promise it keeps:
- Encryption-at-rest and public-access policies are your answer to "is my data safe?" — and to the procurement security questionnaire standing between you and every enterprise deal. When those controls are code, answering that questionnaire means exporting artifacts, not scheduling meetings.
- Drift detection, runtime guardrails, and the DevOps Agent are, from the customer's side, simply uptime. Customers experience security failures as outages, leaked data, and broken trust — they don't care which of your four layers failed, only that one failing wasn't enough.
- AgentCore payments limits are a trust feature you can print on a pricing page: "an agent will never spend your money outside its approved budget." In an agentic product, the spending policy is the customer contract.
- Compliance as code (Config conformance packs mapped to NIST and CIS benchmarks) compresses audit cycles — which means Security as Code is a revenue accelerator, not a cost center. Sales teams feel this before security teams do.
The test is simple: if you can't trace a policy to a customer promise, question why the policy exists.
1.2 The developer lens: adoption is the real KPI
A security gate developers route around is worse than no gate — it gives you the illusion of control with none of the coverage. Security as Code succeeds only if developers choose it, which makes developer experience a security property:
- Feedback where they already work. Violations must surface as PR comments in seconds, not as security-review tickets in weeks. The pipeline in Section 4 posts the plan, the violations, and — critically — how to fix each one directly onto the pull request.
- Error messages that teach, not just deny. Compare:
- Bad:
Policy SG-001: DENIED. - Good:
aws_security_group_rule.web: ingress 0.0.0.0/0 on port 22 is forbidden. Fix: scope cidr_blocks to the VPN range (e.g., 10.0.0.0/16) or use SSM Session Manager via the secure-bastion module. Why: internet-exposed SSH is a common breach vector. Policy: policies/network.rego — questions? #security-help - Golden paths over gatekeeping. Hardened internal modules (Section 3.3) should make the compliant way the fastest way: copy-paste examples, sane secure defaults, and a self-service module catalog. Developers who can ship in five minutes using the secure module won't spend two hours hand-rolling an insecure one.
- Escape hatches without shame. Soft-mandatory policies plus a time-boxed exception workflow beat hard walls that encourage shadow IT. Exceptions are data — their rate and age are metrics (Section 10), and every recurring exception is a signal the policy or the golden path needs work.
- A speed budget. If the static-analysis stage takes longer than ~2 minutes, developers will batch, bypass, or bypass-by-force-push. Cache providers, parallelize scans, fail fast on the criticals.
- Developers as policy co-authors. A developer who can open a PR against a policy — propose a better rule, refine a message, add a test — owns the control. Policies written with the people they govern get followed; policies handed down get bypassed.
The cultural test: if your security tooling makes developers measurably faster — fewer review round-trips, fewer rollback-induced rewrites, fewer 2 a.m. hotfixes — adoption stops being a management problem.
2. The Layered Defense Model
A mature Terraform-on-AWS security posture has four pipeline layers plus one organizational backstop. Relying on any single one is how breaches happen.
┌─────────────────────────────────────────────────────────────┐ │ Layer 4: DETECT & RESPOND (runtime, continuous) │ │ AWS Config · Security Hub CSPM · GuardDuty · CloudTrail · │ │ IAM Access Analyzer · Inspector · AWS DevOps Agent · │ │ Well-Architected Agent │ ├─────────────────────────────────────────────────────────────┤ │ Layer 3: ENFORCE AT APPLY (platform gate) │ │ Sentinel / OPA policy evaluation on the plan, approvals, │ │ RBAC, audit logs (HCP Terraform, Spacelift, Atlantis…) │ ├─────────────────────────────────────────────────────────────┤ │ Layer 2: SCAN IN CI (pull request) │ │ Trivy (absorbed tfsec) · Checkov · OPA against plan JSON ·│ │ secrets scanning │ ├─────────────────────────────────────────────────────────────┤ │ Layer 1: PREVENT AT AUTHORING (developer's machine) │ │ pre-commit hooks · secure module standards · IDE linting │ ├─────────────────────────────────────────────────────────────┤ │ Layer 0: ORGANIZATIONAL GUARDRAILS (account/OU level) │ │ SCPs · RCPs · permission boundaries │ └─────────────────────────────────────────────────────────────┘ Each layer catches what the previous one missed — and each layer is itself code, reviewed and versioned like application code.
Layer 0 matters because Layers 1–4 are all bypassable by credentials. Anyone with valid console or CLI access can change infrastructure without ever touching your pipeline. Service Control Policies (SCPs), Resource Control Policies (RCPs), and permission boundaries are the backstop that makes even a leaked admin credential unable to disable CloudTrail, open a security group to the world, or leave the approved regions. Deploy them with Terraform from a dedicated governance account, and treat changes to them with the same review rigor as changes to production.
Layer 1 is advisory by design. git commit --no-verify skips pre-commit hooks entirely, and a developer can always choose not to install them. Pre-commit hooks exist to shorten the feedback loop, not to enforce. The same checks must run again in CI (Layer 2), where they cannot be skipped.
3. Terraform Operations: Securing the Foundation
Before any policy tooling matters, the Terraform operating model itself must be hardened. Most real-world Terraform incidents are not exotic — they are leaked state files, over-privileged CI roles, and hand-edited consoles.
3.1 State file security
The state file is a map of your entire infrastructure and can contain sensitive values. Non-negotiables:
terraform { backend "s3" { bucket = "org-terraform-state-prod" key = "networking/prod/terraform.tfstate" region = "eu-west-1" encrypt = true kms_key_id = "arn:aws:kms:eu-west-1:123456789012:key/1234abcd-12ab-34cd-56ef-123456789012" # SSE-KMS, not just SSE-S3 use_lockfile = true # native S3 locking (stable since Terraform 1.11; experimental in 1.10) } } - Encrypt at rest with SSE-KMS and a key policy that restricts usage to the CI/CD execution role. (
encrypt = truealone only gives you SSE-S3.) - Enable bucket versioning so a corrupted or maliciously overwritten state file can be recovered.
- Lock the state — use the native S3 lockfile on current Terraform versions (DynamoDB locking is deprecated). The execution role needs
s3:PutObject/s3:GetObject/s3:DeleteObjecton the state key ands3:PutObject/s3:GetObject/s3:DeleteObjecton*.tflockobjects. - Least-privilege access: only the CI/CD execution role can write state; humans get read access only through audited break-glass paths.
- Never commit state to git. Enforce it with
.gitignoreand a secrets-scanner in CI. - Commit
.terraform.lock.hclso provider versions are pinned and verified, and use write-only attributes and ephemeral resources (Terraform 1.11+) for secrets that should never persist in state — passwords and tokens can be marked write-only so they never appear interraform show, plan output, or the state file.
3.2 The CI/CD role: least privilege or nothing
The pipeline's AWS credentials are the crown jewels:
- Use OIDC federation (e.g., GitHub Actions → AWS IAM role) instead of long-lived access keys.
- Pin the trust policy to the exact subject. The role's trust condition must pin the
subclaim — repository, and ideally branch or environment — not just the organization. Otherwise any workflow in any repo of your GitHub org can assume the role:
"Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", "token.actions.githubusercontent.com:sub": "repo:your-org/your-infra-repo:ref:refs/heads/main" } } - Scope the role to exactly the services each workspace manages, and split roles per environment — the dev apply role should be physically unable to touch prod. Permission boundaries on the role itself add a second ceiling that even a pipeline bug cannot exceed.
3.3 Module governance
Free-form Terraform written per-repo drifts into inconsistency. Instead:
- Publish hardened internal modules (S3 with public access block + KMS, security groups with no
0.0.0.0/0ingress by default, logging enabled everywhere). - Pin module versions by tag, never by branch.
- Enforce secure defaults in the module so the secure path is the easy path — this is what makes Security as Code stick culturally.
- Run the module catalog like a product with developers as customers: copy-paste examples in every README, a searchable catalog, versioned changelogs, and a Slack channel with an SLA. The golden path wins on convenience or it doesn't win.
4. The Pipeline: Where Security as Code Lives
Here is a reference GitHub Actions design implementing Layer 2 (scan) feeding into Layer 3 (enforce). It uses two workflows: one on pull requests (scan + plan + policy), one on merges to main (re-plan, policy-check again, apply). The apply workflow re-plans rather than reusing the PR artifact — a PR-time plan can be stale by merge time, and plan files contain sensitive values, so passing them between runners via artifacts requires encryption at rest and careful scoping. Re-planning on the protected branch is simpler and safe because the branch itself is protected.
# .github/workflows/terraform-pr.yml name: terraform-pr on: pull_request: branches: [main] permissions: id-token: write # OIDC to AWS — no stored credentials contents: read pull-requests: write env: TF_DIR: ./terraform jobs: static-analysis: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.2.2 — pin actions to SHAs - uses: hashicorp/setup-terraform@b9a1b7b2b3c6f8d4e5a6b7c8d9e0f1a2b3c4d5e6 # pin to SHA with: terraform_version: 1.11.x - name: Terraform fmt & validate working-directory: ${{ env.TF_DIR }} run: | terraform fmt -check -recursive terraform init -backend=false -input=false terraform validate - name: Trivy IaC scan (tfsec's engine now lives in Trivy) uses: aquasecurity/trivy-action@6e7c7a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7 # pin to SHA with: scan-type: config scan-ref: ${{ env.TF_DIR }} severity: CRITICAL,HIGH exit-code: 1 # fail the PR on high findings - name: Checkov scan uses: bridgecrewio/checkov-action@d0e1f2a3b4c5d6e7f8a9a0b1c2d3e4f5a6b7c8d9 # pin to SHA with: directory: ${{ env.TF_DIR }} framework: terraform soft_fail: false plan-and-policy: needs: static-analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42b034b650 # pin to SHA with: role-to-assume: arn:aws:iam::123456789012:role/terraform-plan-role aws-region: eu-west-1 - uses: hashicorp/setup-terraform@b9a1b7b2b3c6f8d4e5a6b7c8d9e0f1a2b3c4d5e6 with: terraform_version: 1.11.x - uses: open-policy-agent/setup-opa@34a30d5a8f8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f # pin to SHA - name: Plan and export JSON working-directory: ${{ env.TF_DIR }} run: | terraform init -input=false terraform plan -input=false -out=tfplan terraform show -json tfplan > ../plan.json - name: Evaluate OPA policies against the plan run: | # --fail-defined makes opa eval exit non-zero when a deny rule fires. # Plain `opa eval 'data.terraform.deny'` always exits 0 — it only prints. opa eval --fail-defined \ --input plan.json \ --data ./policies/ \ 'data.terraform.deny[_]' - name: Post plan + policy results to PR run: ./scripts/comment-plan.sh # transparency for reviewers # .github/workflows/terraform-main.yml name: terraform-main on: push: branches: [main] permissions: id-token: write contents: read env: TF_DIR: ./terraform jobs: apply: environment: production # requires manual approval — a gate ON TOP of automated gates runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42b034b650 with: role-to-assume: arn:aws:iam::123456789012:role/terraform-apply-role-prod aws-region: eu-west-1 - uses: hashicorp/setup-terraform@b9a1b7b2b3c6f8d4e5a6b7c8d9e0f1a2b3c4d5e6 with: terraform_version: 1.11.x - uses: open-policy-agent/setup-opa@34a30d5a8f8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f # Re-plan on the protected branch: the PR-time plan may be stale by merge # time, and plan files contain sensitive values that shouldn't be passed # between runners as artifacts. - name: Plan, re-check policy, apply working-directory: ${{ env.TF_DIR }} run: | terraform init -input=false terraform plan -input=false -out=tfplan terraform show -json tfplan > ../plan.json cd .. opa eval --fail-defined --input plan.json --data ./policies/ 'data.terraform.deny[_]' cd ${{ env.TF_DIR }} terraform apply -input=false tfplan Key properties of this design:
- Nothing reaches
applywithout passing static analysis and plan-time policy evaluation — twice. - The apply stage consumes a plan generated on the protected branch, not a stale PR artifact — and that plan passes the same policy gate before apply.
- Human approval is a gate on top of automated gates, not a substitute for them.
- Every check is code in the repo — auditable, diffable, reversible.
- Every action is pinned to a commit SHA. Pinning to
@masteror@v4leaves you exposed to tag-movement supply-chain attacks — an indefensible choice in a security article.
5. Policy as Code: The Heart of It All
5.1 Choosing your weapons
| Tool | Category | Best for | Watch out |
|---|---|---|---|
| OPA (Rego) | Policy as code | Vendor-neutral rules evaluated against plan JSON; also covers Kubernetes, APIs, anything JSON | Rego has a learning curve; policies need unit tests |
| HashiCorp Sentinel | Policy as code | Teams on HCP Terraform / Terraform Enterprise; runs natively between plan and apply | HashiCorp ecosystem only; not available for OpenTofu |
| Checkov | Static analysis | Scanning HCL and plan JSON in PRs; huge built-in library mapped to CIS, NIST | Detection only — needs an enforcement layer around it; plan-JSON scans catch resolved values that HCL scans miss |
| Trivy (config) | Static analysis | Fast developer feedback; Aqua folded tfsec's engine into Trivy — use Trivy for new setups | Same as Checkov: a scanner, not a governance platform |
| Static analysis | — | Archived by Tenable in November 2025. Do not adopt; migrate to Checkov, KICS, or Trivy |
The pragmatic pattern most teams converge on: Checkov or Trivy in the PR for fast feedback, OPA or Sentinel at the platform gate before apply. Run Checkov against the plan JSON, not just the raw HCL — plan output has resolved values (variables, module outputs, data sources), which catches misconfigurations that static HCL analysis cannot see.
5.2 Example: a hard-mandatory OPA policy
This Rego policy denies any security group rule that opens SSH or RDP to the world, evaluated against the Terraform plan. It covers all three ways security group ingress can appear in a plan: aws_security_group_rule resources, the newer aws_vpc_security_group_ingress_rule resource, and it is where you would extend coverage to inline ingress blocks in aws_security_group:
package terraform import rego.v1 risky_ports := {22, 3389} open_to_world(a) if "0.0.0.0/0" in a.cidr_blocks open_to_world(a) if a.cidr_ipv4 == "0.0.0.0/0" # aws_vpc_security_group_ingress_rule # A port-range rule hits p if p falls inside [from_port, to_port]. hits_port(a, p) if { a.from_port <= p; a.to_port >= p } # Protocol "-1" (all traffic) reports ports as 0, so range checks miss it. hits_port(a, _) if a.protocol == "-1" hits_port(a, _) if a.ip_protocol == "-1" # aws_vpc_security_group_ingress_rule deny contains msg if { some rc in input.resource_changes rc.type in {"aws_security_group_rule", "aws_vpc_security_group_ingress_rule"} a := rc.change.after object.get(a, "type", "ingress") == "ingress" some p in risky_ports hits_port(a, p) open_to_world(a) msg := sprintf( "%s exposes port %d to the internet. Fix: scope cidr_blocks to your VPN range, or use SSM Session Manager (module: secure-bastion). Why: internet-exposed admin ports are a common breach vector. Policy: policies/network.rego", [rc.address, p], ) } Notice the message itself: it names the resource, states the rule, tells the developer exactly how to fix it, and says why the rule exists. Denial messages are developer experience (Section 1.2) — a policy that blocks without teaching generates tickets; one that teaches generates fixes.
Unit-test your policies. A policy without tests is a bug waiting to block a production deploy at the worst moment:
package terraform_test import rego.v1 import data.terraform test_denies_ssh_to_world if { deny := terraform.deny with input as mock_plan("aws_security_group_rule", 22, "0.0.0.0/0") count(deny) == 1 } test_allows_ssh_to_vpn if { deny := terraform.deny with input as mock_plan("aws_security_group_rule", 22, "10.0.0.0/16") count(deny) == 0 } test_denies_all_traffic_protocol_neg1 if { deny := terraform.deny with input as mock_plan("aws_vpc_security_group_ingress_rule", 0, "0.0.0.0/0") with input.resource_changes[0].change.after as {"protocol": "-1", "cidr_blocks": ["0.0.0.0/0"]} count(deny) > 0 } Run with opa test ./policies/.
5.3 Enforcement levels matter more than tool choice
Sentinel (HashiCorp's policy language) defines three enforcement levels, configured per policy at deploy time rather than inside the policy body:
- Advisory — failures are logged but never block. Perfect for introducing a new policy without breaking anyone's day.
- Soft-mandatory — failures block the run, but an authorized user can override case-by-case. Good for rules with legitimate exceptions (a genuinely public S3 bucket for a static site). Overrides are audited.
- Hard-mandatory — failures block, no exceptions. Reserved for regulatory and existential rules: public SSH, unencrypted databases, data residency violations.
OPA-based platforms vary. Raw OPA has no built-in levels — blocking behavior is whatever your CI step does with the result (e.g., --fail-defined = hard block). Commercial platforms built on OPA (Spacelift, Scalr, env0) implement their own advisory/soft/hard ladders, but the semantics differ per vendor — check your platform's docs rather than assuming Sentinel parity.
Start everything advisory, measure violation rates for 2–4 weeks, then promote. Policies written with developers get followed; policies handed down from on high get bypassed.
5.4 The starter policy set
Every organization should encode these early:
- No public ingress on sensitive ports (22, 3389, database ports).
- Encryption at rest required (S3, EBS, RDS, EFS) with approved KMS keys.
- Mandatory tags:
owner,cost-center,environment,data-classification. - Approved regions only (data residency / GDPR).
- S3 public access block enforced; no public ACLs.
- IAM: no wildcard
Action: *withResource: *on new roles. - Logging enabled: CloudTrail, VPC Flow Logs, ALB access logs.
- Backups configured for stateful resources.
6. The AWS-Native Detection Layer (Layer 4)
Prevention will never be perfect, so the runtime layer must be continuous and — critically — itself deployed by Terraform:
- AWS Config + Config Rules / conformance packs: continuous resource compliance evaluation; deploy a conformance pack (e.g., NIST 800-53 or CIS) via Terraform so compliance is code too.
- AWS Security Hub CSPM: AWS renamed the original Security Hub to Security Hub CSPM and launched a new, separate service under the Security Hub name. The CSPM service remains the findings aggregator with CIS AWS Foundations and FSBP standards — verify which "Security Hub" your automation targets, as APIs and behavior differ between the two.
- Amazon GuardDuty: managed threat detection — flow its findings into Security Hub CSPM.
- AWS CloudTrail: organization-level trail, multi-region, log-file validation, centralized immutable bucket in a dedicated security account.
- IAM Access Analyzer: continuously flags unintended external access and unused access — the automated counterpart to your IAM policies.
- Amazon Inspector: continuous vulnerability scanning of EC2/ECR/Lambda — feeds the same findings hub.
The pattern: Security Hub CSPM as the single pane, EventBridge rules routing critical findings to Slack/PagerDuty and to auto-remediation Lambda functions (e.g., automatically re-enable S3 Block Public Access when Config flags it).
Drift detection
Console clicks happen. Emergencies happen. Detect the delta:
- Schedule a nightly
terraform plan -refresh-only -detailed-exitcodeper workspace. Exit code2means drift — real-world state differs from Terraform state. (A plainplan -detailed-exitcodealso returns2for unapplied config changes, which is noise;-refresh-onlyisolates true drift.) Open a ticket automatically on drift. - If you run HCP Terraform, Spacelift, or env0, use their built-in drift detection and reconciliation runs.
- Rule of thumb: drift is reconciled back through Terraform, never by editing state to match the console unless it's a genuine disaster-recovery import.
7. Where the AWS Agents Fit
The new agents don't replace Security as Code — they make it more necessary and more powerful:
| Agent | Role in a Security-as-Code world |
|---|---|
| Kiro autonomous agent | Generates infrastructure code — which must pass the same pipelines and policies as human code. Agent-authored Terraform gets no special treatment; the pipeline trusts no one. Steering files (.kiro/steering/) encode your module standards so agents write compliant code from the start. |
| AWS Security Agent | Acts as the continuous reviewer: design security reviews, PR analysis against your org's security requirements, and on-demand penetration testing — turning periodic assessments into continuous validation. It complements your OPA/Sentinel gates with semantic, context-aware review. |
| AWS DevOps Agent | The on-call responder: triages incidents, correlates findings, proposes fixes. In a mature setup its incident proposals flow back as pull requests — which pass through the same Security-as-Code pipeline, closing the loop from detection to governed remediation. |
| AgentCore payments | Gives agents wallets to autonomously pay for APIs, MCP servers, and content. Spending limits, approval thresholds, and wallet permissions are policies — manage them as code, audit every transaction, and alert on spend anomalies like any other security signal (see 7.1). |
| AWS Well-Architected Agent | The continuous architecture reviewer: analyzes your environment against Well-Architected best practices across 65+ services and can read your Terraform directly, returning concrete code changes. Route its recommendations through the same PR pipeline — review, scan, policy-check, apply (see 7.2). |
7.1 AgentCore payments: when your agents carry a wallet
AgentCore payments (GA on August 18, 2026) lets agents autonomously execute micro-transactions for paid APIs, MCP servers, and content — wallet infrastructure from Coinbase and Stripe, the open x402 protocol and the Machine Payments Protocol (MPP), authentication via AgentCore Identity, and full transaction visibility through AgentCore Observability. It is among the first times a major cloud platform has made agents economically active — and the Security-as-Code implications are immediate, because every control here is a policy:
- Spending limits are policy. AgentCore enforces deterministic, infrastructure-level numeric limits (e.g., a
maxSpendAmountper session). Treat the configuration of those limits as code: a change to an agent's wallet limit should be a pull request with approvers, not a console edit. - Build semantic guardrails around the numeric limits. The platform gives you amount ceilings, not purpose rules — so wrap it: endpoint allow-lists enforced in your own proxy or gateway layer, per-counterparty limits, purpose-bound budgets ("only pay for threat-intel APIs"), and human-approval thresholds above which autonomy stops. The advisory → soft-mandatory → hard-mandatory ladder from Section 5 applies to money: sub-cent micro-transactions fully autonomous, anything above a defined threshold requires human approval.
- Wallets follow least privilege. Separate wallets per environment and per agent, scoped through AgentCore Identity, so one compromised or malfunctioning agent can only burn its own budget.
- Spend is a security signal. Transaction logs flow into your observability stack; alert on spend-velocity anomalies the way you alert on GuardDuty findings. An agent suddenly paying a brand-new endpoint at 3 a.m. is the financial equivalent of unexpected egress traffic.
- Know the settlement model. Settlement is in USDC on Base and Solana. Wallets can be funded with stablecoins directly or topped up with fiat via debit card — but a fiat-only or compliance-const...