Skip to main content
Version: 26.2

Workload identity federation

With workload identity federation, Seqera Platform connects to your cloud provider account without storing a long-lived workspace credential. Seqera Platform mints a short-lived, signed OpenID Connect (OIDC) token that names your organization, your workspace, and the type of work in progress. Your cloud provider exchanges that token for temporary credentials against a role you control.

Workload identity federation is an authentication mode you select when you create an AWS or Google Cloud credential. It is not a separate credential type. Seqera Platform stores only a role reference. For AWS, that is an Identity and Access Management (IAM) role Amazon Resource Name (ARN). For Google Cloud, it is a workload identity provider path and a service account email. You have no access key, service account key, or secret to rotate.

info

Workload identity federation is not available for Azure credentials. See Limitations.

Enable workload identity federation​

Workload identity federation requires Seqera Platform Enterprise 26.2 or later, and is enabled in every organization workspace by default. To use it, configure your instance as follows:

  • Set TOWER_OIDC_PEM_PATH to the path of a PEM file that holds an RSA keypair. This variable turns on the Seqera Platform OIDC provider. If it is unset, Seqera Platform serves no JSON Web Key Set (JWKS) endpoint, and no token exchange can complete. See Cryptographic options.
  • Set TOWER_OIDC_REGISTRATION_INITIAL_ACCESS_TOKEN to a random value. Setting TOWER_OIDC_PEM_PATH also opens the OIDC client registration endpoint. Without this token, anyone who can reach the API can register a client. See Data features.
  • Serve Seqera Platform over public HTTPS. AWS and Google Cloud fetch {issuer}/.well-known/openid-configuration and {issuer}/.well-known/jwks.json directly, and fail if they cannot reach the host. Workload identity federation does not work on localhost.
  • Optionally, set TOWER_IDENTITY_FEDERATION_ALLOWED_WORKSPACES to a comma-separated list of workspace IDs to restrict workload identity federation to those workspaces. If you omit the variable or leave it empty, every workspace can use it.

To generate the keypair:

openssl genrsa -out private.pem 4096
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
cat private.pem public.pem > oidc.pem

Platform signs every federation token with RS256 using this keypair, and sets the audience your cloud provider expects. TOWER_AUTH_TOKEN_SIGNING_RS256_ENABLED, TOWER_OIDC_ACCESS_TOKEN_AUDIENCE, and TOWER_OIDC_AUDIENCE_ENFORCEMENT_ENABLED apply only to the session and access tokens Platform issues for its own API. Workload identity federation does not need them.

info

Personal workspaces cannot use the workload identity federation credential mode, regardless of configuration.

Token exchange​

For each call, Platform mints a short-lived token and exchanges it with your cloud provider for temporary credentials. Your trust policy and permissions decide what those credentials can do. Write your policies against the values in this section. Configure AWS and Configure Google Cloud show one working setup.

AWS​

Platform calls sts:AssumeRoleWithWebIdentity with the following values:

FieldValue
RoleArnThe role ARN in the credential
RoleSessionNameseqera-{workload}, for example seqera-data or seqera-studio
WebIdentityTokenA JSON Web Token (JWT) that Platform signs with RS256. It is valid for 300 seconds by default.

The token carries the following claims:

ClaimValuePresent
issYour Platform URL followed by /api, for example https://seqera.example.com/apiAlways
subThe subject. See Subjects and attribution.Always
audsts.amazonaws.comAlways
iat, exp, jtiIssue time, expiry, and a unique token IDAlways
principal_idThe acting user's IDWhen a user is acting
principal_emailThe acting user's email addressWhen a user is acting and has an address
https://aws.amazon.com/tagsThe session tags below, all marked transitiveAlways
https://aws.amazon.com/source_identityThe acting user's email address, or their ID when the address does not meet AWS's source identity rulesWhen a user is acting

AWS turns the tags claim into these session tags:

TagValuePresent
seqera:orgOrganization IDOrganization workspaces
seqera:workspaceWorkspace IDOrganization workspaces
seqera:principal-idThe acting user's IDWhen a user is acting
seqera:principal-emailThe acting user's email addressWhen a user is acting and the address fits AWS's tag character set
seqera:workloadplatform, data, studio, or workflowAlways

Credential validation sends the fixed source identity seqera-validation instead of a user. When you save the credential, this checks that the trust policy allows sts:SetSourceIdentity. Without the check, a credential could pass validation and then fail on the first call that names a user.

Google Cloud​

