feat(providers): consume tbot-rotated JWT-SVID files as external provider credentials
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 8.7k
- Forks
- 1.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 253
Description
Problem statement
OpenShell Providers v2 already models externally rotated credentials, endpoint-bound credential resolution, and HTTP header injection. A provider profile can declare strategy: external, bind a credential to approved endpoints, and use auth_style: header plus header_name to control placement.
What is missing is a Kubernetes runtime bridge that makes a credential continuously rotated by a trusted sidecar available through that existing provider mechanism.
Teleport tbot can authenticate to a remote Teleport cluster using an operator-configured join method, select an authorized Teleport WorkloadIdentity, issue a short-lived SPIFFE-compatible JWT-SVID, and write it as the jwt_svid artifact of its workload-identity-jwt service. In daemon mode, tbot replaces that artifact on its configured renewal interval.
For Kata Containers and other microVM-backed Kubernetes runtimes, tbot can run inside the sandbox pod/microVM and write jwt_svid to a memory-backed emptyDir. The volume can be mounted read-only by the OpenShell supervisor while remaining completely absent from the sandbox application container.
OpenShell should consume that rotated file as the current value of an existing external provider credential. Existing provider endpoint binding and header placement should then inject it into a Teleport-specific or other operator-approved HTTP header.
tbot sidecar
-> authenticates to remote Teleport cluster
-> requests authorized WorkloadIdentity JWT-SVID
-> rotates /run/workload-identity/jwt_svid in memory-backed emptyDir
OpenShell external provider credential
-> observes current JWT-SVID generation
-> existing provider binding authorizes its use
-> existing header placement injects it at the egress boundary
Requested capability
Extend the existing Providers v2 external-credential path so a Kubernetes compute deployment can map an operator-mounted, rotating credential file to a provider credential key.
This should not introduce a separate identity-source or credential-source framework. The provider remains the logical credential source and continues to own:
- Provider attachment and workspace scope.
- Credential generation and expiry semantics.
- Host, port, and path binding.
auth_style: headerandheader_nameplacement.- Static placeholder resolution and other existing credential consumers.
- Revocation when the provider is detached or its binding changes.
The Kubernetes/runtime integration only supplies the latest externally rotated value to that existing provider credential.
Illustrative profile and runtime configuration:
# Illustrative only; not a proposed schema.
id: workload-access
credentials:
- name: workload_jwt
env_vars: [WORKLOAD_IDENTITY_TOKEN]
auth_style: header
header_name: X-Workload-Identity
refresh:
strategy: external
endpoints:
- host: access-gateway.example
port: 443
protocol: rest
path: /**
# Kubernetes driver/operator-owned mapping.
external_provider_credentials:
- provider: workload-access-instance
credential: WORKLOAD_IDENTITY_TOKEN
file: /run/workload-identity/jwt_svid
The exact mapping schema is intentionally left open. It must be operator-owned and must reference an attached provider plus a credential already declared by its profile.
Trusted pluggable supervisor features should consume the credential through the existing provider credential resolver and binding checks rather than reading the tbot file independently. A plugin may request an existing provider placement operation, but raw credential bytes must not be included in ordinary middleware request payloads or exposed to sandbox-controlled configuration.
tbot deployment model
- tbot runs as a sidecar in the same Kubernetes pod and microVM boundary as the OpenShell supervisor.
- tbot authenticates to a remote Teleport cluster using an operator-selected join method.
- Teleport RBAC permits the bot to issue only the intended
WorkloadIdentity. - tbot runs
workload-identity-jwtwith explicit audience, credential TTL, and renewal interval settings. - Its
jwt_svidoutput is written to anemptyDirwithmedium: Memory. - The volume is read-write in tbot, read-only in the supervisor, and not mounted in the sandbox application container.
- tbot bootstrap credentials and internal storage use a separate volume and are never exposed to the supervisor or sandbox application.
- OpenShell detects each valid rotated generation without requiring a sandbox or supervisor restart.
This model does not use a SPIFFE Workload API socket. tbot owns remote authentication, issuance, and rotation; OpenShell only consumes the rotated provider credential artifact.
Security requirements
- The file mapping must be operator-owned; sandbox input cannot select a path, provider, credential key, destination binding, or header name.
- Only tbot can write the memory-backed output volume, and only the supervisor can read it.
- The sandbox application cannot mount or read the output volume, tbot storage, or the resolved provider credential.
- Handle tbot's atomic file replacement safely and never read or activate a partially written token.
- Parse JWT expiry and reject expired or not-yet-valid generations. Profiles or operator configuration should also constrain expected issuer, audience, and SPIFFE subject when supported.
- Preserve the last complete valid generation only until its expiration; fail closed afterward.
- Remove or overwrite sandbox-supplied copies of the configured identity header.
- Apply existing provider host/port/path binding before injection and do not forward the credential across a cross-origin redirect.
- Never log the token. Audit only non-secret metadata such as provider, credential key, issuer, SPIFFE subject, audience, expiry, and generation fingerprint.
- Keep provider credential state isolated by sandbox, workspace, provider instance, and credential key.
- Detach, policy change, invalid rotation, or removal of the mapping must revoke future resolution through the existing provider path.
Acceptance criteria
- A tbot sidecar authenticates to a remote Teleport cluster and continuously rotates a selected Workload Identity JWT-SVID in a memory-backed volume.
- The Kubernetes/OpenShell runtime maps
jwt_svidinto a credential declared by an attached Providers v2 provider using the existing external-refresh semantics. - Existing provider header placement injects the current JWT into an operator-configured Teleport-specific or generic HTTP header for matching endpoints.
- Rotation becomes active without restarting the sandbox, supervisor, or workload process.
- Existing endpoint binding, detach, expiry, and revocation behavior continues to apply.
- A sandbox-supplied spoofed header cannot override or suppress the provider-injected value.
- Missing, malformed, partial, expired, or policy-mismatched generations fail closed.
- Non-matching endpoints and cross-origin redirects never receive the credential.
- The application cannot read the memory-backed volume or resolved token.
- Tests cover a conventional Kubernetes runtime and a microVM-backed runtime such as Kata Containers.
- Documentation includes a tbot
workload-identity-jwtsidecar example and explains how it maps into an existing Providers v2 profile.
Related work
- #1665 introduced SPIFFE workload identity support for sandbox credentials.
- #2708 tracks SPIFFE-backed provider token grants on non-Kubernetes drivers.
- #1733 tracks supervisor middleware and protected request transformation.
- #2917 requests policy-controlled host and path rewriting, which is complementary when an identity-bearing request must traverse an access proxy.
This RFE is limited to integrating a sidecar-rotated credential with the existing Providers v2 credential pipeline. It does not request Workload API socket access or a new pluggable credential-source subsystem.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the existing Providers v2 external-credential path and the Kubernetes/runtime integration; related issues #1665, #2708, #1733, and #2917 provide surrounding context. Done means a tbot-rotated jwt_svid can update an attached provider credential safely, preserve existing binding and revocation behavior, and pass the listed Kubernetes and microVM runtime acceptance tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kubernetes, rust
- Domain
- authentication, cloud, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100