Skip to main content

Observation Export Schema

This page is the field-by-field reference for the S3 resource property groups carried in an obs.v0.1 observation. Each group maps to a set of AWS API calls or Terraform resource attributes.

For the schema envelope (top-level structure, the assets/identities arrays, and validation rules) see Observation Schema (obs.v0.1). For step-by-step recipes that produce these snapshots, see Create Observation Snapshots.

Observation file shape

Every observation file follows this structure:

{
"schema_version": "obs.v0.1",
"generated_by": {
"source_type": "aws-s3-snapshot",
"tool": "aws-cli",
"tool_version": "2.15.0"
},
"captured_at": "2026-01-15T00:00:00Z",
"resources": [
{
"id": "res:aws:s3:bucket:acme-patient-records",
"type": "storage_bucket",
"vendor": "aws",
"properties": {
"storage": {
"kind": "bucket",
"name": "acme-patient-records",
"visibility": { "public_read": false, "public_list": false },
"controls": { "public_access_fully_blocked": true },
"encryption": { "at_rest_enabled": true, "algorithm": "aws:kms" }
}
}
},
{
"id": "res:aws:s3:bucket:acme-static-assets",
"type": "storage_bucket",
"vendor": "aws",
"properties": {
"storage": {
"kind": "bucket",
"name": "acme-static-assets",
"visibility": { "public_read": true, "public_list": false },
"controls": { "public_access_fully_blocked": false },
"encryption": { "at_rest_enabled": true, "algorithm": "AES256" }
}
}
}
]
}
FieldRequiredDescription
schema_versionyesMust be "obs.v0.1"
generated_bynoDescribes the tool that created this snapshot
generated_by.source_typenoIdentifier for the data source (e.g., "aws-s3-snapshot", "terraform.plan_json")
captured_atyesRFC 3339 timestamp of when this snapshot was taken
resourcesyesArray of resource objects (S3 buckets)
identitiesnoArray of IAM identity objects (for tenant isolation controls)

Key constraints:

  • Each file represents a single point in time (captured_at)
  • The top-level object must contain only these fields — the schema rejects unknown properties (additionalProperties: false)
  • Place multiple snapshot files in a directory, one per timestamp
  • File names do not matter — Stave sorts by captured_at

Resource object

Each entry in the resources array describes one S3 bucket:

{
"id": "res:aws:s3:bucket:acme-patient-records",
"type": "storage_bucket",
"vendor": "aws",
"properties": {
"storage": {
"kind": "bucket",
"name": "acme-patient-records",
"visibility": { "public_read": false, "public_list": false },
"controls": { "public_access_fully_blocked": true },
"encryption": { "at_rest_enabled": true, "algorithm": "aws:kms" },
"versioning": { "enabled": true },
"logging": { "enabled": true, "target_bucket": "acme-access-logs", "target_prefix": "patient-records/" }
}
}
}
FieldRequiredDescription
idyesUnique resource identifier
typeyesResource type — use "storage_bucket" for S3
vendoryesCloud provider — use "aws" for S3
propertiesyesNested object containing the configuration data Stave evaluates

S3 property groups

The properties.storage object contains the bucket configuration that controls check. Each group maps to a set of AWS API calls or Terraform resource attributes.

Core

FieldTypeDescription
kindstringAlways "bucket" for S3
namestringBucket name
tagsobjectKey-value tag pairs
"kind": "bucket",
"name": "acme-patient-records",
"tags": {
"data-classification": "phi",
"Environment": "production"
}

Visibility

Describes whether the bucket is publicly accessible and through which mechanism.

FieldTypeSource
visibility.public_readbooleanBucket policy or ACL grants public read
visibility.public_listbooleanBucket policy grants public listing
visibility.public_writebooleanBucket policy or ACL grants public write
visibility.public_read_via_policybooleanPublic read specifically via bucket policy
visibility.public_read_via_aclbooleanPublic read specifically via ACL
visibility.public_list_via_policybooleanPublic listing specifically via bucket policy
"visibility": {
"public_read": true,
"public_list": false,
"public_write": false,
"public_read_via_policy": true,
"public_read_via_acl": false,
"public_list_via_policy": false
}

Controls

