Skip to content

Accessing Woodpecker privately

AKKO v2026.04 ships Woodpecker CI as an internal-only Deployment. The default ingress.enabled=false means no inbound traffic hits it from the public internet — a sensible default for any CI server (CVE exposure, credential theft, supply-chain abuse are real risks).

This page lists the three supported access patterns, in order of preference.

1. kubectl port-forward (default)

Zero network exposure — an operator forwards the Service to their laptop on demand:

kubectl -n akko port-forward svc/akko-akko-woodpecker-server 8000:80
# Then open http://localhost:8000

Ideal for casual admin use. No credentials cross the public internet, sessions die when the port-forward is closed.

Join the cluster nodes to a private overlay network — Tailscale, Cloudflare Tunnel, WireGuard, Nebula — and the cluster-internal Service becomes reachable only by authorised members of the mesh.

Tailscale example:

# On every k8s node
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --authkey=<key> --advertise-routes=<cluster-cidr>

# On your laptop
tailscale up
kubectl proxy   # or a direct port-forward through the mesh

No AKKO chart change required.

3. Opt-in Ingress (only if you accept the risk)

If your operational reality requires a public URL (e.g. GitHub webhooks need to reach Woodpecker directly), opt in deliberately with a strict stack:

akko-woodpecker:
  ingress:
    enabled: true
    className: traefik
    annotations:
      # Traefik middlewares — OAuth2 gate + IP allowlist
      traefik.ingress.kubernetes.io/router.middlewares: >-
        akko-oauth2-woodpecker@kubernetescrd,akko-ghwebhooks-ipallowlist@kubernetescrd
    tls:
      - hosts: ["ci.your-domain.example"]
        secretName: woodpecker-tls

Then create two Traefik Middleware CRs :

  • akko-oauth2-woodpecker — oauth2-proxy that only lets the akko-admins Keycloak group through.
  • akko-ghwebhooks-ipallowlist — Traefik IPAllowList with GitHub's published webhook ranges (https://api.github.com/meta → .hooks).

GitHub webhooks without public exposure

For push-to-main / PR webhooks when the Ingress is off:

  • Cloudflare Tunnel (cloudflared) — free, attach it to a Cloudflare Access policy so only GitHub webhook ranges can post. The Tunnel traverses NAT without opening any inbound port.
  • smee.io — a public proxy that forwards GitHub webhooks to a local agent. Good for dev, less ideal for prod.
  • Repo poll mode — a CronJob in the cluster runs woodpecker-cli pipeline start --interval 30s against the repo and triggers pipelines without relying on webhooks at all.

Do NOT

  • Do not helm upgrade with akko-woodpecker.ingress.enabled=true on a default domain without an OAuth2 gate and an IP allowlist.
  • Do not embed webhook URLs with Woodpecker secrets in a public repo.
  • Do not configure Woodpecker to sign Cosign artefacts under a publicly discoverable OIDC issuer — use a private one.