Per-step federated identity across all step types, with scoped ephemeral credentials
C
Cute Silverfish
Extend HarnessID so that every pipeline step receives its own uniquely-claimed, short-lived JWT, and provide a supported mechanism to inject that JWT into a credential-minting service that exchanges it for an ephemeral, least-privilege credential scoped to exactly what that step needs (e.g., a Kubernetes token valid only for a single namespace, for the duration of the step).
Problem Statement
- Insufficient process isolation on the delegate
Harness delegates today execute pipeline steps within a shared execution context. Steps running natively on a delegate execute as separate JVM threads inside the same process, so serial and parallel executions share process state. Any misconfiguration, vulnerability, or inappropriate use of local resources can affect the security of other pipeline executions and deployments running on the same delegate.
This risk is amplified by Harness capabilities that permit developer-authored inline code (shell/script steps) to run inside the delegate's context. Abuse of these features creates a credible privilege-escalation and confused-deputy path.
- Credentials are broader than the task requires
Because credentials are resolved at the connector/delegate level rather than the step level, a step inherits the full entitlement of the connector or delegate identity — not the entitlement the individual task actually needs. A drift-detection step and a production-apply step reusing the same connector present identical identities to the cloud provider, so the trust policy must be written to the widest common denominator.
- Fragmented OIDC today
Per the current design, OIDC is implemented per connector (AWS, GCP, Azure, Vault each with their own code path, token shape, and signing key), is unsupported for several connector types, and has no path at all outside a connector — meaning custom shell and container steps fall back to long-lived static secrets, defeating the purpose of federation.
Requested Capability
Per-step identity by default — Every step execution is issued its own JWT from HarnessID, with a distinct sub derived from account / org / project / pipeline / stage / step / execution ID. No two steps share a token.
Configurable claims and subject template — Support subjectTemplate and customClaims declared at pipeline, stage, and step level, with closer-to-step precedence. Base claims (account, org, project, pipeline, execution) must be platform-stamped and non-overridable.
Native (connector-less) identity — Allow YAML to declare named identities that surface as environment variables inside the step container, so custom shell/container steps can federate without a connector and without stored secrets.
Token exchange for ephemeral scoped credentials — Provide a documented, supported flow to present the step JWT to a minting service (Kubernetes API, HashiCorp Vault, AWS STS, GCP STS, Azure AD) and receive a credential scoped to exactly that step's target — e.g., a namespace-bound Kubernetes ServiceAccount token, TTL bounded by step duration.
Scope and suppression controls — scope: STEP must guarantee the token is present only in the declaring step's container environment, never pod-wide. disabled: true must suppress an inherited identity so, for example, third-party scan steps never see a Vault token.
Mint-time abuse prevention — HarnessID must structurally validate the requested sub against the workload token's execution context to close cross-project/cross-account impersonation, and must strip and audit any attempt to set reserved claims via customClaims.
Step-level containerization — Complete and make generally available the roadmap item to execute all delegate-native steps in ephemeral, isolated containers, so the identity boundary and the process boundary align. Steps in the same stage may share a context only where entitlement requirements are identical; separate pipelines must never share one.
Unified audit trail — A single audit stream across all connectors and native identities, recording the requested subject, resolved claims, audience, and any validation failure with a claim diff.
Optional Enhancement (Future Consideration)
Multiple identities per step — Support a map of named identities per step, each with its own audience, subject, and claims, so a single step could authenticate to Kubernetes, Vault, and a registry with three independent, separately-scoped tokens. This is not required for the initial delivery; a single scoped identity per step satisfies the security finding. We would like this on the roadmap for future multi-cloud and multi-target step patterns
Concrete Target Scenario
A deployment stage targeting namespace payments-prod:
1) Step run_migrations is issued a JWT with sub = account:abc:pipeline:deploy:stage:deploy_prod_eu:step:run_migrations.
2) That JWT is presented to the cluster's OIDC-federated token minting endpoint.
3) The cluster returns a token bound to a RoleBinding permitting only apps/deployments and batch/jobs in payments-prod, with a TTL of 10 minutes.
4) The next step, rolling_deploy, receives a different JWT and a different minted credential with a different RoleBinding.
5) Neither token exists after the step container exits, and neither is visible to the other step or to any other pipeline on the delegate.
Log In