Documentation Index
Fetch the complete documentation index at: https://docs.skyhook.io/llms.txt
Use this file to discover all available pages before exploring further.
Skyhook generates GitHub Actions workflows that build your images and deploy to your clusters. Those workflows need two things from you:
- A way to authenticate to your cloud provider — so they can push to your container registry and talk to your cluster’s Kubernetes API
- A way to write back to your Git repos — semver bumps on release, GitOps overlay updates, commits against a separate deployment repo
This page covers both. For what the workflows do and which actions they call, see CI/CD Configuration. For the secret/variable names as a cheat-sheet, see Secrets and variables reference.
Three GitHub integrations, three purposes
If you run through full onboarding you’ll set up as many as three separate GitHub integrations. They do different things — don’t install one and assume it covers the others:
| Integration | What it does | When you need it | Set up with |
|---|
| GitHub Actions OIDC | Lets your CI/CD workflows authenticate to AWS, GCP, or Azure without long-lived keys. | Every project that uses the generated workflows with a cloud provider. | skyhook github setup |
| Deployment GitHub App | Lets workflows push commits to a separate deployment repo (GitOps overlays, image-tag bumps). Issues short-lived App tokens, not user creds. | Only if your Kubernetes manifests live in a different repo from your code. | skyhook onboard deploy-auth |
| ArgoCD GitHub App | Lets ArgoCD read your GitOps repo from inside the cluster. Completely separate from the one above. | Only if you’re using GitOps with ArgoCD. | skyhook onboard argocd configure-access — covered in GitOps with ArgoCD |
Most teams using GitOps end up with all three. Most teams doing direct kubectl deploys from a single repo only need the first.
Cloud authentication
The recommended path for AWS and GCP is OIDC — GitHub Actions authenticates to your cloud provider with a short-lived token, no long-lived keys to rotate. The Skyhook CLI can set this up end-to-end.
skyhook github setup creates the cloud-side trust relationship — the OIDC identity provider and an IAM role on AWS, or a Workload Identity Federation pool and service account on GCP — and prints the GitHub repository variables you need to add.Useful flags:
--cloud gcp / --cloud aws — skip the cloud prompt
--github-org <org> — explicit GitHub org (auto-detected from git remote otherwise)
--template-only — print CloudFormation/Terraform instead of running cloud CLI commands, useful when you don’t have aws/gcloud locally or want the setup applied by a platform team
--dry-run — show what would change without touching anything
The command expects gh plus the relevant cloud CLI (gcloud or aws) to be installed and authenticated. If they’re not, it falls back to template mode.On success you’ll see the variables to add to GitHub → Settings → Secrets and variables → Actions → Variables:
- AWS:
AWS_BUILD_ROLE, AWS_DEPLOY_ROLE
- GCP:
WIF_PROVIDER, WIF_SERVICE_ACCOUNT
You can re-run the command any time — it detects existing configuration and offers to update or reuse it.For the full OIDC flow — detection of existing setups, scope-mismatch handling, multi-account setups, template/dry-run modes, and the manual walkthroughs (GCP + AWS) using the same resource names the CLI creates — see GitHub OIDC setup. Use this path if you can’t or don’t want to set up Workload Identity — for example, on restricted projects where you don’t have IAM admin.
-
Set the right project:
gcloud config set project <project>
-
Create a service account and grant it the permissions the workflows need (GKE access + Artifact Registry write):
SA_NAME="github-actions"
PROJECT="$(gcloud config get-value project)"
SA_EMAIL="${SA_NAME}@${PROJECT}.iam.gserviceaccount.com"
gcloud iam service-accounts create "$SA_NAME" \
--display-name="GitHub Actions deploy"
for role in roles/container.developer roles/artifactregistry.writer; do
gcloud projects add-iam-policy-binding "$PROJECT" \
--member="serviceAccount:$SA_EMAIL" --role="$role"
done
-
Generate a JSON key and download it:
gcloud iam service-accounts keys create sa-key.json \
--iam-account="$SA_EMAIL"
-
Add the
sa-key.json contents as a GitHub secret named GCP_CREDENTIALS:
- Organization secret for org-wide access
- Repository secret for single-repo access
The generated build and deploy workflows fall back to GCP_CREDENTIALS when the WIF variables aren’t set.Service account keys are long-lived credentials. Prefer Workload Identity Federation when you can — skyhook github setup is the fastest path. Use this path if your environment can’t support OIDC — for example, self-hosted GitHub Actions runners behind a firewall.Create a deploy user with the permissions the workflows need, generate an access key, and set it as GitHub secrets AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY:AWS_REGION="us-east-1"
IAM_USER_NAME="github-actions"
aws iam create-user --user-name $IAM_USER_NAME
# ECR (build) + EKS read access (deploy)
aws iam attach-user-policy --user-name $IAM_USER_NAME \
--policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
aws iam put-user-policy --user-name $IAM_USER_NAME \
--policy-name EKSSkyhookAccessV1 \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Action": ["eks:AccessKubernetesApi", "eks:Describe*", "eks:List*"],
"Effect": "Allow",
"Resource": "*"
}]
}'
aws iam create-access-key --user-name $IAM_USER_NAME
Copy the AccessKeyId and SecretAccessKey from the output into GitHub secrets.If you’re using EKS with the legacy aws-auth ConfigMap (rather than EKS access entries), map the IAM user in:kubectl edit configmap aws-auth -n kube-system
data:
mapUsers: |
- userarn: arn:aws:iam::<account-id>:user/github-actions
username: github-actions
groups:
- system:masters # scope this down for production
Modern EKS clusters use access entries instead — if your cluster was created after late 2023, prefer those over aws-auth edits. Create a service principal (Azure AD application) and grant it the roles the workflows need — AcrPush on your ACR and Azure Kubernetes Service Cluster User Role on your AKS cluster.Two credential paths:OIDC with federated credentials (recommended). No long-lived client secret — Azure AD trusts GitHub OIDC tokens directly. Configure a federated credential on the app registration with the GitHub subject pattern repo:<ORG>/<REPO>:ref:refs/heads/main (or :pull_request, :environment:<name>, etc. depending on when workflows should be allowed to assume it). Then add these as GitHub repository variables (not secrets):
AZURE_CLIENT_ID — the app registration’s application (client) ID
AZURE_TENANT_ID — your Azure AD tenant ID
AZURE_SUBSCRIPTION_ID — the subscription the AKS cluster lives in
Client secret. If federated credentials don’t work in your environment (e.g. self-hosted runners with no OIDC issuer), create a client secret and store all three as GitHub secrets:
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_TENANT_ID
Prefer the OIDC path — client secrets are long-lived and need rotation. For clusters you operate yourself and non-cloud registries (Docker Hub, GHCR, Harbor, Quay, or any OCI-compliant registry), the workflows use standard Kubernetes and Docker authentication.Cluster access:
- Create a
KUBECONFIG secret in GitHub with the base64-encoded contents of a kubeconfig scoped to your deployment namespace. Prefer a dedicated ServiceAccount with namespace-scoped RBAC over a cluster-admin credential.
Registry credentials:
- GitHub Container Registry — workflows use
github.token automatically, no secret needed
- Docker Hub —
DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets
- Private / OCI-compliant —
REGISTRY_USERNAME and REGISTRY_PASSWORD secrets
Image pull inside the cluster:If your registry requires authentication to pull, create an imagePullSecret in each namespace:kubectl create secret docker-registry regcred \
--docker-server=<your-registry-url> \
--docker-username=<username> \
--docker-password=<password> \
-n <namespace>
No cloud provider CLI or IAM configuration is needed for BYOK. Kubernetes auth + Docker registry credentials are sufficient.
Writing back to your repos
The workflows push commits back to Git for a few reasons: bumping a service’s VERSION file on release, writing new image tags into GitOps overlays, and (for services with a separate deployment repository) updating manifests in a repo other than the source repo. Each of those needs something more privileged than the default GITHUB_TOKEN.
Separate deployment repositories
If your Kubernetes manifests live in a different repo from your code, workflows need cross-repo access. Skyhook’s Deployment GitHub App is the recommended way — fine-grained permissions, auto-rotating tokens, and attribution under a bot identity instead of a user.
CLI (recommended)
UI
Personal Access Token
skyhook onboard deploy-auth
skyhook onboard deploy-auth walks through creating the GitHub App, installing it on the deployment repo, and storing the credentials where the workflows can find them. Supports re-running for reconfiguration.On success you’ll have GH_APP_ID and GH_APP_PK as GitHub secrets (organization-wide or per-repo, depending on your GitHub plan).Open Settings → Code & Repositories → GitHub App, then Install App. See GitOps → Deployment GitHub App for the full walkthrough. Quick fallback — tied to one user’s GitHub identity.
- Create a fine-grained PAT with Contents: Read & Write on the deployment repo (and code repo if you need semver bumps).
- Add it as a GitHub secret named
GHA_PAT (repository or organization scope).
The workflows fall back to GHA_PAT when the GitHub App credentials aren’t set.
Protected branches
If your default branch is protected with required reviews, the workflow can’t push VERSION bumps or GitOps overlay updates with the built-in GITHUB_TOKEN — GitHub doesn’t grant it bypass permissions.
The simplest fix is to use the GH_APP_ID/GH_APP_PK secrets from the Deployment GitHub App (recommended above) and allow that app to bypass branch protection under Repository settings → Branches → Branch protection rules → Allow specified actors to bypass required pull requests.
As a fallback, you can use a PAT from a user with bypass permissions (organization admin, repository admin, or an explicit bypass actor):
-
Create a PAT at https://github.com/settings/tokens with full
repo access.
-
Add it as an org or repo secret named
GHA_PAT.
-
Reference it in the checkout step of
release.yml and (for GitOps) deploy.yml:
- uses: actions/checkout@v6
with:
token: ${{ secrets.GHA_PAT }}
The generated workflows reference GHA_PAT automatically when it’s set, so step 3 isn’t needed if you’re on the current template.
Verify the setup
Once credentials are in place, trigger a run to confirm. From the service directory, use skyhook deploy to build and deploy to a safe environment:
skyhook deploy --env dev --build -y
Or push a commit to your default branch and watch the Release workflow run in GitHub Actions. If it fails on authentication, the CI/CD troubleshooting guide maps the common error messages back to the specific secret or variable that’s missing or misconfigured.