Platform exchanges the token with the Google Cloud Security Token Service for a federated token. It then impersonates the service account with generateAccessToken and requests the https://www.googleapis.com/auth/cloud-platform scope.

The token carries the same iss, sub, iat, exp, and jti claims as on AWS, plus principal_id and principal_email when a user is acting. Its aud is the provider resource name, //iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL}/providers/{PROVIDER}, unless you set a custom token audience in the credential.

Google Cloud has no session tags or source identity. The acting user reaches Google Cloud Audit Logs only through the google.subject mapping. See Attribute mapping.

For a workspace that is not in TOWER_IDENTITY_FEDERATION_ALLOWED_WORKSPACES, Platform sends the legacy workflow subject on every Google Cloud call. Existing trust configurations keep matching. A change to the allow list takes effect when Platform's cached client for the credential expires.

Subjects and attribution​

Every token Seqera Platform generates carries a subject (sub) that names the tenant and the kind of work making the request, in the form org:{orgId}:wsp:{workspaceId}:{workload}.

The trailing segment is the workload type. The following table shows the subject each call presents, and who it is attributed to in principal_id, the user session tags, and the source identity. Platform makes every call except a Studio's own mounts and SDK calls, which the Studio container makes through its own token exchange.

CallSubjectAttributed to
Data Explorer bucket list, cached and refreshed in the backgrounddataUnattributed
Data Explorer browsing, previews, downloads, and uploadsdataThe browsing user
Studio mount dialog bucket listdataUnattributed
Studio mount dialog browsingdataThe browsing user
Studio checkpoints and data-link cache refreshdataUnattributed
A shared Studio's mounts and SDK callsstudioUnattributed
A private Studio's mounts and SDK callsstudioThe allow-listed user, or the creator if the allow list is empty. Unattributed if more than one user is allowed.
Credential validationplatformUnattributed. On AWS, the source identity is seqera-validation.
Compute environment describe and provisioning, Forge, job submission, log reads, and Secrets ManagerplatformUnattributed
Pipeline launch bucket probeworkflowThe launching user
The pipeline run itselfNot usedSee Pipeline runs and Pipeline runs on Google Cloud.

Platform decides a private Studio's attribution each time the Studio starts, because its privacy and allow list can change between sessions.

One credential presents all four subjects. Write your trust policy and IAM bindings to admit all of them. A condition that matches only one subject breaks every call that presents another.

The acting user is not part of the subject for organization workspaces, because a trust policy is scoped to a workspace. Per-user information travels separately, in session tags and source identity. See Cloud audit attribution.

Configure AWS​

Prerequisites

You need the following:

  • An AWS account with permission to create IAM identity providers and roles.
  • A Seqera Platform organization workspace with workload identity federation enabled.

Under Credentials > AWS > Workload identity, Seqera Platform shows the values to copy into AWS: the issuer, the four subjects, and the session tag keys.

  1. In the AWS console, go to IAM > Identity providers > Add provider > OpenID Connect.
  2. Set Provider URL to ${TOWER_SERVER_URL}/api and Audience to sts.amazonaws.com.
  3. Select Create role > Web identity, then select the provider you created.
  4. Replace the trust policy with the template in Trust policy.
  5. Attach an inline permission policy. See Permission policies.
  6. In Seqera Platform, create an AWS credential, select Workload identity, and enter the role ARN.

Trust policy​

Replace the placeholders in this template:

  • {{ACCOUNT_ID}}: Your AWS account ID.
  • {{ISSUER_HOST}}: Your Platform host and its /api path, without the scheme. For example, seqera.example.com/api.
  • {{ORG_ID}} and {{WORKSPACE_ID}}: The values Platform shows in the credential form.

The template wildcards the workload segment of the subject, so that one role serves every subject:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::{{ACCOUNT_ID}}:oidc-provider/{{ISSUER_HOST}}"
},
"Action": [
"sts:AssumeRoleWithWebIdentity",
"sts:TagSession",
"sts:SetSourceIdentity"
],
"Condition": {
"StringEquals": {
"{{ISSUER_HOST}}:aud": "sts.amazonaws.com"
},
"StringLike": {
"{{ISSUER_HOST}}:sub": "org:{{ORG_ID}}:wsp:{{WORKSPACE_ID}}:*"
}
}
}
]
}
note

The template uses the aws partition. In GovCloud or China, replace arn:aws: with arn:aws-us-gov: or arn:aws-cn: in both the Federated principal and the role ARN. The partition must match the one your role is in.

