6.2 KiB
STS Credential Vending Assessment for NetKingdom
Status: assessment complete (ARTIFACT-STORE-WP-0007 D7.3)
Date: 2026-07-02
Upstream baseline: net-kingdom/docs/object-storage-sts-credential-vending.md
(NK-WP-0007, 2026-05-18) — this assessment specializes that architecture for
artifact-store and records the current-state inventory it asks for.
1. Current object-storage credential inventory
| Consumer | Credential path today | Temporary-credential ready? |
|---|---|---|
| artifact-store S3 backend | Static key pair via ARTIFACTSTORE_S3_ACCESS_KEY_REF / ARTIFACTSTORE_S3_SECRET_KEY_REF (file/env refs, no plaintext in config) |
No — S3BackendConfig has no session_token field and aioboto3.Session is constructed without aws_session_token (src/artifactstore/storage/backends/s3.py); STS credentials cannot be consumed until D7.4 lands |
NetKingdom CNPG backups (net-kingdom-pg-backup-s3) |
Documented as a static kubectl create secret generic --from-literal key pair in sso-mfa/k8s/postgresql/README.md; not yet provisioned — backups are parked "until object storage is available" |
No — static by design today; should adopt the vending flow (or at minimum an ExternalSecret lane) when object storage is provisioned |
MinIO compatibility harness (make test-minio / test-minio-local) |
One-run generated throwaway root credentials, local container only | N/A — dev double, never a production path |
No other live S3/MinIO credential consumers were found in net-kingdom or artifact-store. The most important inventory conclusion: nothing is production-live yet, so the vending architecture can be adopted without a migration burden — the CNPG backup lane should start on the target pattern rather than shipping static keys first.
2. Can Keycloak / Authelia / local-identity act as the OIDC IdP for MinIO AssumeRoleWithWebIdentity?
MinIO's STS AssumeRoleWithWebIdentity accepts any OIDC JWT whose issuer is
configured in MinIO's identity-provider settings and whose claims map to a
MinIO policy. Assessment per NetKingdom issuer:
- key-cape (lightweight mode) — yes, and it is the preferred first issuer: it already issues IAM Profile v0.2 tokens with OIDC discovery + JWKS (proven by the Core Hub verifier integration test, CUST-WP-0025-T03). MinIO consumes the discovery URL directly.
- Keycloak (expanded mode) — yes; standard, widely documented MinIO OIDC pairing. This is the production/enterprise-federation issuer per the NetKingdom baseline; not yet deployed (NK-WP-0001 Keycloak was cancelled as superseded, so key-cape leads until enterprise federation is needed).
- Authelia — technically an OIDC provider, but it is the NetKingdom
session/portal SSO layer and does not issue IAM Profile v0.2 claims
(
tenant,principal_type,assurance). Using it as a storage IdP would bypass the IAM Profile contract. Do not use as the vending issuer. - local-identity — dev/bootstrap contexts only, per the baseline's local-dev restrictions: only explicitly configured dev vending instances may accept it, and minted credentials must be confined to local/sandbox object stores.
Important nuance from the baseline: consumers should not hit MinIO STS directly with raw IdP tokens. The credential-vending service verifies the IAM Profile and asks flex-auth for the decision first; MinIO's own claim-to-policy mapping is then deliberately coarse (one policy per tenant/prefix class), keeping authorization in flex-auth rather than in MinIO policy JSON.
3. Target architecture (artifact-store specialization)
Follow the NetKingdom baseline flow (IAM Profile token → vending service → flex-auth decision → backend exchange → temporary credentials). The artifact-store-specific bindings:
| Element | Binding |
|---|---|
| Issuer | key-cape lightweight mode first; Keycloak expanded mode when enterprise federation arrives; local-identity for sandbox only |
| Audience | the credential-vending service audience (not artifact-store, not MinIO) — aud per IAM Profile v0.2 |
| Role/policy mapping | flex-auth vocabulary from the baseline: tenant, protected-system=object-storage, bucket, prefix, actions (read/write/list), TTL; MinIO side keeps one coarse policy per tenant-prefix class |
| Expiration | default lease 15–60 min with refresh-before-expiry + jitter in the consumer; TTL bounds enforced by flex-auth (proven pattern: ttl_out_of_bounds denial in the FLEX-WP-0007 smoke) |
| Revocation | short TTLs are the primary control; for immediate cuts, disable the MinIO policy or the vending grant; OpenBao lease revocation applies only to broker-held parent material |
| Audit | vending service emits the baseline's audit event (issuer, sub, tenant, decision id, backend, TTL, non-secret request ids); OpenBao audit covers parent-credential access |
| Break-glass | platform-control-plane path per the baseline: short-lived, post-event review record mandatory; never a tenant-plane shortcut |
artifact-store consumer work (feeds D7.4)
- Add
session_token: str | NonetoS3BackendConfigand passaws_session_tokenintoaioboto3.Session. - Add
ARTIFACTSTORE_S3_SESSION_TOKEN_REF(and optionallyARTIFACTSTORE_S3_CREDENTIAL_EXPIRATION_REF) alongside the existing refs, with atomic refresh of all three values. - Support the delivery modes from the baseline in priority order: mounted
files refreshed by a controller/sidecar first (fits the current
_REFfile pattern),credential_processfor CLI/batch use later.
Sequencing recommendation
- D7.4: session-token consumer support (small, local, no deployment gate).
- Vending service + flex-auth vocabulary (NetKingdom/flex-auth owned; artifact-store is a consumer, not the owner).
- Wire the CNPG backup lane and artifact-store deployment to the vending flow when Railiance provisions the production object store — do not ship static production keys in the interim.
Non-goals confirmed
- artifact-store does not own identity, authorization, or secret custody (baseline ownership table).
- OpenBao is not the object-storage authorization engine; it holds parent material and audit only.
- MinIO policy JSON is not the canonical tenant policy model; flex-auth is.