OIDC is the recommended cloud authentication path. For the static-credential alternatives (GCP service account keys, AWS IAM access keys, Azure client secret, BYOK) and the non-OIDC pieces of the CI/CD setup — the Deployment GitHub App, protected branches, the verify step — see GitHub Actions setup.
Run the step
skyhook github setup and skyhook onboard github are aliases — same flags, same behavior. The setup form is the canonical one; the onboard github form exists because the step is also the GitHub stage of the full skyhook onboard wizard.- Resolves the cloud provider from your Skyhook-registered clusters. A single supported cloud (GCP or AWS) is selected silently; multi-cloud setups prompt. BYOK (
other) clusters don’t influence detection — if all your clusters are BYOK, the CLI falls back to a genericgcp/awsprompt. For BYOK-only setups, use the BYOK tab on GitHub Actions setup instead (OIDC doesn’t apply there). - Checks tooling and authentication for
gcloud/awsandgh. For GCP, the CLI actively exercises the credential withgcloud auth print-access-tokenso expired sessions are caught here, not mid-setup. - Detects the GitHub org from
git remote get-url originin the current directory, falling back to a prompt. - Scans your cloud account for an existing GitHub OIDC configuration (read-only; skipped in
--template-onlymode or when the cloud CLI isn’t installed). - Creates or extends the setup based on what was found.
- Prints the GitHub variables to copy into your repository or organization.
Flags
| Flag | Description |
|---|---|
--cloud <gcp|aws> | Skip cloud auto-detection |
--github-org <name> | GitHub organization (defaults to the git remote in the current directory) |
--template-only | Emit a Terraform/CloudFormation template instead of executing |
--dry-run | Print the plan without creating anything |
--github-org is the GitHub organization. The Skyhook org is set via skyhook config set org <name> or the root-level -o/--org flag — don’t confuse the two.Prerequisites
- Cloud CLI installed and authenticated
- GCP:
gcloudwith an active login (not expired) - AWS:
awswithaws configureor an active SSO session
- GCP:
- Cloud admin permissions on the target project or account
- GCP: manage Workload Identity Pools, service accounts, and IAM bindings
- AWS:
iam:CreateOpenIDConnectProvider, role management, and CloudFormation deploy
ghCLI (optional) — if installed, makes setting GitHub variables a one-liner- A connected cluster in Skyhook (recommended) — the CLI auto-detects your cloud provider from registered clusters. Without one, you’ll be prompted to pick
gcporaws.
What the CLI creates
- GCP
- AWS
On GCP, the CLI creates a full Workload Identity Federation stack in the current
Scope is enforced at the binding (the
gcloud project:| Resource | Name | Purpose |
|---|---|---|
| Workload Identity Pool | github-pool | Container for OIDC providers |
| OIDC Provider | github-provider | Accepts tokens from token.actions.githubusercontent.com; attribute mapping google.subject=assertion.sub, attribute.repository=assertion.repository |
| Service Account | github-actions-sa@<project>.iam.gserviceaccount.com | Impersonated by GitHub Actions |
| SA IAM binding | roles/iam.workloadIdentityUser scoped to principalSet://.../attribute.repository/<org>/* | Lets any repo under your GitHub org impersonate the SA |
| Project IAM bindings | roles/artifactregistry.writer, roles/container.developer | Lets the SA push images to Artifact Registry and deploy to GKE |
principalSet pattern), not on the provider. The provider itself has no attributeCondition, so the same pool/provider can be extended later by adding a binding for another org rather than reconfiguring the provider.After success, the CLI prints:The CLI labels the service-account value
WIF_SA in the terminal for width, but the generated workflows expect the GitHub variable name to be WIF_SERVICE_ACCOUNT. Use WIF_SERVICE_ACCOUNT in GitHub.Existing OIDC detection
The scan is read-only and produces one of four outcomes.Nothing found
Found, scope matches your GitHub org
A scope-match detection doesn’t record completion in Skyhook’s org settings — on a fresh machine,
skyhook onboard status may still show this step as incomplete even though OIDC is already configured in the cloud. This is a known gap in the detect-and-exit path (the CLI has no force-mark path today).Found, scope mismatches
Common when one cloud project serves multiple GitHub orgs, or the existing setup is scoped to a single repository. The CLI offers a menu — see Handling scope mismatch below.Could not check
Usually a permissions issue.- GCP needs
iam.workloadIdentityPools.listandiam.serviceAccounts.getIamPolicy. - AWS needs
iam:ListOpenIDConnectProvidersandiam:GetRole.
Handling scope mismatch
You have GitHub OIDC in this cloud account, but it’s scoped to a different GitHub org, a single repository, or a scope pattern the CLI couldn’t parse. The CLI analyzes the existing setup’s bindings and providerattributeCondition to pick the safest options:
- Extend automatically (recommended) — shown when the CLI can safely add an IAM binding to the existing service account, mirroring the existing binding style (
attribute.repository_owner/<org>vsattribute.repository/<org>/*). If the existing provider’sattributeConditionwould reject tokens from your org, the CLI also proposes a relaxed replacement and shows the exact diff before running anything. GCP only — AWS trust-policy edits aren’t automated. - Create a new parallel OIDC setup — always available. Creates an independent pool/provider/SA stack. Safest when the existing setup is complex or you don’t want to modify it.
- Show me how to extend the existing setup myself — when the CLI has a concrete extend plan, it prints the exact
gcloud(oraws iam) commands for your specific setup. When auto-extend isn’t feasible, it prints a diagnostic and recommends the parallel or manual path instead of speculative commands. Either way, run what’s shown, then re-runskyhook github setup. - Skip for now — defer and come back later.
attributeCondition the CLI can’t safely parse), the CLI prints a diagnostic of what it found, explains why it can’t auto-extend, and recommends the parallel setup or manual path.
Option 1: Extend automatically
When the existing setup uses org-wide bindings with a simpleattributeCondition (a single equality or in [...] list) — or no condition at all — the CLI can extend it without user intervention. If the condition needs updating (e.g., from assertion.repository_owner == 'OldOrg' to assertion.repository_owner in ['OldOrg', 'your-org']), the update is part of the plan.
The confirmation shows every operation with its exact gcloud command before running anything.
Option 2: Manually extend the existing setup
Reuse the existing pool/provider by adding a new IAM binding for your GitHub org. When the CLI has enough information to build an extend plan, it prints the exact commands for your specific setup — substituting project number, pool/provider IDs, and SA email. Here’s the shape (your output will have concrete values):- GCP
- AWS
The
--member string has to match what the existing provider’s attributeMapping exposes:- If the provider maps
attribute.repository_owner(common for org-scoped setups), useattribute.repository_owner/your-org(no/*). - If it only maps
attribute.repository(what Skyhook’s own parallel setup creates), useattribute.repository/your-org/*.
roles/iam.serviceAccountAdminon the service account- If a condition update is also needed:
iam.workloadIdentityPools.providers.updateon the pool - The existing provider’s
attributeCondition(if any) must not exclude your org
skyhook github setup — detection will now show the scope covers your org and exit without changes.
Manual setup
Use this path when you can’t or won’t runskyhook github setup — restricted environments, admins who type commands personally, or IaC-only shops. The resource names below match what the CLI creates, so running the CLI later will detect your setup as already-configured instead of creating a parallel stack.
GCP manual setup
Substitute<PROJECT_ID> and <GITHUB_ORG> throughout.
WIF_PROVIDER=projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/github-pool/providers/github-providerWIF_SERVICE_ACCOUNT=github-actions-sa@<PROJECT_ID>.iam.gserviceaccount.com
Optional hardening: provider-level attributeCondition
Optional hardening: provider-level attributeCondition
The CLI-created provider has no Per Google’s Workload Identity Federation with deployment pipelines guide.
attributeCondition — scope is enforced at the IAM binding via the principalSet://.../attribute.repository/<org>/* pattern. This is intentional: the same pool/provider can be extended later by adding a binding for another org, without reconfiguring the provider.If you want defense-in-depth, you can add a provider-level condition that rejects tokens outside your org before they ever reach the binding check. It’s an extra layer, not a replacement for the binding constraint:AWS manual setup
sub claim to your org so random repos can’t impersonate it:
-
Build role —
AmazonEC2ContainerRegistryPowerUser(or narrowerecr:*on a single repository) for pushing to ECR. -
Deploy role — an inline policy with EKS client permissions. Do not attach
AmazonEKSClusterPolicy— that’s the policy for the EKS control plane’s own service role, not a client, and a workflow with it attached will still fail onaws eks update-kubeconfig.
eks:AccessKubernetesApi still needs RBAC inside the cluster before it can kubectl apply:
- EKS Access Entries (recommended, for clusters created after late 2023) —
aws eks create-access-entry+aws eks associate-access-policywithAmazonEKSClusterAdminPolicy(or a narrower one) aws-authConfigMap (legacy) — add amapRolesentry for the role ARN; see the AWS-keys tab on GitHub Actions setup for the ConfigMap edit pattern
AWS_BUILD_ROLE— used by the build workflow (ECR)AWS_DEPLOY_ROLE— used by the deploy workflow (EKS)
Multi-account and multi-project setups
OIDC configuration applies to the current cloud account or project only. If your GitHub Actions workflows push images or deploy to multiple AWS accounts or GCP projects, runskyhook github setup in each one — switching gcloud config or AWS profile between runs.
The CLI prints a reminder after setup with the account or project name so this is hard to miss.
Template-only mode
- GCP — Terraform HCL (
google_iam_workload_identity_pool,..._provider,google_service_account, bindings) - AWS — CloudFormation YAML (
AWS::IAM::OIDCProvider,AWS::IAM::Rolewith the trust policy and EKS access policy baked in)
terraform apply or aws cloudformation deploy. Useful when you want the setup reviewed in PRs, applied from a central IaC pipeline, or when you don’t have gcloud/aws installed locally — the CLI falls back to template mode automatically in that case.
Dry run
--template-only is also set, --dry-run is ignored — template output is already non-destructive.
After setup
GitHub variables
Set the variables printed by the CLI at the org level so every repo under the org can use them:- GCP
- AWS
--org and add --repo owner/name.
Status persistence
On successful setup (including a successful Workload Identity binding), the CLI records OIDC completion in Skyhook’s org settings.skyhook onboard status then shows the GitHub integration step as complete, and Skyhook’s workflow codegen knows which variable values to inject into generated YAML.
Generated workflows
Skyhook’s generated GitHub Actions workflows already referenceWIF_PROVIDER / WIF_SERVICE_ACCOUNT (GCP) and AWS_BUILD_ROLE / AWS_DEPLOY_ROLE (AWS) — no workflow edits needed after setup.
Troubleshooting
Google Cloud session expired — reauthentication required
Yourgcloud credentials have expired. The CLI catches this up-front by exercising the token with gcloud auth print-access-token, so the error surfaces before any cloud operations run.
When the CLI prompts, choose Re-authenticate now and continue — it runs gcloud auth login inline, without an account argument (passing an account forces gcloud into a password reauth flow that breaks for passkey and SSO accounts). Or run it manually:
skyhook github setup.
Workload Identity binding failed
The pool, provider, and service account were created, but theroles/iam.workloadIdentityUser binding on the SA couldn’t be added. OIDC setup is incomplete — GitHub Actions can’t impersonate the service account until the binding exists, and the CLI will not mark the step complete.
Verify you have roles/iam.serviceAccountAdmin on the service account (or project-level IAM admin), then rerun:
Could not check for existing OIDC configuration
Detection failed, usually from missing read permissions.- GCP needs
iam.workloadIdentityPools.listandiam.serviceAccounts.getIamPolicy. - AWS needs
iam:ListOpenIDConnectProvidersandiam:GetRole.
--template-only output instead.