Each part of the trust policy is required:

  • sts:AssumeRoleWithWebIdentity performs the exchange.
  • sts:TagSession is required because every token carries session tags. Without it, AWS rejects the entire exchange rather than dropping the tags.
  • sts:SetSourceIdentity is required because tokens for a user's actions carry a source identity, and credential validation tests for it. Without it, AWS rejects the entire exchange.
  • The aud condition accepts only tokens minted for the AWS Security Token Service (STS).
  • The tenant prefix in the sub condition is the security boundary. Without it, any organization or workspace on the same installation could assume the role. The trailing * admits every workload type, because one role serves all four. To let one role serve several workspaces, list each workspace's prefix in the condition.

Permission policies​

Grant the role the combined permissions of every workload it serves. Because the trust policy's tenant prefix keeps other organizations and workspaces out, the permission policy does not need to repeat it. Credential validation needs nothing beyond STS. A credential can pass validation and still have no data access.

WorkloadNeeds
platformDescribe and job submission permissions for your compute environment, s3:ListBucket and s3:GetObject on the work directory, and the Forge permissions if Forge creates the environment
datas3:ListAllMyBuckets, plus object access on the buckets Data Explorer shows and on the work directory, where Studio checkpoints are stored
studioObject access on the buckets your Studios mount and on the work directory
workflows3:ListBucket on the work directory and the compute environment's allowed buckets, for the launch probe

Grant bucket discovery in its own statement. Because s3:ListAllMyBuckets has no resource dimension, a denial fails the whole listing instead of returning fewer buckets:

{
"Sid": "ListBuckets",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}

Grant object access on each bucket Data Explorer shows, each bucket your Studios mount, and the work directory:

{
"Sid": "Buckets",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": [
"arn:aws:s3:::BUCKET",
"arn:aws:s3:::BUCKET/*"
]
}

Data Explorer uses s3:GetBucketAcl only to mark public buckets. Without it, every bucket shows as private.

caution

When the trust policy is correct but the permission policy has no matching statement, the exchange succeeds and AWS denies every request afterwards. See A Studio starts but its data does not mount.

For compute environments, grant the describe permissions:

{
"Sid": "PlatformDescribe",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"batch:Describe*",
"batch:List*",
"ecs:Describe*",
"ecs:List*",
"eks:DescribeCluster",
"eks:ListClusters",
"iam:ListRoles",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:GetLogEvents"
],
"Resource": "*"
}

When you create an AWS Batch compute environment, Platform checks that the work directory is in the environment's region. This check needs s3:ListBucket. Platform also reads task logs and files from the work directory, which needs s3:GetObject. The Buckets statement covers both if it includes the work directory.

To submit runs, add batch:RegisterJobDefinition, batch:SubmitJob, batch:TerminateJob, batch:TagResource, and iam:PassRole. Platform registers a job definition on the first launch that has no matching one. A role without batch:RegisterJobDefinition fails on its first run.

AWS Batch compute environments need no EC2 launch permissions, because Batch scales the environment with its own service role. AWS Cloud compute environments launch and terminate EC2 instances directly, under the platform subject. For AWS Cloud, also grant the role the EC2 permissions listed in AWS Cloud.

Narrow access by workload or user​

The permissions above apply to every workload the role serves. To restrict a statement to one workload type, add a condition on the seqera:workload session tag, for example "StringEquals": {"aws:PrincipalTag/seqera:workload": "data"}. The {{ISSUER_HOST}}:sub condition key works too, because AWS keeps the sub claim available for the whole session. To restrict a statement by user, condition it on seqera:principal-id. See Per-user access control.

Batch Forge and Cloud Forge​

Batch Forge and Cloud Forge run under workload identity and present the platform subject. Grant IAM write permissions scoped to the TowerForge-* name prefix, and the compute permissions Forge uses to build the environment:

{
"Sid": "Forge",
"Effect": "Allow",
"Action": [
"iam:CreateRole", "iam:DeleteRole", "iam:GetRole", "iam:TagRole", "iam:PassRole",
"iam:AttachRolePolicy", "iam:DetachRolePolicy", "iam:ListAttachedRolePolicies",
"iam:PutRolePolicy", "iam:DeleteRolePolicy", "iam:ListRolePolicies",
"iam:CreateInstanceProfile", "iam:DeleteInstanceProfile", "iam:GetInstanceProfile",
"iam:TagInstanceProfile",
"iam:AddRoleToInstanceProfile", "iam:RemoveRoleFromInstanceProfile"
],
"Resource": [
"arn:aws:iam::{{ACCOUNT_ID}}:role/TowerForge-*",
"arn:aws:iam::{{ACCOUNT_ID}}:instance-profile/TowerForge-*"
]
},
{
"Sid": "ForgeCompute",
"Effect": "Allow",
"Action": [
"batch:*ComputeEnvironment", "batch:*JobQueue", "batch:Describe*", "batch:TagResource",
"ec2:CreateLaunchTemplate", "ec2:DeleteLaunchTemplate", "ec2:Describe*",
"ssm:GetParameters",
"elasticfilesystem:*", "fsx:*"
],
"Resource": "*"
}
caution

