- Go 86%
- Makefile 4.9%
- Shell 3.9%
- Nix 2.2%
- Smarty 2.2%
- Other 0.8%
| .github/workflows | ||
| charts/zitadel-bootstrap | ||
| cmd/bootstrap | ||
| internal/bootstrap | ||
| scripts/hooks | ||
| test/integration | ||
| .env.example | ||
| .envrc | ||
| .gitignore | ||
| .goreleaser.yaml | ||
| docker-compose.yaml | ||
| Dockerfile | ||
| Dockerfile.goreleaser | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
zitadel-bootstrap
zitadel-bootstrap is a small Go utility that bootstraps an already deployed ZITADEL instance via API.
Current bootstrap scope:
- create or reuse a human admin user
- grant instance and default-org administrator roles
- disable user registration in the instance default login policy
- optionally register a fixed set of ZITADEL action executions backed by a webhook service
Runtime contract
The bootstrap binary expects a reachable ZITADEL instance and an admin PAT with enough permissions to manage users, permissions, and, when enabled, action targets.
Required environment:
ZITADEL_HOSTZITADEL_ADMIN_PATorZITADEL_ADMIN_PAT_FILE
Optional environment:
ZITADEL_APITIMEOUTMANAGE_ACTIONSWEBHOOK_URLwhenMANAGE_ACTIONS=trueCREATE_ADMIN_USERADMIN_LOGIN_NAMEADMIN_FIRST_NAMEADMIN_LAST_NAMEADMIN_DISPLAY_NAMEADMIN_EMAILADMIN_EMAIL_VERIFIEDADMIN_INITIAL_PASSWORDwhenCREATE_ADMIN_USER=trueADMIN_ORG_ROLESTARGET_NAME_PREUSERINFO
Action management:
MANAGE_ACTIONS=true: manage the Zitadel Actions V2preuserinfotarget and execution used for token enrichmentMANAGE_ACTIONS=false: skip action reconciliation entirely and leave existing action state untouchedWEBHOOK_URLis only required when action management is enabled
Helm chart
The repo includes a Helm chart that deploys the bootstrap binary as a one-shot Kubernetes Job.
Chart location:
charts/zitadel-bootstrap
Typical install:
helm upgrade --install zitadel-bootstrap oci://edp.buildth.ing/devfw/charts/zitadel-bootstrap \
--version 0.1.0 \
--namespace zitadel \
--create-namespace \
--set env.zitadelHost=https://zitadel.example.com \
--set env.manageActions=true \
--set env.webhookUrl=https://webhook.example.com \
--set adminPat.existingSecret=zitadel-admin-pat \
--set adminInitialPassword.existingSecret=zitadel-admin-password
Important values:
image.repositoryimage.tagenv.zitadelHostenv.zitadelApienv.manageActionsenv.webhookUrlenv.createAdminUseradminPat.existingSecretadminPat.secretKeyadminPat.mountAsFileadminInitialPassword.existingSecret
The chart supports two PAT delivery modes:
- direct env var injection via
ZITADEL_ADMIN_PAT - mounted secret file via
ZITADEL_ADMIN_PAT_FILE
When env.manageActions=false, env.webhookUrl is not required.
When env.createAdminUser=false, adminInitialPassword.existingSecret is not required.
Example values for disabling action reconciliation:
env:
manageActions: false
zitadelHost: "https://example.com"
createAdminUser: true
Releases
Forgejo Actions workflows are included for validation and tagged releases.
.github/workflows/ci.yaml- runs tests
- lints the Helm chart
- renders the chart with required values
.github/workflows/release.yaml- triggers on tags matching
v* - runs tests and Trivy scans
- publishes multi-arch container images with GoReleaser
- packages the Helm chart
- attempts to push the chart to the Forgejo OCI registry
- falls back to uploading the packaged chart to the release if OCI chart push is unavailable
- triggers on tags matching
Expected release secrets:
PACKAGES_TOKENGPG_PRIVATE_KEYGPG_PASSPHRASE
The release workflow derives the registry path from GITHUB_SERVER_URL and github.repository_owner.
Local development
Run unit tests:
make test
Run integration tests:
make test-integration
Render the Helm chart locally:
helm template zitadel-bootstrap charts/zitadel-bootstrap \
--set env.zitadelHost=https://zitadel.example.com \
--set env.manageActions=true \
--set env.webhookUrl=https://webhook.example.com \
--set adminPat.existingSecret=zitadel-admin-pat \
--set adminInitialPassword.existingSecret=zitadel-admin-password