Skip to content

Auth Modules

Kyku supports multiple authentication strategies, from environment variables to OIDC-based temporary credentials in CI/CD.

The @kykucloud/core/auth module abstracts credential resolution:

interface AuthConfig {
provider: 'aws' | 'gcp' | 'hetzner' | 'digitalocean';
env: string;
// OIDC-specific
awsRoleArn?: string;
gcpWorkloadProvider?: string;
gcpServiceAccount?: string;
}

The auth module resolves credentials in priority order:

  1. OIDC (if CI environment detected and OIDC config present)
  2. Env vars (standard cloud SDK credentials)
  3. Config/SDK default chains (AWS profile, GCP ADC)
Terminal window
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...

Kyku auto-detects CI platforms and exchanges OIDC tokens for AWS credentials:

env:
KYKU_AWS_ROLE_ARN: arn:aws:iam::123456789012:role/KykuDeployRole

The exchange uses STS AssumeRoleWithWebIdentity:

  1. Reads OIDC token from CI platform (GitHub: ACTIONS_ID_TOKEN_REQUEST_URL)
  2. Calls STS AssumeRoleWithWebIdentity with the token and role ARN
  3. Injects temporary AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN as env vars
  4. Standard SDK picks them up automatically
Terminal window
aws sso login --profile my-profile
export AWS_PROFILE=my-profile

Kyku reads the SSO-sourced credentials from the shared credentials file via the standard SDK credential chain.

Terminal window
gcloud auth application-default login
Terminal window
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
export GOOGLE_PROJECT_ID=my-project

Two approaches:

1. Using google-github-actions/auth (recommended for GitHub Actions):

- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/123/...
service_account: [email protected]

2. Direct OIDC via Kyku env vars:

env:
KYKU_GCP_WORKLOAD_PROVIDER: projects/123/locations/global/workloadIdentityPools/my-pool/providers/github
KYKU_GCP_SERVICE_ACCOUNT: [email protected]
KYKU_GCP_PROJECT_ID: my-project

Kyku uses google-auth-library for ADC and OIDC token exchange. Tokens are cached with a 1-minute margin before expiry.

Hetzner Cloud API does not support OIDC. Use API tokens:

Terminal window
export HCLOUD_TOKEN=your-cloud-token

Additional tokens for Hetzner DNS and S3:

Terminal window
export HETZNER_DNS_TOKEN=your-dns-token
export HETZNER_S3_ACCESS_KEY=your-s3-key
export HETZNER_S3_SECRET_KEY=your-s3-secret
Terminal window
export DIGITALOCEAN_TOKEN=your-api-token
export DO_SPACES_ACCESS_KEY=your-spaces-key
export DO_SPACES_SECRET_KEY=your-spaces-secret

The auth module returns early for token-based providers:

function resolveAuth(config: AuthConfig): AuthResult {
if (config.provider === 'hetzner' || config.provider === 'digitalocean') {
// Token-based — no OIDC exchange needed
return { type: 'token' };
}
if (isCI() && hasOidcConfig(config)) {
return exchangeOidcToken(config);
}
// Rely on SDK credential chain (env vars, config file, etc.)
return { type: 'sdk-default' };
}

Kyku detects CI platforms by checking environment variables:

Platform Detection Env Var
GitHub Actions GITHUB_ACTIONS
GitLab CI GITLAB_CI
CircleCI CIRCLECI
Jenkins JENKINS_HOME

For OIDC exchanges, the resulting credentials are cached to avoid repeated STS calls within a single plan/apply run:

  • AWS temp creds expire in 1 hour (refreshed if needed)
  • GCP access tokens cached with 1-minute margin before expiry
  • Hetzner/DO tokens are static and don’t expire