Crossplane providers use a ProviderConfig
Kubernetes object to
supply credentials to authenticate with external services. For
example,
Upbound’s AWS provider
offers a
ProviderConfig
that supports
supplying credentials
via a Kubernetes Secret
, environment variable, file, and more. Users can
create multiple ProviderConfig
instances and reference them from the
spec.providerConfigRef
field of any managed resource.
Providers in Upbound managed control planes can also use an Upbound
credential
source called Provider Identity.
The Upbound
credential source uses OpenID Connect (OIDC
) to
authenticate to providers without requiring users to store credentials on Upbound.
This authentication method is comparable to “workload identity” offered by some managed Kubernetes providers.
OpenID Connect
OpenID Connect (OIDC) is a protocol that’s built on top of OAuth 2.0. It serves to establish the identity of an entity in one environment that’s attempting to access resources in another.
OIDC calls the two parties the OpenID Providers (OPs) and Relying Parties (RPs). Managed control planes define these roles as follows:
- OpenID Provider: Upbound
- Relying Party: an external service that supports OIDC, for example, AWS, Azure or GCP
Users set up a trust relationship between Upbound and the external service. Upbound uses the trust relationship instead of storing credentials for an external service in the managed control plane.
Upbound injects an identity token into the file system of every
provider Pod
. Upbound sends the token to the external service and exchanges it for a
short-lived credential. Upbound uses the short-lived credential to perform
operations against the external service.
Creating trust relationships
Every OIDC relying party implements its own mechanism for establishing a trust relationship and associating permissions. Typically, the process involves the following broad steps:
- Specifying the issuer. For Upbound, this is
https://proidc.upbound.io
. - Specifying an audience. This may vary by relying party.
- Creating a role or service account that an entity possessing a valid identity token can assume.
- Associating permissions with the role or service account.
Different OIDC relaying parties may define valid tokens differently. Typically it involves writing a policy that restricts what subject can assume the role or service account.
Identity tokens are
JSON Web Tokens (JWTs
).
The OIDC claims supported by Upbound are available in the OIDC metadata
endpoint at https://proidc.upbound.io/.well-known/openid-configuration
.
1{
2 "issuer": "https://proidc.upbound.io",
3 "jwks_uri": "https://proidc.upbound.io/.well-known/jwks",
4 "response_types_supported": [
5 "id_token"
6 ],
7 "subject_types_supported": [
8 "public"
9 ],
10 "id_token_signing_alg_values_supported": [
11 "RS256"
12 ],
13 "claims_supported": [
14 "sub",
15 "aud",
16 "exp",
17 "iat",
18 "iss",
19 "jti",
20 "nbf"
21 ]
22}
OIDC relying parties use this information to validate identity tokens.
Relying parties use the jwks_uri
to ensure that the OIDC provider signed the
identity token with their private key. The private key must
correspond to one of the public keys from
https://proidc.upbound.io/.well-known/jwks
.
The iss
and aud
claims of an
identity token should match the issuer and audience configured for the
relying party. The sub
should be a valid subject based on the
authored policy. For providers running in Upbound managed control planes, the
subject adheres to the following format.
mcp:<account>/<mcp-name>:provider:<provider-name>
For example, the following would be a valid subject for provider-aws
in a
managed control plane named prod-1
in the my-org
account.
mcp:my-org/prod-1:provider:provider-aws
The claims for an identity token injected into the file system of a provider in a managed control plane looks like the following.
1{
2 "iss": "https://proidc.upbound.io",
3 "sub": "mcp:my-org/prod1:provider:provider-aws",
4 "aud": [
5 "sts.amazonaws.com"
6 ],
7 "exp": 1680124165,
8 "nbf": 1680120565,
9 "iat": 1680120565,
10 "jti": "YL1ouQ5KJiTY2QShIRczqQ=="
11}
Pod
are valid
for 1 hour. They are automatically refreshed before expiration to ensure there
is no interruption in service.Using Upbound OIDC as a credential source
The Upbound console allows for creating instances of a ProviderConfig
via the
console, instead of manually authoring a YAML manifest. Users
may also connect to their managed control planes directly and apply a
ProviderConfig
YAML manifest.
Each Provider
defines their own ProviderConfig
schema and values.
source: Upbound
to enable OIDC authentication.For example,
Upbound’s GCP provider
includes the following manifest for using the Upbound
OIDC identity source.
1apiVersion: gcp.upbound.io/v1beta1
2kind: ProviderConfig
3metadata:
4 name: default
5spec:
6 credentials:
7 source: Upbound
8 upbound:
9 federation:
10 providerID: projects/<project-id>/locations/global/workloadIdentityPools/<identity-pool>/providers/<identity-provider>
11 serviceAccount: <service-account-name>@<project-name>.iam.gserviceaccount.com
12 projectID: my-org-gcp-project
Applying this manifest in a
managed control plane causes provider-gcp
to fetch its identity token from
the file system and use it to authenticate to GCP.
Adding Upbound OIDC to a Provider
Any provider that can run in a managed control plane can support the Upbound
credential source. Upbound injects identity tokens into the file system of every
provider Pod
whether they support OIDC or not. A provider wishing to support OIDC
can access its identity token in the
/var/run/secrets/upbound.io/provider/token
file. This Pull
Request provides a reference implementation.