Secretless deployments from GitHub Actions to Kubernetes with OIDC and Argo Rollouts

Deploying to Kubernetes from CI used to mean stuffing long-lived cloud credentials into secrets, then hoping they never leaked. Today you can avoid that risk by using GitHub Actions’ OpenID Connect (OIDC) support to obtain short-lived cloud credentials at runtime, and combine that with a progressive delivery controller (Argo Rollouts) to automate safe canary releases. This article walks through the architecture, a concrete GitHub Actions workflow for AWS + EKS, how Argo Rollouts fits in, and practical security and observability tips.

Why this matters

GitHub Actions exposes OIDC tokens that cloud providers can trust; several clouds support workload identity/federation so you don’t need to store provider credentials in the repo. (docs.github.com)

How the pieces fit together

Configuring OIDC (high level)

Concrete example: GitHub Actions -> AWS EKS -> Argo Rollouts Below is a focused, practical CI job that: 1) Uses GitHub Actions OIDC to obtain temporary AWS credentials. 2) Updates kubeconfig for EKS. 3) Uses Helm (or kubectl) to update the image on a Rollout CR. 4) Triggers Argo Rollouts operations to drive a canary.

.github/workflows/deploy.yml (excerpt)

name: deploy
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write          # allow OIDC token to be minted
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
          aws-region: us-west-2

      - name: Update kubeconfig for EKS
        run: aws eks update-kubeconfig --name my-eks-cluster --region $

      - name: Install kubectl / argo-rollouts plugin / helm
        run: |
          curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
          chmod +x kubectl && sudo mv kubectl /usr/local/bin/
          curl -sSL -o /usr/local/bin/kubectl-argo-rollouts https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
          chmod +x /usr/local/bin/kubectl-argo-rollouts

      - name: Set image on Rollout (triggers canary)
        run: |
          kubectl argo rollouts set image rollout/my-app my-container=$:$
          kubectl argo rollouts get rollout my-app -n production -w

Notes on the above:

Rollout CR: a minimal canary snippet A Rollout replaces a Deployment and encodes canary steps (weights, pauses, analysis). Here’s the essence of a canary strategy (paraphrased):

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: { duration: 60s }
        - setWeight: 50
        - pause: {}
  template:
    spec:
      containers:
      - name: my-container
        image: myregistry/my-app:old-tag

Why use Argo Rollouts (short list)

Monitoring and automated analysis

Security and best practices

Cloud portability and alternatives

Common pitfalls and troubleshooting

Wrapping up Using OIDC with GitHub Actions eliminates long-lived deployment keys in your repo and gives you per-run, inspectable credentials. Pairing that flow with Argo Rollouts’ declarative canary/blue-green strategies gives you automated, low-risk deployments that are both secure and observable. The modern CI → cloud → Kubernetes pipeline is now short-lived, auditable, and designed for progressive delivery.

References and further reading

Implementing the pattern above gives you a deployment pipeline that’s more secure by default and better suited to run safe, observable canary releases in Kubernetes.