Skip to content

Instantly share code, notes, and snippets.

@alexandermalyga
Created March 2, 2025 13:44
Show Gist options
  • Save alexandermalyga/599a99425ea2d63dcd18709bea2bcbc0 to your computer and use it in GitHub Desktop.
Save alexandermalyga/599a99425ea2d63dcd18709bea2bcbc0 to your computer and use it in GitHub Desktop.
services:
postgres:
image: postgres:17
environment:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 2s
timeout: 5s
retries: 5
zitadel:
image: ghcr.io/zitadel/zitadel:v2.70.0
command: start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
environment:
ZITADEL_DATABASE_POSTGRES_HOST: postgres
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
ZITADEL_EXTERNALSECURE: false
ZITADEL_PORT: 8081
ZITADEL_EXTERNALPORT: 8081
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: zitadel-admin
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: Password1!
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: false
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: zitadel-admin-sa
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: ZITADEL Admin SA
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_EXPIRATIONDATE: '2100-01-01T00:00:00Z'
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE: 1
ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH: /keys/admin-sa-key.json
depends_on:
postgres:
condition: service_healthy
ports:
- 8081:8081
volumes:
- ./.volumes/zitadel-compose:/keys
import httpx
import jwt
import json
from datetime import datetime, timedelta, UTC
KEY_PATH = ".volumes/zitadel-compose/admin-sa-key.json"
BASE_URL = "http://localhost:8081"
with open(KEY_PATH) as f:
key = json.load(f)
admin_jwt = jwt.encode(
payload={
"iss": key["userId"],
"sub": key["userId"],
"aud": BASE_URL,
"exp": datetime.now(UTC) + timedelta(hours=1),
"iat": datetime.now(UTC),
},
key=key["key"],
algorithm="RS256",
headers={"alg": "RS256", "kid": key["keyId"]},
)
# Get admin SA token
with httpx.Client() as client:
resp = client.post(
f"{BASE_URL}/oauth/v2/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"scope": " ".join(
[
"openid",
"urn:zitadel:iam:org:project:id:zitadel:aud",
]
),
"assertion": admin_jwt,
},
).json()
access_token = resp["access_token"]
# Create project
with httpx.Client() as client:
resp = client.post(
f"{BASE_URL}/management/v1/projects",
json={
"name": "My Project",
},
headers={"Authorization": f"Bearer {access_token}"},
).json()
project_id = resp["id"]
# Create frontend SPA app
with httpx.Client() as client:
resp = client.post(
f"{BASE_URL}/management/v1/projects/{project_id}/apps/oidc",
json={
"name": "My App",
"accessTokenType": "OIDC_TOKEN_TYPE_JWT",
"appType": "OIDC_APP_TYPE_USER_AGENT",
"authMethodType": "OIDC_AUTH_METHOD_TYPE_NONE",
"grantTypes": [
"OIDC_GRANT_TYPE_AUTHORIZATION_CODE",
"OIDC_GRANT_TYPE_TOKEN_EXCHANGE",
],
},
headers={"Authorization": f"Bearer {access_token}"},
).json()
app_id = resp["appId"]
client_id = resp["clientId"]
# Enable token exchange in the instance
with httpx.Client() as client:
resp = client.put(
f"{BASE_URL}/v2/features/instance",
json={"oidcTokenExchange": True},
headers={"Authorization": f"Bearer {access_token}"},
).json()
# Enable impersonation in the instance
with httpx.Client() as client:
resp = client.put(
f"{BASE_URL}/admin/v1/policies/security",
json={"enableImpersonation": True},
headers={"Authorization": f"Bearer {access_token}"},
).json()
# Create human user
with httpx.Client() as client:
resp = client.post(
f"{BASE_URL}/v2/users/human",
json={
"profile": {
"givenName": "John",
"familyName": "Doe",
},
"email": {
"email": "[email protected]",
},
},
headers={"Authorization": f"Bearer {access_token}"},
).json()
user_id = resp["userId"]
# Impersonate human user
with httpx.Client() as client:
resp = client.post(
f"{BASE_URL}/oauth/v2/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token": user_id,
"subject_token_type": "urn:zitadel:params:oauth:token-type:user_id",
"actor_token": access_token,
"actor_token_type": "urn:ietf:params:oauth:token-type:access_token",
"requested_token_type": "urn:ietf:params:oauth:token-type:jwt",
"scope": "openid",
"client_id": client_id,
},
).json()
2025/03/02 13:39:39 http: panic serving 172.18.0.1:61586: runtime error: invalid memory address or nil pointer dereference
goroutine 14422 [running]:
net/http.(*conn).serve.func1()
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:1947 +0xb0
panic({0x2a17880?, 0x7e928d0?})
/opt/hostedtoolcache/go/1.23.6/x64/src/runtime/panic.go:785 +0x124
github.com/zitadel/zitadel/internal/api/oidc.(*Server).createJWT(0x4003f1be40?, {0x592f050?, 0x4006146420?}, {0x5964650, 0x4004f2c7c0}, 0x0, 0x4006186270, 0x0, 0x4006142300)
/home/runner/work/zitadel/zitadel/internal/api/oidc/token.go:193 +0xf0
github.com/zitadel/zitadel/internal/api/oidc.(*Server).createExchangeJWT(0x40041ca1c0, {0x592f050?, 0x4006146420?}, 0x4004f2c7c0, 0x4006186270, 0x0, 0x4006142300, {0x40033e47b0, 0x12}, {0x40033e47c8, ...}, ...)
/home/runner/work/zitadel/zitadel/internal/api/oidc/token_exchange.go:352 +0x244
github.com/zitadel/zitadel/internal/api/oidc.(*Server).createExchangeTokens(0x40041ca1c0, {0x592f050, 0x4006146420}, {0x40039154a0, 0x24}, 0x4004f2c7c0, 0x4003f608f0, 0x4002cc7550, {0x4003f1be40, 0x1, ...}, ...)
/home/runner/work/zitadel/zitadel/internal/api/oidc/token_exchange.go:243 +0x4a8
github.com/zitadel/zitadel/internal/api/oidc.(*Server).tokenExchange(0x40041ca1c0, {0x592f050?, 0x4005fc3290?}, 0x40037a5ef0)
/home/runner/work/zitadel/zitadel/internal/api/oidc/token_exchange.go:85 +0x5dc
github.com/zitadel/zitadel/internal/api/oidc.(*Server).TokenExchange(0x58deaa0?, {0x592f050?, 0x4005fc3290?}, 0x4005faadc0?)
/home/runner/work/zitadel/zitadel/internal/api/oidc/token_exchange.go:32 +0x24
github.com/zitadel/oidc/v3/pkg/op.(*webServer).tokenExchangeHandler(0x4002dd2c60, {0x5929a00, 0x400410dce0}, 0x4005faadc0, {0x5964650, 0x4004f2c7c0})
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/server_http.go:367 +0x6e4
github.com/zitadel/oidc/v3/pkg/op.(*webServer).tokensHandler.(*webServer).withClient.func4({0x5929a00, 0x400410dce0}, 0x4005faac80)
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/server_http.go:157 +0x1b0
github.com/zitadel/oidc/v3/pkg/op.(*webServer).tokensHandler(0x4002dd2c60, {0x5929a00, 0x400410dce0}, 0x4005faac80)
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/server_http.go:273 +0x414
github.com/zitadel/oidc/v3/pkg/op.(*webServer).endpointRoute.func1({0x5929a00, 0x400410dce0}, 0x4005faab40)
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/server_http.go:130 +0x1d0
net/http.HandlerFunc.ServeHTTP(0x4005d503c0?, {0x5929a00?, 0x400410dce0?}, 0x40019ec7c5?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/go-chi/chi/v5.(*Mux).routeHTTP(0x4003181440, {0x5929a00, 0x400410dce0}, 0x4005faab40)
/home/runner/go/pkg/mod/github.com/go-chi/chi/[email protected]/mux.go:459 +0x280
net/http.HandlerFunc.ServeHTTP(0x592f050?, {0x5929a00?, 0x400410dce0?}, 0x58ce210?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/oidc/v3/pkg/op.(*IssuerInterceptor).setIssuerCtx(0x30?, {0x5929a00, 0x400410dce0}, 0x4005faaa00, {0x58dc380, 0x4003175a80})
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/context.go:52 +0x138
github.com/zitadel/oidc/v3/pkg/op.(*IssuerInterceptor).Handler.func1({0x5929a00?, 0x400410dce0?}, 0x4005d6abf8?)
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/context.go:28 +0x40
net/http.HandlerFunc.ServeHTTP(0x592f050?, {0x5929a00?, 0x400410dce0?}, 0x7fa0b80?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/api/http/middleware.ActivityHandler.func1({0x5929a00, 0x400410dce0}, 0x4005faa780)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/activity_interceptor.go:12 +0x1a0
net/http.HandlerFunc.ServeHTTP(0x4003f20ea0?, {0x5929a00?, 0x400410dce0?}, 0x4005faa8c0?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/api/oidc.NewServer.(*AccessInterceptor).HandleWithPublicAuthPathPrefixes.(*AccessInterceptor).handle.func9.1({0x5927670, 0x40018fee70}, 0x4005faa780)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/access_interceptor.go:147 +0x180
net/http.HandlerFunc.ServeHTTP(0x592f050?, {0x5927670?, 0x40018fee70?}, 0x58c5190?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/api/http.CopyHeadersToContext.func1({0x5927670, 0x40018fee70}, 0x4005faa640)
/home/runner/work/zitadel/zitadel/internal/api/http/header.go:66 +0x168
net/http.HandlerFunc.ServeHTTP(0x4005d6aed0?, {0x5927670?, 0x40018fee70?}, 0x4002947bd0?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/api/http/middleware.(*userAgentHandler).ServeHTTP(0x40028c39a0, {0x5927670, 0x40018fee70}, 0x4005faa500)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/user_agent_cookie.go:84 +0x1f4
github.com/zitadel/zitadel/internal/api/http/middleware.(*instanceInterceptor).Handler-fm.(*instanceInterceptor).Handler.(*instanceInterceptor).HandlerFunc.func1({0x5927670, 0x40018fee70}, 0x4005d62140)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/instance_interceptor.go:45 +0x330
net/http.HandlerFunc.ServeHTTP(0x140?, {0x5927670?, 0x40018fee70?}, 0x4000701508?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/api/http/middleware.(*cacheInterceptor).Handler-fm.(*cacheInterceptor).Handler.func1({0x592d5e0, 0x4005d4e640}, 0x4005d62140)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/cache_interceptor.go:76 +0xb4
net/http.HandlerFunc.ServeHTTP(0x592f050?, {0x592d5e0?, 0x4005d4e640?}, 0x58ce210?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP(0x40041ca2a0, {0x592ba20, 0x4005d4e600}, 0x4005d62000, {0x58dc380, 0x4004286e20})
/home/runner/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:218 +0xd58
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1({0x592ba20?, 0x4005d4e600?}, 0x4004231498?)
/home/runner/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:74 +0x40
net/http.HandlerFunc.ServeHTTP(0x592f050?, {0x592ba20?, 0x4005d4e600?}, 0x58ce210?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/internal/telemetry/metrics.(*Handler).ServeHTTP(0x4003c1ea80, {0x59279e0, 0x4005d54380}, 0x4005d03e00)
/home/runner/work/zitadel/zitadel/internal/telemetry/metrics/http_handler.go:93 +0x294
github.com/go-chi/chi/v5.(*Mux).ServeHTTP(0x4003181440, {0x59279e0, 0x4005d54380}, 0x4005d03cc0)
/home/runner/go/pkg/mod/github.com/go-chi/chi/[email protected]/mux.go:90 +0x280
github.com/zitadel/oidc/v3/pkg/op.RegisterServer.(*Cors).Handler.func1({0x59279e0, 0x4005d54380}, 0x4005d03cc0)
/home/runner/go/pkg/mod/github.com/rs/[email protected]/cors.go:289 +0x19c
net/http.HandlerFunc.ServeHTTP(0x4005d25a01?, {0x59279e0?, 0x4005d54380?}, 0x789adc9236d056c8?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/oidc/v3/pkg/op.(*webServer).ServeHTTP(0x10?, {0x59279e0?, 0x4005d54380?}, 0x4005987340?)
/home/runner/go/pkg/mod/github.com/zitadel/oidc/[email protected]/pkg/op/server_http.go:100 +0x30
github.com/zitadel/zitadel/internal/api/http/middleware.RobotsTagHandler.func1({0x59279e0, 0x4005d54380}, 0x4005d03cc0)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/robots_tag_interceptor.go:12 +0xec
net/http.HandlerFunc.ServeHTTP(0x4005d03b80?, {0x59279e0?, 0x4005d54380?}, 0x8?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/zitadel/zitadel/cmd/start.startAPIs.WithOrigin.func1.1({0x59279e0, 0x4005d54380}, 0x4005d03b80)
/home/runner/work/zitadel/zitadel/internal/api/http/middleware/origin_interceptor.go:23 +0x23c
net/http.HandlerFunc.ServeHTTP(0x4005d03a40?, {0x59279e0?, 0x4005d54380?}, 0x70000001010120?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2220 +0x38
github.com/gorilla/mux.(*Router).ServeHTTP(0x4003e92000, {0x59279e0, 0x4005d54380}, 0x4005c92500)
/home/runner/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:212 +0x194
golang.org/x/net/http2/h2c.h2cHandler.ServeHTTP({{0x58dc200?, 0x4003e92000?}, 0x40009aa2a0?}, {0x59279e0, 0x4005d54380}, 0x4005c92500)
/home/runner/go/pkg/mod/golang.org/x/[email protected]/http2/h2c/h2c.go:125 +0x4b0
net/http.serverHandler.ServeHTTP({0x591e910?}, {0x59279e0?, 0x4005d54380?}, 0x6?)
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:3210 +0xbc
net/http.(*conn).serve(0x4005a19170, {0x592f050, 0x4003f16540})
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:2092 +0x4fc
created by net/http.(*Server).Serve in goroutine 12568
/opt/hostedtoolcache/go/1.23.6/x64/src/net/http/server.go:3360 +0x3dc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment