Skip to main content
Requires Enterprise plan. Contact sales for access.
Ona environments can access Google Cloud resources using Workload Identity Federation. You create a workload identity pool with an OIDC provider that trusts Ona’s tokens, then grant the federated identity access to GCP resources. No service account keys are needed.

Prerequisites

How it works

  1. Ona issues a JWT with claims about the environment, user, and organization.
  2. The environment sends the JWT to Google’s Security Token Service (STS).
  3. STS validates the token against Ona’s OIDC discovery endpoint and returns a federated access token.
  4. The environment uses the federated token to access GCP resources directly, or impersonates a service account for broader access.

Step 1: Create a workload identity pool

Create a workload identity pool to manage Ona’s federated identities:
gcloud iam workload-identity-pools create ona-pool \
  --location="global" \
  --display-name="Ona Environments" \
  --project=<PROJECT_ID>

Step 2: Create an OIDC provider

Add an OIDC provider to the pool that trusts Ona’s tokens:
gcloud iam workload-identity-pools providers create-oidc ona-provider \
  --location="global" \
  --workload-identity-pool="ona-pool" \
  --issuer-uri="https://app.gitpod.io" \
  --allowed-audiences="https://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/providers/ona-provider" \
  --attribute-mapping="google.subject=assertion.sub,attribute.organization_id=assertion.organization_id,attribute.environment_id=assertion.environment_id,attribute.project_id=assertion.project_id" \
  --attribute-condition="assertion.organization_id == '<ONA_ORG_ID>'" \
  --project=<PROJECT_ID>
Key parameters:
ParameterDescription
--issuer-urihttps://app.gitpod.io
--allowed-audiencesThe full provider resource name (used as the --audience in ona idp token)
--attribute-mappingMaps Ona token claims to GCP attributes
--attribute-conditionCEL expression that restricts which tokens are accepted

Attribute mappings

Attribute mappings define how Ona token claims map to GCP identity attributes. google.subject is required. Additional custom attributes enable fine-grained IAM bindings. Common mappings for V3 tokens:
google.subject=assertion.sub
attribute.organization_id=assertion.organization_id
attribute.environment_id=assertion.environment_id
attribute.project_id=assertion.project_id
attribute.creator_email=assertion.creator_email
attribute.email=assertion.email

Attribute conditions

Attribute conditions restrict which tokens the provider accepts. Use CEL expressions to filter on Ona claims. Allow only a specific Ona organization:
assertion.organization_id == '<ONA_ORG_ID>'
Allow only a specific project:
assertion.organization_id == '<ONA_ORG_ID>' && assertion.project_id == '<ONA_PROJECT_ID>'
Allow only environments created by a specific user:
assertion.organization_id == '<ONA_ORG_ID>' && assertion.creator_email == 'dev@example.com'
Always set an attribute condition. Without one, any valid Ona token from any organization can authenticate to your pool.

Step 3: Grant access to GCP resources

You can grant access using direct resource bindings or service account impersonation.

Option A: Direct resource access

Grant the federated identity access directly on a GCP resource:
# Allow all identities in the pool
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
  --member="principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/*" \
  --role="roles/storage.objectViewer"
To restrict to a specific Ona project, use the attribute.project_id attribute:
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
  --member="principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/attribute.project_id/<ONA_PROJECT_ID>" \
  --role="roles/storage.objectViewer"
To restrict to a single identity (specific sub claim):
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
  --member="principal://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/subject/organization_id:<ONA_ORG_ID>:project_id:<ONA_PROJECT_ID>" \
  --role="roles/storage.objectViewer"

Option B: Service account impersonation

If the GCP APIs you need do not support direct Workload Identity Federation, impersonate a service account instead.
  1. Create a service account:
gcloud iam service-accounts create ona-sa \
  --display-name="Ona Environment SA" \
  --project=<PROJECT_ID>
  1. Grant the federated identity permission to impersonate the service account:
gcloud iam service-accounts add-iam-policy-binding ona-sa@<PROJECT_ID>.iam.gserviceaccount.com \
  --member="principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/attribute.organization_id/<ONA_ORG_ID>" \
  --role="roles/iam.workloadIdentityUser"
  1. Grant the service account access to the resources it needs:
gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="serviceAccount:ona-sa@<PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/storage.objectViewer"

Step 4: Authenticate from an environment

Create a credential configuration file

Create a credential configuration file that tells the GCP SDK how to obtain tokens from Ona:
gcloud iam workload-identity-pools create-cred-config \
  projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/providers/ona-provider \
  --output-file=gcp-credentials.json \
  --executable-command="ona idp token --audience https://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/providers/ona-provider" \
  --executable-timeout-millis=5000
For service account impersonation, add the --service-account flag:
gcloud iam workload-identity-pools create-cred-config \
  projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/providers/ona-provider \
  --service-account=ona-sa@<PROJECT_ID>.iam.gserviceaccount.com \
  --output-file=gcp-credentials.json \
  --executable-command="ona idp token --audience https://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/ona-pool/providers/ona-provider" \
  --executable-timeout-millis=5000

Authenticate

Set the GOOGLE_APPLICATION_CREDENTIALS environment variable and enable executable-based credentials:
export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/gcp-credentials.json
export GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES=1
Then use GCP tools normally:
gcloud auth login --cred-file=gcp-credentials.json
gcloud storage ls gs://my-bucket

Automate on environment startup

Add the credential setup to your automations:
# automations.yaml
tasks:
  gcp-login:
    name: GCP Login
    command: |
      export GOOGLE_APPLICATION_CREDENTIALS=/workspace/gcp-credentials.json
      export GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES=1
      gcloud auth login --cred-file=$GOOGLE_APPLICATION_CREDENTIALS
    triggeredBy:
      - postDevcontainerStart
Store the credential configuration file in your repository or generate it during environment startup. It does not contain secrets, only the configuration for how to obtain tokens.

Using V2 tokens with GCP

V2 tokens also work with GCP Workload Identity Federation. The V2 sub claim uses a path-based format (e.g., org:<orgID>/prj:<projectID>/env:<envID>). Adjust your attribute mappings and conditions accordingly. V2 tokens include fewer claims (org, gsub, and standard JWT fields), so attribute mappings are limited to google.subject=assertion.sub and conditions on assertion.sub or assertion.org. See the OIDC overview V2 section for the full V2 sub format reference.

Troubleshooting

“The audience in the credential configuration does not match”
  • The --audience in ona idp token must match the --allowed-audiences on the OIDC provider. Use the full provider resource name.
“The attribute condition was not met”
  • Your token’s claims do not satisfy the --attribute-condition CEL expression.
  • Decode your token: ona idp token --audience <AUDIENCE> --decode
  • Verify the organization_id, project_id, or other claims match the condition.
“Permission denied on resource”
  • The federated identity or service account does not have the required IAM role on the target resource.
  • Check the --member format in your IAM binding. For principalSet://, the attribute value must match exactly.
“Executable returned a non-zero exit code”
  • The ona idp token command failed. Verify the CLI is installed and authenticated in the environment.
  • Check that the audience value is correct.

Further reading