Keep the resource scope. A principal that can call both iam:CreateRole and iam:PassRole without a resource scope can create a role more privileged than itself and then pass it. Forge names what it creates {prefix}-{id}-{RoleKind}, where the prefix defaults to TowerForge and is set by TOWER_FORGE_PREFIX. If your deployment overrides that variable, scope the policy to your own prefix instead. A policy scoped to TowerForge-* denies every Forge role creation on an installation that renamed it.

Remove elasticfilesystem:* and fsx:* if the environment mounts neither. Cloud Forge needs the Forge statement and only the ec2 actions from ForgeCompute.

Pipeline runs​

Workload identity federation authenticates the calls Platform makes itself, for compute environment setup, job submission, Data Explorer, and Studios. A pipeline run does not use it. The Nextflow head job and every task it launches read the EC2 instance role from instance metadata. The workload identity role plays no part once the job starts. Before the launch, Platform checks that the run's buckets are reachable, under the workflow subject and attributed to the launching user. See Pipeline launch bucket probe.

The instance role needs the permissions Nextflow uses. On AWS Batch, these are S3 access on the work-directory bucket, plus Batch, ECS, EC2, and CloudWatch Logs permissions. Do not condition these grants on :sub, because an instance-profile session presents no OIDC subject. On a compute environment that Forge creates, Forge writes these grants. On one you create manually, add them to the instance role yourself.

caution

Leave TOWER_WIF_FORGE_LEGACY_MODE_ENABLED at its default, true. With false, Forge grants the instance role no data access. A compute environment that Forge creates for a workload identity credential then cannot run a pipeline, because the head job starts with no credentials. Studios and compute environment provisioning are unaffected. The variable applies to the whole installation. Forge reads it when it creates a compute environment. Changing it does not affect existing ones.

Configure Google Cloud​

Prerequisites

You need the following:

  • A Google Cloud project with permission to create workload identity pools and service accounts.
  • A Seqera Platform organization workspace with workload identity federation enabled.

Under Credentials > Google > Workload Identity, Seqera Platform shows the values to copy into Google Cloud: the OIDC issuer URL, the google.subject mapping, and the recommended attribute condition.

note

Platform uses the project in the Workload identity provider path, which is the project that hosts the pool, as the credential's project. Credential validation and Data Explorer list buckets in that project. Compute environments run their jobs and VMs there, and Platform creates pipeline secrets and reads Cloud Logging there. The service account can live in another project, but it needs its roles on the pool's project. Google recommends keeping pools in a dedicated project. If you follow that recommendation, these calls also go to the dedicated project.

  1. In the project that hosts the pool, enable the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs. See Configure Workload Identity Federation.

  2. In the Google Cloud console, go to the New workload provider and pool page. Under Create an identity pool, enter a Name and Description, then select Continue. The name is also the pool ID, and you can't change it later.

  3. Under Configure provider settings, in Select a provider, select OpenID Connect (OIDC). Enter a Provider name, which is also the provider ID, and set Issuer URL to ${TOWER_SERVER_URL}/api. See Create a workload identity pool and provider.

  4. Under Audiences, keep Default audience. The console shows it as https://iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL}/providers/{PROVIDER}. Platform sends the same path without the scheme, //iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL}/providers/{PROVIDER}, and the default audience accepts both forms. If you select Allowed audiences instead, add the //iam.googleapis.com/... form to the list. Select Continue.

  5. Under Configure provider attributes, set the google.subject mapping. Under Attribute conditions, enter the recommended condition. Select Save. See Attribute mapping.

  6. Create or select a service account, and set up the two grants that credential validation needs before you continue. They are on different tabs of the service account's page:

    • Permissions tab, for what the service account can access: select Manage access and add Storage Bucket Viewer (roles/storage.bucketViewer). This grants the role on the service account's own project. It works only when that project is also the pool's project. Otherwise, grant it on the pool project's IAM page, with the service account as the principal.
    • Principals with access tab, for who can act as the service account: select Grant access, enter the pool's principal, and add Workload Identity User (roles/iam.workloadIdentityUser). Without it, Platform cannot use the service account at all. Don't add this role on the Permissions tab or in the create flow. Those grant roles to the service account itself, which does not let the pool act as it.

    Without both, Platform saves the credential but marks it INVALID. IAM changes can take a few minutes to apply. For the principal to enter and the permissions each workload needs, see Impersonation and permissions.

  7. In Seqera Platform, create a Google credential, select Workload Identity, and enter:

    • Workload identity provider: The provider resource name, in the form projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL}/providers/{PROVIDER}. Use the project number, not the project ID. See Identifying projects.
    • Service account email: The service account to impersonate, in the form NAME@PROJECT_ID.iam.gserviceaccount.com.
    • Token audience (optional): Leave empty. Platform then uses the provider path as the audience.

    The credential uses workload identity federation only when both Service account email and Workload identity provider are set. Saving the credential runs credential validation.

