Configure GitHub Actions OIDC and Safe Teardown with Crossplane

Set up passwordless GitHub Actions access, protect JFrog objects, and tear down Crossplane resources safely.

Use these Crossplane recipes to set up passwordless CI and to remove JFrog objects safely. Each recipe is a set of manifests that combines the JFrog Crossplane providers.

  • Recipe 5 sets up passwordless CI with GitHub Actions OpenID Connect (OIDC).
  • Recipe 6 protects JFrog objects from deletion and tears down the recipe objects in reverse order.

Prerequisites

📘

Note

The manifests on this page omit providerConfigRef for brevity. Every managed resource also needs providerConfigRef: {kind: ClusterProviderConfig, name: jfrog} under spec. Add it to each managed resource before you apply, or name your configurations default.

Recipe 5: Passwordless CI with GitHub Actions OIDC

Step 1: Create the Manifests

Save the following manifests to a directory:

apiVersion: authentication.platform.m.crossplane.io/v1alpha1
kind: OIDCConfiguration
metadata:
  name: github-payments
  namespace: team-payments
  labels: {app.example.com/oidc: github-payments}
spec:
  forProvider:
    providerType: GitHub
    issuerUrl: https://token.actions.githubusercontent.com
    audience: jfrog-github
    organization: my-org
---
apiVersion: authentication.platform.m.crossplane.io/v1alpha1
kind: OIDCIdentityMapping
metadata: {name: payments-main, namespace: team-payments}
spec:
  forProvider:
    priority: 1
    claimsJson: '{"sub":"repo:my-org/payments:ref:refs/heads/main"}'   # literal JSON string
    providerNameSelector: {matchLabels: {app.example.com/oidc: github-payments}}
    tokenSpec: {audience: '*@*', expiresIn: 7200, scope: applied-permissions/user, username: alice}

The values my-org, my-org/payments, and jfrog-github are samples. Replace them with your GitHub organization, repository, and audience.

About these manifests:

  • claimsJson must be a literal JSON string. Crossplane doesn't evaluate Terraform expressions.
  • OIDCIdentityMapping selects the OIDCConfiguration by its label with providerNameSelector. The provider name must name an existing OIDCConfiguration.
  • tokenSpec.username must be an existing user.

Step 2: Apply the Manifests

Run the following command:

kubectl apply -R -f <dir>/

Recipe 6: Protect and Tear Down

Step 1: Protect JFrog Objects

The following block has two parts:

  • The first part is a spec fragment, not a complete manifest. Add the managementPolicies line under spec of each managed resource that you want to protect. With this policy, deleting the managed resource keeps the JFrog object.
  • The second part is a Usage. It blocks deleting the payments-block-high security policy while the payments-watch watch uses it.
spec:
  managementPolicies: ["Observe","Create","Update","LateInitialize"]   # deleting the managed resource keeps the JFrog object
---
apiVersion: protection.crossplane.io/v1beta1
kind: Usage
metadata: {name: watch-uses-block-high, namespace: team-payments}
spec:
  of: {apiVersion: policy.xray.m.crossplane.io/v1alpha1, kind: SecurityPolicy, resourceRef: {name: payments-block-high}}
  by: {apiVersion: watch.xray.m.crossplane.io/v1alpha1, kind: Watch, resourceRef: {name: payments-watch}}

If you delete a resource that a Usage protects, the delete fails with this resource is in use. Delete the using resource first.

Step 2: Remove the Protection

Do this only when you want the JFrog objects deleted. On each protected managed resource, set managementPolicies: ["*"].

Skipping this step deletes the Kubernetes objects and leaves the JFrog objects in place.

Step 3: Tear Down in Reverse Order

Delete the Watch before the SecurityPolicy. The Usage blocks deletion of payments-block-high until payments-watch is gone.

Delete the managed resources in the reverse order of creation:

  1. Xray watch and report, then policies.
  2. Permission and cleanup policy.
  3. Virtual repositories, then local and remote repositories.
  4. Project memberships, role, and environment, then the project.
  5. Group membership, group, users, and global role.

Step 4: Check the Result

kubectl get managed -A must return no resources. That confirms the Kubernetes objects are gone. The JFrog objects are gone only if Delete was restored before this deletion. Otherwise they remain in JFrog.

kubectl get managed -A

Next Steps


Did this page help you?