Public access block settings at the bucket and account level.

FieldTypeSource
controls.public_access_fully_blockedbooleanAll four PublicAccessBlock settings are true
controls.account_public_access_fully_blockedbooleanAccount-level public access block is fully enabled
controls.public_access_block.block_public_aclsbooleanBlockPublicAcls setting
controls.public_access_block.ignore_public_aclsbooleanIgnorePublicAcls setting
controls.public_access_block.block_public_policybooleanBlockPublicPolicy setting
controls.public_access_block.restrict_public_bucketsbooleanRestrictPublicBuckets setting
"controls": {
"public_access_fully_blocked": false,
"account_public_access_fully_blocked": false,
"public_access_block": {
"block_public_acls": true,
"ignore_public_acls": true,
"block_public_policy": false,
"restrict_public_buckets": false
}
}

Encryption

FieldTypeSource
encryption.at_rest_enabledbooleanServer-side encryption is configured
encryption.algorithmstring"AES256", "aws:kms", or "" if disabled
encryption.kms_key_idstringKMS key ARN if using KMS encryption
encryption.in_transit_enforcedbooleanBucket policy requires HTTPS (aws:SecureTransport)
"encryption": {
"at_rest_enabled": true,
"algorithm": "aws:kms",
"kms_key_id": "arn:aws:kms:us-east-1:123456789012:key/mrk-abc123",
"in_transit_enforced": true
}

Versioning

FieldTypeSource
versioning.enabledbooleanObject versioning is enabled
versioning.mfa_delete_enabledbooleanMFA Delete protection is enabled
"versioning": {
"enabled": true,
"mfa_delete_enabled": false
}

Logging

FieldTypeSource
logging.enabledbooleanServer access logging is configured
logging.target_bucketstringDestination bucket for logs
logging.target_prefixstringPrefix for log objects
"logging": {
"enabled": true,
"target_bucket": "acme-access-logs",
"target_prefix": "patient-records/"
}

Access

Cross-account and wildcard policy analysis.

FieldTypeSource
access.has_external_accessbooleanBucket policy grants access to external accounts
access.external_accountsarray or nullList of external account ARNs
access.has_wildcard_policybooleanBucket policy contains wildcard (*) principals
"access": {
"has_external_access": true,
"external_accounts": ["arn:aws:iam::987654321098:root"],
"has_wildcard_policy": false
}

Policy (network scope)

FieldTypeSource
policy.has_ip_conditionbooleanPolicy includes IP address conditions
policy.has_vpc_conditionbooleanPolicy includes VPC endpoint conditions
policy.effective_network_scopestring"public", "vpc-restricted", "ip-restricted", or ""
"policy": {
"has_ip_condition": false,
"has_vpc_condition": true,
"effective_network_scope": "vpc-restricted"
}

Lifecycle

FieldTypeSource
lifecycle.rules_configuredbooleanAt least one lifecycle rule exists
lifecycle.rule_countintegerNumber of lifecycle rules
lifecycle.has_expirationbooleanAny rule includes object expiration
lifecycle.has_transitionbooleanAny rule includes storage class transition
lifecycle.min_expiration_daysintegerShortest expiration period across all rules
lifecycle.has_noncurrent_version_expirationbooleanAny rule expires noncurrent object versions
"lifecycle": {
"rules_configured": true,
"rule_count": 2,
"has_expiration": true,
"has_transition": true,
"min_expiration_days": 90,
"has_noncurrent_version_expiration": true
}

Object Lock

FieldTypeSource
object_lock.enabledbooleanS3 Object Lock is enabled
object_lock.modestring"COMPLIANCE", "GOVERNANCE", or ""
object_lock.retention_daysintegerDefault retention period in days
"object_lock": {
"enabled": true,
"mode": "COMPLIANCE",
"retention_days": 2555
}

Identity object

The optional identities array describes IAM principals. Tenant isolation controls use this data:

{
"id": "arn:aws:iam::123456789012:role/data-pipeline",
"type": "iam_role",
"vendor": "aws",
"owner": "data-team",
"purpose": "ETL pipeline",
"grants": { "has_wildcard": false },
"scope": { "distinct_systems": 1, "distinct_resource_groups": 2 }
}

See also