Skip to content

Learn: Self-Service Cloud Resources — reference

A lookup page. The orientation covers the model.

A field on your Environment claim, under each service:

services:
<service>:
serviceAccount: <sa-name>
resources:
<name>: # your logical name → becomes env var + resource suffix
kind: <class> # objectstore | stream | keyvalue | (schema: relational | cache)
engine: <impl> # s3 | sqs | sns | dynamodb
access: read | readwrite
  • kind is the abstract class; engine the concrete implementation; access your intent.
  • Built + live today: s3 (objectstore), sqs + sns (stream), dynamodb (keyvalue) — all four provisioned & ready on preprod (bravo/dispatch/dev).

Generated from access, scoped to that one resource’s ARN, appended to the service’s Pod-Identity RolePolicy. You never author it.

engine read readwrite adds
s3 GetObject, ListBucket, GetBucketLocation PutObject, DeleteObject, AbortMultipartUpload
sqs ReceiveMessage, DeleteMessage, ChangeMessageVisibility, GetQueueAttributes, GetQueueUrl SendMessage
sns GetTopicAttributes, Subscribe, ListSubscriptionsByTopic Publish
dynamodb GetItem, BatchGetItem, Query, Scan, DescribeTable, ConditionCheckItem PutItem, UpdateItem, DeleteItem, BatchWriteItem

The safety floor (below the claim, non-overridable)

Section titled “The safety floor (below the claim, non-overridable)”
  • S3: PublicAccessBlock, TLS-only (DenyInsecureTransport bucket policy), Versioning, OwnershipControls, region-pinned, encrypted.
  • All engines: encrypted + DenyInsecureTransport. Encryption today is service-managed for every engine (SSE-S3 / SSE-SQS / SNS alias/aws/sns / DynamoDB default, zero key ops).

Designed, not yet built: per-tier encryption — elevated/pci/hipaa → a per-team KMS CMK (cryptographic tenancy isolation, key policy scoped to the team’s roles). The Composition currently uses service-managed keys unconditionally; its comments mark the CMK path deferred, so this is not part of the non-overridable floor yet.

A <service>-resources ConfigMap injects the real coordinates as env vars — read these, never hardcode:

BLOB_BUCKET · JOBS_QUEUE_URL · EVENTS_TOPIC_ARN · SESSIONS_TABLE (⇒ <NAME>_<SUFFIX> per resource)

Naming: refplat-<team>-<product>-<stage>-<name>-<hash> (deterministic, ≤63-char safe, collision-resistant).

All produce the same governed claim → same validation → same realization. Built: PR-as-code, Backstage form. Designed: a natural-language agent. New front doors never touch the safety floor.

  • access gates the verbs. read can’t write — no PutObject/SendMessage/Publish. Bump to readwrite.
  • The IAM lands on the named ServiceAccount’s Pod-Identity role. A pod under a different SA won’t have it. Match serviceAccount.
  • The resources are namespaced MRs (s3.aws.m.upbound.io, Crossplane v2) — cluster-scoped kubectl get managed won’t list them; use kubectl -n <env-ns> get bucket.s3.aws.m.upbound.io ….
  • The floor is non-overridable — no public access, no non-TLS, no disabling encryption. By design.
  • claim — your XEnvironment; resources: is a field on each service.
  • kind / engine / access — abstract class / concrete impl / intent (read vs readwrite).
  • derived IAM — the least-privilege policy the platform computes from access, scoped to the ARN.
  • safe-by-construction — hardening applied below the claim that you can’t configure or disable.
  • managed resource (MR) — the Crossplane object representing the real AWS resource.