caution

A pool or provider resource ID is immutable. To change one, create a replacement rather than renaming it.

Attribute mapping​

Set the google.subject mapping on the OIDC provider:

assertion.sub + (has(assertion.principal_id) ? ':usr:' + assertion.principal_id : '')

This mapping appends the acting user to the tenant subject. The subject Google records in its audit logs then identifies a specific user, for example org:{{ORG_ID}}:wsp:{{WORKSPACE_ID}}:data:usr:{{USER_ID}}. The has() guard keeps background tokens valid. Background tokens carry no principal_id and fall back to the tenant-only subject. Without the guard, their exchange fails with Could not obtain a value for google.subject. See Mappings and conditions.

caution

Map the user through google.subject, not a custom attribute.user. Custom attributes work in IAM conditions and principalSet bindings, but Google never writes them to audit logs. Only google.subject reaches the log.

Set the attribute condition Platform recommends in the credential form:

assertion.sub.startsWith('org:{{ORG_ID}}:wsp:{{WORKSPACE_ID}}:')

Without this condition, a whole-pool impersonation binding accepts subjects minted for any other tenant on the same Platform installation. Use a prefix rather than an exact match, because every workload type must pass, including the workflow subject Platform sends for workspaces where federation is not enabled.

Impersonation and permissions​

Allow the pool's identities to impersonate the service account. Grant the pool's principal the Workload Identity User role (roles/iam.workloadIdentityUser) on the service account itself, not on the project. A project-level grant applies to every service account in the project. See Service account impersonation.

Build the principal from the credential's Workload identity provider value. Drop the /providers/PROVIDER segment, prefix principalSet://iam.googleapis.com/, and end with /* for every identity in the pool, or with /attribute.workspace/WORKSPACE_ID for one workspace:

Value
Workload identity providerprojects/123456789012/locations/global/workloadIdentityPools/seqera-pool/providers/seqera-oidc
Principal for every identity in the poolprincipalSet://iam.googleapis.com/projects/123456789012/locations/global/workloadIdentityPools/seqera-pool/*
Principal for one workspaceprincipalSet://iam.googleapis.com/projects/123456789012/locations/global/workloadIdentityPools/seqera-pool/attribute.workspace/67890

The principal uses the pool's project number and pool ID, not the project ID or the pool's display name. See Principal identifiers.

To grant the role in the Google Cloud console:

  1. Go to the Service Accounts page, select the service account's project, and select the service account's email address.
  2. Open the Principals with access tab and select Grant access.
  3. Enter the principal.
  4. Assign the Workload Identity User role, then select Save.

See Grant a single role. Service Account User (roles/iam.serviceAccountUser) does not work here. It lacks iam.serviceAccounts.getAccessToken, and Google denies impersonation without it.

To grant the role with the gcloud CLI:

gcloud iam service-accounts add-iam-policy-binding SA_EMAIL \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL/*"

The whole-pool principal admits every identity that passes the provider's attribute condition. With the recommended condition, that is one workspace. If one pool serves several workspaces, Google recommends against granting access to all members of a pool. Add the attribute mapping attribute.workspace = assertion.sub.extract("wsp:{workspace}:"), and bind each workspace's service account to its one-workspace principal. One such binding covers all of that workspace's workloads.

caution

Do not bind an exact subject (principal://.../POOL/subject/SUBJECT) or an attribute.workload value. Both break when a subject changes shape. Use a pool-wide or attribute.workspace binding.

Platform signs download URLs through the IAM signBlob API. This needs roles/iam.serviceAccountTokenCreator on the service account, bound to the service account itself:

gcloud iam service-accounts add-iam-policy-binding SA_EMAIL \
--role=roles/iam.serviceAccountTokenCreator \
--member="serviceAccount:SA_EMAIL"

Without this binding, viewing or downloading file contents in Data Explorer fails with a signing error. Pipeline runs are unaffected.

Grant the service account the combined permissions of every workload it serves. Every workload impersonates the same service account, and Google Cloud evaluates that service account as the principal. Each grant therefore applies to every workload type.

WorkloadNeeds
platformstorage.buckets.list on the pool's project, for credential validation and the compute environment form. Object read on the work directory, for run logs and reports. The describe, job submission, and log permissions for your compute environment. See Pipeline runs on Google Cloud.
datastorage.buckets.list on the pool's project, plus the Data Explorer permissions below on the buckets Data Explorer shows and on the work directory, where Studio checkpoints are stored
studioObject access on the buckets your Studios mount and on the work directory
workflowstorage.objects.list on the work-directory bucket, for the launch probe

For Data Explorer, the service account needs both bucket-level and object-level permissions:

PermissionNeeded for
storage.buckets.listListing the buckets in the pool's project that Data Explorer shows
storage.buckets.getOpening a bucket or adding one to Data Explorer. Platform reads the bucket's metadata before each listing.
storage.objects.list, storage.objects.getBrowsing and downloading
storage.objects.createUploading
storage.objects.deleteDeleting

Object roles such as roles/storage.objectViewer include no bucket permissions. With only object roles, the service account can't list or open buckets in Data Explorer. Grant these two roles:

  • roles/storage.bucketViewer on the pool's project, to list and open buckets. Listing buckets is a project-level action. A grant on a single bucket isn't enough.
  • roles/storage.objectAdmin on each bucket, to browse, download, upload, and delete.

Data Explorer discovers buckets in the pool's project only. To browse a bucket in another project, add it with Add data repository, and grant the service account storage.buckets.get and object access on it. See Add data repository links.

Credential validation​

Platform validates the credential when you save it, and re-checks a valid credential about every 12 hours. The check presents the platform subject, or workflow in a workspace that TOWER_IDENTITY_FEDERATION_ALLOWED_WORKSPACES leaves out. The check runs the whole chain. It exchanges a token with the Security Token Service, impersonates the service account, and lists buckets in the pool's project. It passes only when all of the following are true:

  • The provider accepts the token. The issuer URL, audience, and attribute condition all match.
  • The pool's principal holds the Workload Identity User role on the service account.
  • The service account holds the storage.buckets.list permission on the pool's project, for example through roles/storage.bucketViewer.

Unlike on AWS, where validation needs nothing beyond the token exchange, a Google credential with a correct trust setup still fails validation without storage.buckets.list on the pool's project.

A failed check marks the credential INVALID, with a reason that starts with Cannot validate Google WIF Security Keys, reason:. Throttling and Google server errors leave the status unchanged. Platform does not re-check an INVALID credential on its own. After you fix the cause, select Validate on the credential. See Validate a credential manually. IAM changes typically take 2 minutes to apply, and sometimes 7 minutes or longer. See Access change propagation.

Pipeline runs on Google Cloud​

As on AWS, a pipeline run does not use workload identity federation. The Nextflow head job and its tasks authenticate as the service account attached to their VMs.

On Google Cloud Batch, that is the compute environment's Service account email. If you leave it empty, Platform sets it to the credential's own service account. The head job and every task then run as that service account. It needs the Google Cloud Batch service account permissions. Its Service Account User role (roles/iam.serviceAccountUser) must also cover itself, because Platform submits the jobs as the same account. Google requires Service Account User on a job's service account to create the job. See Control access for a job using a custom service account.

For Platform's own calls under the platform subject, the service account also needs the following on the pool's project:

  • roles/compute.viewer, for the zones, machine types, images, and networks in the compute environment form.
  • roles/logging.viewer, to read Google Cloud Batch job logs from Cloud Logging. It includes resourcemanager.projects.get, which Platform needs to resolve the project name from its number.
  • roles/secretmanager.admin, if your pipelines use secrets. Platform creates and deletes pipeline secrets in the pool's project.

On Google Cloud compute environments, Cloud Forge creates a service account for the VM, under the platform subject. With TOWER_WIF_FORGE_LEGACY_MODE_ENABLED at its default, true, Forge grants it roles/storage.objectAdmin on the work-directory bucket, and roles/logging.logWriter, roles/monitoring.metricWriter, roles/storage.bucketViewer, and roles/storage.objectViewer on the pool's project. With false, Forge grants only roles/logging.logWriter and roles/monitoring.metricWriter, and the VM has no storage access of its own. The caution in Pipeline runs applies. The credential's service account needs the Google Cloud permissions that Forge uses to create these resources.

Existing Google Cloud credentials​

Before Seqera Platform Enterprise 26.2, a Google workload identity credential always presented the workflow subject. From 26.2, the credential presents platform, data, studio, or workflow, depending on the request.

caution

If you already use a Google workload identity credential, check your impersonation bindings before you upgrade. Because workload identity federation is on in every organization workspace by default, the credential starts presenting all four subjects when you upgrade. A binding against the exact subject (principal://.../POOL/subject/org:{{ORG_ID}}:wsp:{{WORKSPACE_ID}}:workflow) or against an attribute.workload value then stops matching, and the workspace loses access. Move those bindings to a pool-wide (POOL/*) or attribute.workspace form first. Both read the tenant part of the subject, which does not change. To keep a workspace on the workflow subject while you move its bindings, set TOWER_IDENTITY_FEDERATION_ALLOWED_WORKSPACES to a list that leaves it out. See Google Cloud.

Cloud audit attribution​

Workload identity sessions carry the acting user's identity into your cloud provider's audit log, where you can attribute a request to a specific Seqera user. The two providers record the identity differently:

What the audit log recordsWhat it takes
AWSThe assumed IAM role on every entry, plus the acting user as session tags on the exchange event and as a source identity on every request in the sessionOnly the trust policy. Platform always attaches the tags, and a source identity whenever a user is acting. The trust policy must grant sts:TagSession and sts:SetSourceIdentity or the exchange fails outright
Google CloudThe mapped subject, which carries the acting user only if the google.subject mapping appends principal_idThe guarded mapping in Attribute mapping, and Data Access audit logs, which are off by default and billed separately

The identifier differs by provider. On AWS, the source identity is the user's email where one is known, and their ID otherwise. On Google Cloud, principal_id is always an internal numeric ID.

AWS​

Every session carries the session tags listed in Token exchange, and a source identity when a user is behind the request.

Use tags to authorize a request and source identity to trace it. aws:PrincipalTag/* condition keys match tags. CloudTrail records them as principalTags on the AssumeRoleWithWebIdentity event only, never on the requests made afterwards. CloudTrail records source identity on every request in the session, in userIdentity.sessionContext.sourceIdentity. Source identity is the only way to determine who read a given object.

Because the role session name is seqera-{workload}, CloudTrail shows the workload type in every assumed-role ARN.

To scope one role across many workspaces, use the workspace tag as a policy variable:

{
"Sid": "PerWorkspaceBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::wsp-${aws:PrincipalTag/seqera:workspace}",
"arn:aws:s3:::wsp-${aws:PrincipalTag/seqera:workspace}/*"
]
}

Per-user access control​

Workload identity federation resolves to one role per workspace, not one role per user. Every user in the workspace assumes the same role and, by default, has the same cloud permissions.

Per-user access control comes from your IAM policy, not from Platform. Condition a statement on the seqera:principal-id tag, and your cloud provider decides what that user can reach. An explicit Deny overrides every Allow. To deny one person access to a bucket:

{
"Sid": "BlockUser",
"Effect": "Deny",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKET",
"arn:aws:s3:::BUCKET/*"
],
"Condition": {
"StringEquals": {
"aws:PrincipalTag/seqera:principal-id": "{{USER_ID}}"
}
}
}
caution

A deny list allows every new user by default. Allow-listing by team is not possible because Platform does not emit team membership as a session tag. Plan your policies around denying named users rather than admitting named teams.

A seqera:principal-id condition also has no effect inside a Studio shared with the workspace. A shared session carries no acting user. It presents itself as the Studio, with the subject org:{orgId}:wsp:{workspaceId}:studio, not as a user. Your policy can match the Studio but not an individual user. To limit what a shared Studio can reach, condition a statement on the studio workload and scope its Resource to those buckets. See Narrow access by workload or user.

Note the following when you write policies against these values:

  • Platform asserts the tag values. AWS trusts the provider and does not verify them.
  • Condition on seqera:principal-id, which is stable. Use seqera:principal-email for reading only. Addresses are mutable and reassignable, and absent for service accounts.
  • A condition on an absent tag does not match. A statement requiring seqera:principal-id denies every platform session and all background work, such as cache refresh and job polling.
  • Renaming these keys is a breaking change, because they appear in your IAM policies.

Google Cloud​

Google Cloud Audit Logs record only the mapped google.subject. Custom claims and attributes never reach the log. Organization, workspace, and workload type are traceable because they are part of the base subject. The acting user is traceable only if the google.subject mapping appends principal_id. See Attribute mapping.

Cloud Storage reads and writes are Data Access audit logs, which are off by default. Enable them on the project or service account to see Data Explorer activity. Because previews and downloads use a URL signed by the service account, Cloud Storage logs them as the service account. The token exchange and impersonation entries need Data Access Admin Read for the Security Token Service and IAM Service Account Credentials APIs.

Requests with no acting user​

Background work (data link cache refresh, Studio checkpoints, and job polling) carries no acting user. Neither does a Studio shared with the workspace, because no single person operates a shared session for its whole life. Those entries show the tenant subject with no per-user attribution.

Pipeline launch bucket probe​

When the preflight check is enabled, compute environments that use workload identity probe the work directory before a launch. A run that cannot reach its work directory fails immediately instead of part-way through.

On AWS, the probe performs a fresh, uncached token exchange with the workflow subject, then calls ListObjectsV2 with maxKeys=1 against the work directory and each of the compute environment's allowed buckets. Grant s3:ListBucket on each of those buckets under the workflow subject.

On Google Cloud, the probe lists the root of the work-directory bucket rather than the work-directory prefix, and it does not check allowed buckets. Grant storage.objects.list on the bucket itself. A grant conditioned on the work-directory prefix is denied.

The probe response decides the launch:

  • An explicit AccessDenied refuses the launch with WORK_DIR_INVALID. The message names the subject and the bucket.
  • When AWS refuses the token exchange itself, the launch is also refused. The message names the subject only, because no bucket was reached. A trust policy that does not admit the workflow subject fails this way, with AccessDenied from the token exchange.
  • Inconclusive responses (throttling, quota, billing, and timeouts) log a warning and allow the launch.

Platform does not probe credentials that use access keys or an assumed role.

note

The Google Cloud probe runs from your Platform instance's network location. VPC Service Controls or organization policies can deny that request even when a Batch job inside the permitted perimeter could reach the bucket.

Credential revocation​

Platform briefly caches the temporary cloud credentials it derives from a workload identity credential. Editing or deleting the credential, or removing a user from the workspace, drops the affected cache entries immediately across all nodes.

Platform cannot recall access it has already handed out:

  • On AWS, a presigned URL embeds the temporary credential and stays valid until that credential expires, up to approximately one hour.
  • On Google Cloud, a presigned URL is signed by the service account and stays valid for the Data Explorer URL duration, one day by default, regardless of the credential's lifetime.
  • A running Studio keeps renewing its workload identity until it stops, for up to three days by default. Deleting the credential or removing the user does not end a running session's access. To cut it off, stop the Studio, or change the role's trust policy or the service account's impersonation binding.

Limitations​

  • Azure is not supported. Azure federated identity credentials match the subject claim by exact string. That would require one federated credential per workspace per workload type, against a cap of 20 per identity. Flexible federated identity credentials solve this with wildcard matching, but only for a fixed list of Microsoft-supported issuers that Platform cannot join.
  • You cannot change an AWS credential's mode after creation. To move an existing AWS credential to workload identity, create a new credential. Google credentials have no mode field, and you can update them in place.
  • On AWS, Data Explorer omits buckets the credential cannot reach rather than showing them as inaccessible. You cannot distinguish an omitted bucket from one that does not exist. This applies to every AWS credential type, not only workload identity federation.
  • The credential form accepts only arn:aws: role ARNs. To use a role in the aws-us-gov or aws-cn partition, create the credential through the API.
  • You can create AWS workload identity credentials through version 1 of the API only. Google workload identity credentials are available in both versions.
  • Data lineage does not support workload identity credentials. Platform builds its lineage bucket and SNS topic clients without a workload identity. Lineage works only with key-based or role-based AWS credentials.
  • A trust policy error does not prevent credential creation. Saving runs the token exchange, but a failed exchange does not roll back the new credential. Check the credential's status to confirm the exchange succeeded.

For token exchange, permission, and audit attribution failures, see Workload identity troubleshooting.