Skip to content

Draft: implement space-owned service-account lifecycle and runtime identity - #5520

Draft
rkoster wants to merge 57 commits into
cloudfoundry:mainfrom
rkoster:service-accounts-poc
Draft

rkoster wants to merge 57 commits into
cloudfoundry:mainfrom
rkoster:service-accounts-poc

Conversation

@rkoster

@rkoster rkoster commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Community RFC draft: cloudfoundry/community#1645.

Draft implementation of the service-account proposal, exercised end-to-end in a CF lab.

Intentional proposal revision: accounts are space-owned, with one immutable owning space and same-space app assignment only. This supersedes the gist's org ownership/cross-space use grants. Names remain foundation-unique and immutable, with permanent deletion tombstones.

  • Add /v3/service_accounts create/list/show/update/delete and account app listing, plus GET/PATCH /v3/apps/:guid/relationships/service_account.
  • Space managers/platform admins manage accounts; app writers assign within the owning space. Bind does not implicitly grant roles.
  • Provision canonical secretless UAA clients (cf:service-account:<name>, exact <name>.svc.identity DNS SAN) and roleless CAPI OAuth principals on first bind through retryable pollable jobs. Reuse active provisioning jobs and reject client/principal collisions and conflicting lifecycle operations.
  • Reconcile disable/enable/delete, retaining roles on disable and rejecting direct account deletion while desired or active process/task references exist. Space/org deletion cascades workloads, managed clients, principals/roles and accounts, retaining name reservations; cleanup failures preserve the parent and support retry.
  • Add an atomic rolling seven-day creation budget per authenticated principal across all spaces. Operator configuration supports unlimited (-1); platform admins and admin automation are exempt. Failed requests consume no budget; account deletion and audit-event retention do not refund it.
  • Snapshot launch identity for processes/runtime tasks, propagate typed certificate properties and non-secret VCAP_SERVICE_ACCOUNT, exclude staging, and reject unsupported/unready runtime identity. Assignment changes require explicit restart.
  • Add lifecycle/assignment audit events, API documentation, generated Ruby BBS bindings, and MySQL collation/partial-migration recovery exercised in the lab.

Verification

History intentionally preserves small failing-test RED and passing-implementation GREEN commits.

  • RFC follow-ups: budget RED 93fffd2bc → GREEN a1a6dc0b5; cascade RED 052cd6293 / corrected runtime fixture RED c3c53dfec → GREEN ec582b703.

  • Follow-up verification: 38 budget/request examples (including concurrent cross-space creation), 105 lifecycle/action/request regressions, 42 space/org deletion request regressions; all passing. Nine changed Ruby files lint-clean. Creation ledger migration exercised on PostgreSQL.

  • Local milestone: 721 targeted request/unit examples passed; 57 changed Ruby files lint-clean; API documentation build passed.

  • Subsequent lab fixes: MySQL migration/assignment regressions (8 examples) and full managed-client provisioning action (15 examples) passed with lint checks.

  • Live two-app and runtime-task validation: same account SAN, independent keys; certificate-authenticated token acquisition; zero visible apps without roles and two after an explicit role grant; disable blocks new tokens; enable retains roles; unbind without restart retains launch identity, restart removes the SAN and old-account authentication fails.

  • Native CLI demo completed the flow using go run ./main.go, including provisioning jobs and lifecycle operations.

Draft dependencies and open criteria

  • Companion drafts: BBS contract #168, capi-release #702, Diego #1216, CLI #3875.
  • UAA authentication baseline: Harden the RFC 8705 mTLS token endpoint - Supersedes 3792  uaa#4076. Live tokens currently include cnf; the draft requires bearer issuance without it. Per-client RFC 8705 policy feedback: Harden the RFC 8705 mTLS token endpoint - Supersedes 3792  uaa#4076 (review). CAPI registration will also need explicit tls_client_certificate_bound_access_tokens: false once UAA honors it.
  • The dedicated lab provisioning client requires clients.admin in addition to read/write to register CAPI authorities. Namespace-limited client administration is not yet demonstrated; managed account clients receive no management authorities.
  • Authoritative BBS contract source is separate revision 869b0650f4147bb24d790f52153ef571fc11bda0, now published in BBS draft #168. Generated bindings originate there. Upstream module publication/version alignment remains a merge prerequisite.
  • No automatic mixed-version capability negotiation: keep runtime disabled until all participating BBS/rep/cells support the contract. Default-off gates are deliberate.
  • Remaining live criteria include timed renewal, near-leaf-expiry token lifetime cap, staging certificate inspection, broader negative matrices and Windows runtime. Lab CAPI calls used internal HTTP; UAA mTLS used verified direct TLS.
  • Disable/unbind/restart are not immediate cryptographic revocation. Route-policy integration and external WIF/OSB are subsequent work.

These follow-ups are locally verified and not yet deployed to the lab. Account-backed OSB bindings and account route grants remain future integration work; cascade currently cleans existing service bindings/workloads and account registrations/principals.

This is a discussion/implementation draft, not a claim of full RFC acceptance. Tested source head: ec582b703ef80fa9b9c5b3c34ca2798a29b4b801.

rkoster added 30 commits October 5, 2026 18:30

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant