Skip to content

RFC: Service Accounts for Cloud Foundry Workload Identity - #1645

Open
rkoster wants to merge 21 commits into
cloudfoundry:mainfrom
rkoster:rfc-service-accounts
Open

rkoster wants to merge 21 commits into
cloudfoundry:mainfrom
rkoster:rfc-service-accounts

Conversation

@rkoster

@rkoster rkoster commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Propose space-owned service accounts: stable identities shared by selected apps, with independent instance keys and no app-distributed client secret.

The primary use case is workload identity federation (WIF) to off-platform services, especially services managed by service brokers. The RFC follows a payments API and background worker accessing a broker-managed object store. Cloud Foundry issues and rotates instance certificates; apps use them to obtain UAA JWTs that external services can trust or exchange for their own credentials.

An emerging second use case is coding agents running as CF apps, with explicit CAPI permissions to push generated applications.

Proposal at a glance

  • One immutable owning space; zero/one account per app, many same-space apps per account. Binding establishes identity, not resource permissions.
  • Native create/list/show/bind/unbind/enable/disable/delete UX. Creation mirrors service-instance permissions: Space Developer or platform admin, with readable/writable-space checks.
  • RFC 1123 hostname-label names, restricted to lowercase ASCII and 3–63 characters, unique within a foundation. Deletion retains a tombstone; audited admin-only --reuse-name provides deliberate recovery with identity-reuse consequences made explicit.
  • Maximum service-account count in space quotas; count existing accounts, not bindings or tombstones.
  • Certificate-authenticated, short-lived bearer JWTs without cnf, scoped to approved recipients. Explicit roles/grants determine access.
  • Proposed OSBAPI capability and platform-owned binding identity payload, non-secret federation metadata and per-binding grant lifecycle. Existing bindings retain their behavior.
  • Account-aware RFC 0055 route sources use cf:svc:<service-account-name> and match the certificate's account SAN while retaining domain restrictions.
  • Assignment changes require restart. Disable is a token-issuance switch; it retains assignments/roles and does not revoke existing JWTs or certificate-based route access.

Three Mermaid diagrams illustrate provisioning, external federation and agent→UAA→CAPI access. CLI examples, broker request/response JSON, a decoded JWT, lifecycle table and quota fragment explain the developer experience.

Existing work

The UAA certificate-authentication and subject/SAN-matching foundation is implemented and agreed with the UAA team, pending final review in UAA #4076.

Companion drafts: CAPI #5520, capi-release #702, BBS #168, Diego #1216, CLI #3875. These demonstrate the shared two-app identity, explicit CAPI roles, disable/enable and unbind/restart. Detailed implementation and verification evidence is recorded in those PRs.

Review requested

The next step is community review and RFC approval of the identity model and developer experience. This PR remains Draft; no RFC number or FCP is requested yet.

@cloudfoundry/toc — relevant working groups include App Runtime Interfaces, App Runtime Platform and App Runtime Deployments. Feedback is requested from CAPI, Diego/BBS, UAA, CLI, networking and service-broker maintainers.

@rkoster
rkoster marked this pull request as ready for review October 6, 2026 14:22
Copilot AI balanced review requested due to automatic review settings October 6, 2026 14:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The owning-space deletion contract and safeguards against unbounded global tombstones need definition.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Proposes space-owned service accounts for stable, secretless Cloud Foundry workload identities.

Changes:

  • Defines account lifecycle, permissions, quotas, and app assignments.
  • Specifies UAA JWT federation, broker integration, and CAPI access.
  • Extends identity-aware routing for service-account identities.
File Description
toc/​rfc/​rfc-draft-service-accounts.md Adds the service-account RFC and developer workflows.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread toc/rfc/rfc-draft-service-accounts.md
Comment thread toc/rfc/rfc-draft-service-accounts.md
@beyhan
beyhan requested a review from a team October 6, 2026 14:47
@beyhan
beyhan requested review from Gerg, beyhan, cweibel, mkocher and stephanme and removed request for a team October 6, 2026 14:47
@beyhan beyhan added toc rfc CFF community RFC labels Oct 6, 2026
@pbusko

pbusko commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

IMO this feels like a lot of new concepts and lifecycle machinery for what the federation case actually needs, and most of it looks like it's there to manage the new resource rather than solve the original problem.

mTLS auth with SAN matching is already in the UAA, the actual gap is just a stable identifier that a selected set of apps can share.

Instead of a new first-class resource, could that association just be an app label? e.g.

cf set-label app payments-api identity.cloudfoundry.org/service-account=payments-worker

That's the SPIFFE/OIDC workload-identity style, and space-scoping also drops the need for the creation budget. Today UAA matches against a pre-registered SAN, so for this to work it'd need to read the subject straight from the cert instead. And the SAN would have to be space-scoped, so one app can't grab another space's identity.

@rkoster

rkoster commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@pbusko — responding to your suggestion to use app labels and space-scoped identities:

Instead of a new first-class resource, could that association just be an app label?

I explored SPIFFE-based identity earlier, including an end-to-end UAA/Diego POC and research on name-derived identities. The main question is the canonical identity and its lifecycle, rather than how an app expresses its assignment.

At Rabobank, a recurring requirement—raised repeatedly during the route-policy work—is human-readable, stable identifiers that teams can use directly in external authorization policies.

Those identifiers must also be known before the platform exists. For disaster recovery, we want to pre-create external WIF roles and trust policies, then recreate the platform and push apps using predetermined identities. Requiring each team to create CF resources, retrieve a generated GUID-based identity, provision external roles, and only then deploy introduces sequencing and state-management complexity into every application pipeline.

A space GUID plus an account label could form a valid SPIFFE ID, but would not meet that pre-provisioning requirement and would change when the space is recreated. Using org/space names instead introduces other problems: CF permits names up to 255 characters, including printable punctuation and Unicode, and those names are mutable. SPIFFE path segments permit only letters, digits, dots, dashes and underscores, and prohibit percent-encoding. Lossy sanitization/truncation introduces collisions; name-based paths change on rename. Deterministic hashing can address representation, but sacrifices readability.

The proposed account name is therefore human-readable, immutable and chosen in advance, independently of platform-generated GUIDs. External policies can be prepared for cf:service-account:payments-worker before CF resources exist. Trust remains scoped to the planned UAA issuer; a different recovery issuer must also be pre-authorized.

This does not rule out SPIFFE: the predetermined account name could appear in a URI SAN. The distinction is the identity model, not DNS versus URI encoding.

A label could be an assignment UX, but needs platform-controlled authorization and issuance: ordinary metadata must not let an app claim an identity with existing grants. Explicit CAPI roles, broker grants and disable/delete behavior also need lifecycle semantics independent of any one app. That is why the RFC models the shared identity as a resource.

Today UAA matches against a pre-registered SAN, so for this to work it'd need to read the subject straight from the cert instead.

That changes the authentication profile. RFC 8705 tls_client_auth requires an exact expected DN/SAN registered for each client. Deriving an unregistered client/subject from a trusted certificate needs a separately specified issuance profile. This RFC builds on existing exact-SAN registration.

Space-scoping could avoid foundation-wide name contention, but still needs a predetermined, stable namespace and name-reuse semantics. The creation budget is configurable, including unlimited for internal platforms.

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

Labels

rfc CFF community RFC toc

Projects

Status: Inbox

Development

Successfully merging this pull request may close these issues.

4 participants