Skip to main content

S3 Assessment Workflow

This is the supported S3 MVP workflow for the current CLI surface.

Golden Path

extract (external) -> validate -> apply -> verify

1) Extract observations from an offline AWS snapshot

Use an extractor (any language) to produce obs.v0.1 JSON from your AWS snapshot directory. See Building an Extractor for a jumpstart template, or use an existing extractor such as stave-extractor.

Input:

  • Snapshot directory with AWS CLI exports (list-buckets.json, get-bucket-* files)

Output:

  • observations.json (obs.v0.1)

2) Evaluate observations against the S3 control pack

stave apply --profile aws-s3 --input observations.json --include-all --now 2026-01-15T00:00:00Z > evaluation.json

Input:

  • observations.json
  • Built-in S3 controls under controls/s3

Output:

  • evaluation.json (out.v0.1)
  • Exit code 3 when violations are found

3) Verify remediation (before vs after)

stave check \
--before ./obs-before \
--after ./obs-after \
--controls ./controls/s3 \
--now 2026-01-15T00:00:00Z \
--out ./output

Input:

  • Before/after observations directories
  • Controls directory

Output:

  • stdout JSON verification summary
  • output/verification.json when --out is set

Optional: generate enforcement templates

From an out.v0.1 evaluation file, stave enforce produces deterministic remediation artifacts — either Public Access Block Terraform or a Service Control Policy:

# Public Access Block (Terraform)
stave enforce --in evaluation.json --out ./output --mode pab

# Service Control Policy (JSON)
stave enforce --in evaluation.json --out ./output --mode scp

Output:

  • PAB mode: output/enforcement/aws/pab.tf
  • SCP mode: output/enforcement/aws/scp.json

What the S3 pack covers

The aws-s3 profile evaluates 67 controls across these categories:

CategoryControlsWhat they detect
Public exposurePUBLIC.001–008, PUBLIC.LIST, PUBLIC.PREFIXPublic read, list, write via policy or ACL
ACL misconfigurationACL.ESCALATION, ACL.FULLCONTROL, ACL.RECON, ACL.WRITE, ACL.OBJECTBucket and object-level ACL grants
Access controlACCESS.001–003, AUTH.READ, AUTH.WRITE, PRESIGNED, ACCESS.GRANTSCross-account, wildcard actions, presigned URLs
EncryptionENCRYPT.001–004At-rest, in-transit, KMS for PHI/sensitive data
Block Public AccessCONTROLS.001, ACCOUNT.PAB.001Bucket-level and account-level PAB
Object OwnershipOWNERSHIP.001BucketOwnerEnforced to disable ACLs
Logging & auditLOG.001, AUDIT.OBJECTLEVEL.001Server access logging, CloudTrail object-level
Sensitive data discoveryDETECT.MACIE.001–002Macie enablement, automated discovery
Versioning & integrityVERSION.001–002, MFADELETE.001, LOCK.001–003Versioning, MFA delete, Object Lock
ReplicationREPLICATION.001–003Replication enabled, cross-region, destination encrypted
Lifecycle & retentionLIFECYCLE.001–002Lifecycle rules, PHI minimum retention
VisibilityINVENTORY.001S3 Inventory for bucket content auditing
GovernanceGOVERNANCE.001, REGION.001Data classification tags, approved regions
NetworkNETWORK.001, NETWORK.POLICY.001, NETWORK.VPC.001, MRAP.*VPC endpoints, MRAP policies
CDN & takeoverCDN.OAC.001, CDN.EXPOSURE.001, BUCKET.TAKEOVER.001, DANGLING.ORIGIN.001CloudFront OAC, dangling origins
Write scopeWRITE.SCOPE.001, WRITE.CONTENT.001Signed upload key/content-type binding
Tenant isolationTENANT.ISOLATION.001Prefix-scoped multi-tenant access
Vendor delegationDELEGATION.{KNOWN,SCOPE,LIFECYCLE,REVOCABLE,ESCALATION}.001Supply-chain governance of external principals with control rights

Vendor delegation governance

Five controls under controls/s3/delegation/ plus one compound chain detect the "your bucket has an owner, the vendor has control" pattern — risk transferred to a weaker party without safety continuity.

ControlDetects
CTL.S3.DELEGATION.KNOWN.001External principal not in controldata/taxonomy/vendor_registry.yaml
CTL.S3.DELEGATION.SCOPE.001Actual permissions exceed the vendor's declared scope
CTL.S3.DELEGATION.LIFECYCLE.001Vendor review_date in the past
CTL.S3.DELEGATION.REVOCABLE.001Customer cannot unilaterally revoke vendor access
CTL.S3.DELEGATION.ESCALATION.001Vendor can make bucket public (PutBucketPolicy / PutBucketAcl)

Compound chain: delegated_control_failure — threshold 3 of 5, CRITICAL. Complementary to vendor_attack_path (confused-deputy); same bucket can fire both.

The collector populates properties.delegation.* booleans by comparing the bucket policy against vendor_registry.yaml. Single-snapshot detection: the predicates fire whether a declaration was removed yesterday or never applied.

Worked demo: examples/s3-delegation-failure/run.sh. See examples/s3-delegation-failure/multi-engine-results.md for CEL + chain + Clingo + Soufflé output. The Soufflé program examples/souffle-reachability/delegation-reach.dl enumerates per-principal excessive_reach rows and counts; the Clingo rules in examples/clingo-constraints/ai-delegation-shadow.lp name every (bucket, principal, reason) triple.

Notes

  • Offline by design: reads local files only.
  • Deterministic in CI: always set --now.
  • For troubleshooting unexpected results, run stave diagnose.