Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing credentials to composition functions #5543

Merged
merged 4 commits into from
Apr 30, 2024

Conversation

negz
Copy link
Member

@negz negz commented Apr 4, 2024

Description of your changes

Fixes #3718

Some functions need credentials to talk to an external system, like AWS or a git repository. Today you can only pass credentials to a function by using a DeploymentRuntimeConfig to inject them as files or environment variables. This isn't ideal, as you probably want per-caller credentials, not credentials that are available to all callers.

This PR allows you to tell Crossplane what credentials to give a function when you write a Composition.

Here's an example:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: parent
spec:
  compositeTypeRef:
    apiVersion: nop.example.org/v1alpha1
    kind: XNopResource
  mode: Pipeline
  pipeline:
  - step: example
    functionRef:
      name: function-needs-a-secret
    credentials:
    - name: credentials-for-something
      source: Secret
      secretRef:
        namespace: crossplane-system
        name: super-secret

The credentials block uses the same schema as a ProviderConfig. For now, it only supports loading credentials from a Kubernetes secret (i.e. source: Secret).

In future we might support other sources, but for now I think secrets will be a good start. I've designed both the Kubernetes and protobuf APIs to support adding other credential sources / shapes in future. I'm not sure what other sources we might support. Perhaps IRSA, if we ever relax the function spec:

A Function MUST NOT assume it is deployed in any particular way, for example that it is running as a Kubernetes Pod in the same cluster as Crossplane.

Given that we intend to remove support for external secret stores per #5522, I don't expect we'll ever have to expand this API to support loading from a secret store like Vault. Instead we'd expect people to use https://external-secrets.io (or similar) to load credentials into a Kubernetes secret.

Reading credentials looks like this in Go:

cred := req.GetCredentials()["credentials-for-something"]
switch cred.GetSource().(type) {
	case *v1beta1.Credentials_CredentialData:
		data := cred.GetCredentialData().GetData()
	default:
		// No credentials
}

In Python (I think) it looks like this:

cred = req.credentials["credentials-for-something"]
if cred.HasField("credential_data"):
  data = cred.credential_data.data

This is just the "bare" protobuf-generated code. We could add wrappers to the function SDKs if we think they'd add a better UX.

I have:

Need help with this checklist? See the cheat sheet.

@negz negz requested a review from a team as a code owner April 4, 2024 03:55
@negz negz requested a review from bobh66 April 4, 2024 03:55
Copy link
Member

@jbw976 jbw976 left a comment

Choose a reason for hiding this comment

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

Looks good to me @negz, thanks for iterating on this support for credentials! I like where it landed 💪

Just a couple small questions from me, nothing blocking at all.

Copy link
Contributor

@phisco phisco left a comment

Choose a reason for hiding this comment

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

a few minor comments, otherwise lgtm 🙏 thanks @negz!

apis/apiextensions/v1/composition_common.go Show resolved Hide resolved
apis/apiextensions/v1/composition_validation_test.go Outdated Show resolved Hide resolved
In future we might support other sources, but for now I think secrets
will be a good start. I've designed both the Kubernetes and protobuf
APIs to support adding other credential sources / shapes in future.

Signed-off-by: Nic Cope <nicc@rk0n.org>
These are all fairly obvious, but we try to add comments for all fields.
The only exceptions I've left are wrapper messages with singleton fields
(e.g. MatchLabels, Resources, CredentialData).

Signed-off-by: Nic Cope <nicc@rk0n.org>
We think it's likely that a function will need more than one credential.
In particular, a function could need credentials from different sources.

Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
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.

Support passing credentials to Composition Functions
3 participants