ZITADEL v4.19.5 API 使用详解
ZITADEL v4.19.5 API 使用详解:curl 逐条实测 OIDC 发现/JWKS、Session API(v4.19 需调用者凭证)、机器用户三种凭证全流程(Client Credentials/PAT/JWT Profile)、userinfo 与 introspection 受众机制、v2 资源 API 与 v1 管理/Admin API、六类错误回显特征库与端点速查表,JSON 回显逐字照抄自 2026-10-18 实测。
ZITADEL v4.19.5 API 使用详解
目标:用 curl 把 ZITADEL v4.19.5 的对外 API 完整跑通一遍——OIDC 发现端点、Session API 会话认证、机器用户三种凭证(Client Credentials / PAT / JWT Profile)换取 token、userinfo 与 introspection、v2 资源 API 与 v1 管理/Admin API,全部回显逐字来自 2026-10-18 在本地实例上的实测。实例的部署与配置见《ZITADEL Docker Compose 部署指南》《ZITADEL v4.19.5 配置参数详解》,平台定位见《ZITADEL v4.19.5 介绍与选型指南》。
一、环境信息
| 项目 | 值 |
|---|---|
| 服务器(容器模拟真实服务器) | IP 192.168.146.128,主机名 ops,网卡 ens33(出口路由验证 ip route get 192.168.1.62 → via 192.168.146.2 dev ens33) |
| 操作系统 | Ubuntu 22.04.4 LTS(内核 6.8.0-138-generic) |
| ZITADEL 实例 | v4.19.5(compose 栈,issuer http://localhost:8113,API 基址 http://localhost:8113) |
| 请求工具 | curl 8.9.x(系统自带) |
| 初始管理员 | admin / q1w2e3r4(登录名 admin@zitadel.localhost,user id 395667685880964611) |
| 实测用机器账号 | svc-cicd(user id 395667878902244867,Access Token Type BEARER) |
| 实测项目/应用 | demo-project(id 395668063753610755)、OIDC 应用 demo-rs(clientId 395668074642023939) |
| 组织 | ZITADEL(id 395667685880440323,primaryDomain zitadel.localhost) |
| 敏感值处理 | access_token / sessionToken / PAT 均为 JWT 形态,文中一律截断显示;密钥类仅实验值 |
实测约定:所有请求基于 issuer http://localhost:8113;HTTP 状态码与 JSON 回显逐字照抄;长响应(token 正文、长列表)在标注处截断节选。
二、API 版图与认证方式总览
2.1 四族端点
| 端点族 | REST 前缀 | 认证凭证 | 本文覆盖章节 |
|---|---|---|---|
| OIDC/OAuth 标准 | /oauth/v2/*、/oidc/v1/* | 各 grant 的 access_token / 应用凭据 | 三、五 |
| v2 资源 API(推荐) | /v2/* | Bearer token(PAT / 会话 / access_token) | 四、五~八 |
| v1 管理 API(维护态) | /management/v1/*、/admin/v1/*、/auth/v1/* | Bearer token | 六、八 |
| System API | /system/v1/* | system token(多实例运营) | 未实测(单实例环境无 system 凭证) |
每个 gRPC 服务同时暴露 REST 映射(grpc-gateway),本文全部走 REST。API 目录总入口:https://zitadel.com/docs/apis/introduction。
2.2 三种机器凭证怎么选(实测结论先行)
| 凭证 | 获取方式 | 调 API 形态 | 实测要点 |
|---|---|---|---|
| Client Credentials | 机器用户 + client secret → token 端点换 access_token | Authorization: Bearer <access_token> | 短时 token(默认 12h),最标准 |
| PAT | 机器用户 → 直接签发长期 token | Authorization: Bearer <PAT> | 免换发但权限跟随用户且调用管理 API 仍需 membership(第六章 404 实录) |
| JWT Profile | 机器用户 + JSON key → 本地签 JWT 换 access_token | Authorization: Bearer <access_token> | 私钥不出机,适合 CI/CD |
三、OIDC 发现与健康端点
3.1 发现文档(.well-known)
curl -s http://localhost:8113/.well-known/openid-configuration | python3 -m json.tool
实测回显(节选,全文较长;端点路径逐字照抄):
{
"issuer": "http://localhost:8113",
"authorization_endpoint": "http://localhost:8113/oauth/v2/authorize",
"token_endpoint": "http://localhost:8113/oauth/v2/token",
"introspection_endpoint": "http://localhost:8113/oauth/v2/introspect",
"userinfo_endpoint": "http://localhost:8113/oidc/v1/userinfo",
"revocation_endpoint": "http://localhost:8113/oauth/v2/revoke",
"end_session_endpoint": "http://localhost:8113/oidc/v1/end_session",
"device_authorization_endpoint": "http://localhost:8113/oauth/v2/device_authorization",
"jwks_uri": "http://localhost:8113/oauth/v2/keys",
...
}
注意 ZITADEL 的路径前缀分裂:
/oauth/v2/*与/oidc/v1/*并存(token 在 oauth、userinfo 在 oidc),对接第三方 SDK 时以发现文档为准,不要手拼。
3.2 JWKS 与健康
curl -s http://localhost:8113/oauth/v2/keys | head -c 200; echo
curl -s http://localhost:8113/debug/healthz -w " HTTP %{http_code}\n"
实测回显(jwks 节选):
{"keys":[{"use":"sig","kty":"RSA","kid":"395667686987933187","alg":"RS256",...}]}
ok HTTP 200
四、Session API:会话认证(CreateSession)
Session API(/v2/sessions)是自建登录 UI 的核心:一次调用内完成「用户名 + 密码」两级校验,产出可反查的会话。
4.1 无凭证调用(复现 auth header missing)
curl -s -X POST http://localhost:8113/v2/sessions \
-H 'Content-Type: application/json' \
-d '{"checks":{"user":{"loginName":"admin@zitadel.localhost"},"password":{"password":"q1w2e3r4"}}}' \
-w "\nHTTP %{http_code}\n"
实测回显:
{"code": 16, "message": "auth header missing"}
HTTP 401
这是 v4.19 的关键变更:CreateSession 也要求调用者先有身份(gRPC 权限 authenticated)。官方提供的调用者身份就是部署时自动生成的 login-client PAT(落盘于 bootstrap 卷):
docker cp zitadel-v4-19-5-api:/zitadel/bootstrap/login-client.pat - | tar -xO # 取出 PAT(JWT 形态)
(该 PAT 长度实测 277 字符,eyJ 开头;本篇以 <LOGIN_CLIENT_PAT> 代称。)
4.2 带 login-client PAT 创建会话
curl -s -X POST http://localhost:8113/v2/sessions \
-H "Authorization: Bearer <LOGIN_CLIENT_PAT>" \
-H 'Content-Type: application/json' \
-d '{"checks":{"user":{"loginName":"admin@zitadel.localhost"},"password":{"password":"q1w2e3r4"}}}' \
-w "\nHTTP %{http_code}\n"
实测回显(sessionToken 为加密 JWE,敏感值截断):
{"details":{"sequence":"4", "changeDate":"2026-10-18T14:43:43.549768Z", "resourceOwner":"395667685880374787"}, "sessionId":"395671551736817155", "sessionToken":"eyJhbGciOiJBMjU2R0NNS1ci...(截断)"}
HTTP 201
4.3 会话反查(sessionToken 走 x-session-token 头)
curl -s http://localhost:8113/v2/sessions/395671551736817155 \
-H "Authorization: Bearer <LOGIN_CLIENT_PAT>" \
-H "x-session-token: <sessionToken>" | python3 -m json.tool
实测回显(节选 factors):
{
"session": {
"id": "395671551736817155",
"factors": {
"user": {
"verifiedAt": "2026-10-18T14:43:42.904902Z",
"id": "395667685880964611",
"loginName": "admin@zitadel.localhost",
"displayName": "ZITADEL Admin",
"organizationId": "395667685880440323"
},
"password": {
"verifiedAt": "2026-10-18T14:43:43.548891Z"
}
},
...
}
}
factors.user + factors.password 双 verifiedAt 即「用户存在 + 密码正确」的机器可读证明。要点:sessionToken 走 x-session-token 请求头(不是 Authorization);它本身还能当短期 Bearer 调 /auth/v1/* 自助端点(实测可用),但正式集成应使用第五~七章的机器凭证。
五、机器用户之 Client Credentials(token / userinfo / introspect)
5.1 创建机器用户并签发 secret
curl -s -X POST http://localhost:8113/v2/users/new \
-H "Authorization: Bearer <admin会话token或PAT>" \
-H 'Content-Type: application/json' \
-d '{"organizationId":"395667685880440323","username":"svc-cicd","machine":{"name":"CI/CD service account","accessTokenType":"ACCESS_TOKEN_TYPE_BEARER"}}'
实测回显:
{"id":"395667878902244867", "creationDate":"2026-10-18T14:07:13.718383Z"}
HTTP 200
给机器用户加 client secret:
curl -s -X POST http://localhost:8113/v2/users/395667878902244867/secret \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' -d '{}'
实测回显:
{"creationDate":"2026-10-18T14:07:19.301717Z", "clientSecret":"Oepy8tuM5Nt6K1k78umuyRx5U7B4u3h7SuTZAT5L7hazhg9caUr5Go526nqOtp4s"}
HTTP 200
(secret 只在响应出现一次,立即保存。)
5.2 换取 access_token(Basic 认证)
curl -s -u 'svc-cicd:Oepy8tuM5Nt6K1k78umuyRx5U7B4u3h7SuTZAT5L7hazhg9caUr5Go526nqOtp4s' \
-X POST http://localhost:8113/oauth/v2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&scope=openid urn:zitadel:iam:org:project:id:zitadel:aud' \
-w "\nHTTP %{http_code}\n"
实测回显(token 正文截断,字段为响应全集):
{"access_token":"eyJhbGciOiJBMjU2R0NNS1ci...(截断)","token_type":"Bearer","expires_in":43199,"id_token":"eyJhbGciOiJSUzI1NiIs...(截断)"}
HTTP 200
三个实测要点:
- client_id 用「用户名」:
svc-cicd直接过;用数字 user id 则失败(实测原文):
{"error":"invalid_client","error_description":"client not found"}
HTTP 400
(ZITADEL 特有约定,与一般 OIDC 的 client_id=UUID 习惯不同);
2. expires_in: 43199 ≈ 12h,与 defaults.yaml 的 OIDC.DefaultAccessTokenLifetime: 12h 一致(见《ZITADEL v4.19.5 配置参数详解》7.3);
3. scope urn:zitadel:iam:org:project:id:zitadel:aud 把 ZITADEL 内置项目设为受众。
5.3 userinfo
curl -s http://localhost:8113/oidc/v1/userinfo \
-H "Authorization: Bearer <access_token>" -w "\nHTTP %{http_code}\n"
实测回显(机器用户无 profile scope,仅 sub):
{"sub":"395667878902244867"}
HTTP 200
5.4 introspection 与受众坑(两次实测)
内省(资源服务器校验 token 的标准方式)需要另一个 OIDC 应用的 Basic 凭据做 HTTP Basic。先建项目与应用:
curl -s -X POST http://localhost:8113/management/v1/projects \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' \
-d '{"name":"demo-project","projectRoleAssertion":false}'
实测回显:
{"id":"395668063753610755", "details":{"sequence":"3", "creationDate":"2026-10-18T14:09:03.894234Z", "resourceOwner":"395667685880440323"}}
HTTP 200
curl -s -X POST http://localhost:8113/management/v1/projects/395668063753610755/apps/oidc \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' \
-d '{"name":"demo-rs","redirectUris":[],"responseTypes":["OIDC_RESPONSE_TYPE_CODE"],"grantTypes":["OIDC_GRANT_TYPE_CLIENT_CREDENTIALS"],"appType":"OIDC_APP_TYPE_WEB","authMethodType":"OIDC_AUTH_METHOD_TYPE_BASIC","postLogoutRedirectUris":[],"version":"OIDC_VERSION_1_0"}'
实测回显(节选;合规警告为无 redirect_uri 所致,属预期):
{"appId":"395668074625246723", "details":{"sequence":"4", "creationDate":"2026-10-18T14:09:10.383186Z", "resourceOwner":"395667685880440323"}, "clientId":"395668074642023939", "clientSecret":"LF2GTivBd9NCrVhnmKmqIQLFeDSBMMnsN15IWrg2y0oqrfESJRPkcjSILeADWg4m", "noneCompliant":true, "complianceProblems":[...]}
第一次内省(token 受众是 zitadel 项目,被内省的是 demo-project 应用):
curl -s -u '395668074642023939:LF2GTivBd9NCrVhnmKmqIQLFeDSBMMnsN15IWrg2y0oqrfESJRPkcjSILeADWg4m' \
-X POST http://localhost:8113/oauth/v2/introspect -d "token=< zitadel受众的access_token >" -w "\nHTTP %{http_code}\n"
实测回显:
{"active":false}
HTTP 200
active:false(HTTP 仍 200,符合 RFC 7662)——受众不匹配。重新以 demo-project 为受众取 token(scope 改为 urn:zitadel:iam:org:project:id:395668063753610755:aud),再内省:
curl -s -u 'svc-cicd:<clientSecret>' -X POST http://localhost:8113/oauth/v2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&scope=openid urn:zitadel:iam:org:project:id:395668063753610755:aud' -o /dev/null
curl -s -u '395668074642023939:LF2GTivBd9NCrVhnmKmqIQLFeDSBMMnsN15IWrg2y0oqrfESJRPkcjSILeADWg4m' \
-X POST http://localhost:8113/oauth/v2/introspect -d "token=< demo受众的access_token >" | python3 -m json.tool
实测回显(全文):
{
"active": true,
"scope": "openid urn:zitadel:iam:org:project:id:395668063753610755:aud",
"client_id": "svc-cicd",
"token_type": "Bearer",
"exp": 1792375780,
"iat": 1792332580,
"auth_time": 1792332580,
"nbf": 1792332580,
"sub": "395667878902244867",
"aud": ["395668063753610755"],
"amr": ["pwd"],
"iss": "http://localhost:8113",
"jti": "V2_395668125493765635-at_395668125493831171"
}
结论(本篇最重要的坑):ZITADEL 的 introspection 是「资源服务器视角」——校验方必须是 token 受众项目内的 OIDC 应用;受众不含校验方 → active:false。排查口诀:先看 scope 里的 ...:id:<project-id>:aud 指向谁。
六、机器用户之 PAT(长期令牌)
6.1 签发 PAT
curl -s -X POST http://localhost:8113/v2/users/395667878902244867/pats \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' \
-d '{"expirationDate":"2099-01-01T00:00:00Z"}' -w "\nHTTP %{http_code}\n"
实测回显(token 正文截断):
{"creationDate":"2026-10-18T14:09:46.900749Z", "tokenId":"395668135895639555", "token":"eyJhbGciOiJBMjU2R0NNS1ci...(截断)"}
HTTP 200
PAT 是 JWT 形态的长期令牌,无需再换发,直接作 Bearer。
6.2 PAT 调 v1 自助与管理 API 的权限差异(两次实测)
调 /auth/v1/users/me(当前用户自助,任何已认证用户可查自己):
curl -s http://localhost:8113/auth/v1/users/me -H "Authorization: Bearer <PAT>"
实测回显(全文):
{"user":{"id":"395667878902244867", "details":{"sequence":"2", "creationDate":"2026-10-18T14:07:13.718383Z", "changeDate":"2026-10-18T14:07:19.301717Z", "resourceOwner":"395667685880440323"}, "state":"USER_STATE_ACTIVE", "userName":"svc-cicd", "loginNames":["svc-cicd"], "preferredLoginName":"svc-cicd", "machine":{"name":"CI/CD service account", "hasSecret":true}}}
调 /management/v1/orgs/me(管理类,需要组织角色):
{"code":5, "message":"membership not found (AUTHZ-cdgFk)", "details":[{"@type":"type.googleapis.com/zitadel.v1.ErrorDetail", "id":"AUTHZ-cdgFk", "message":"membership not found"}]}
HTTP 404
实测结论:PAT 解决「我是谁」(认证),不自带「我能管」(授权)——管理 API 需要 User Grant/membership。给机器用户授组织角色(Console 的 User Grants 或 User Grant API)后即可通过。
七、机器用户之 JWT Profile(私钥签发)
7.1 创建 JSON key
curl -s -X POST http://localhost:8113/v2/users/395667878902244867/keys \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' \
-d '{"type":"KEY_TYPE_JSON","expirationDate":"2099-01-01T00:00:00Z"}' -w "\nHTTP %{http_code}\n"
实测回显(结构展示,keyContent 为 base64 的服务账号 JSON,截断):
{"id":"395668213370648578","keyContent":"eyJ0eXBlIjoic2VydmljZWFjY291bnQiLiwia2V5SWQiOiIzOTU2NjgyMTMzNzA2NDg1NzgiLiwia2V5IjoiLS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLVxu...(截断)"}
HTTP 200
base64 解码后的服务账号 JSON(字段与 GCP SA 同构):
{
"type": "serviceaccount",
"keyId": "395668213370648578",
"key": "-----BEGIN RSA PRIVATE KEY-----\n...(截断)\n-----END RSA PRIVATE KEY-----\n",
"userId": "395667878902244867"
}
7.2 本地签 JWT 并换 access_token
JWT Profile 流程:本地用私钥签一个 RS256 JWT(claims:iss/sub=user id、iat/exp、aud=issuer),POST 到 token 端点换正式 token。签名可用 openssl 完成而不依赖任何 SDK:
# header.payload(未编码示意,实际需 base64url)
{"alg":"RS256","kid":"395668213370648578"}
{"iss":"395667878902244867","sub":"395667878902244867","iat":<now>,"exp":<now+3600>,"aud":"http://localhost:8113"}
openssl dgst -sha256 -sign svc_key.pem signing.bin | base64 -w0 | tr '+/' '-_' | tr -d '=' # 签名
(构造脚本与签名过程见配套实验记录;svc_key.pem 即 7.1 私钥。)换取 token:
curl -s -X POST http://localhost:8113/oauth/v2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "assertion=<签好的JWT>" \
-d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=openid urn:zitadel:iam:org:project:id:zitadel:aud' \
-w "\nHTTP %{http_code}\n"
实测回显(token 正文截断,字段结构同 5.2):
{"access_token":"eyJhbGciOiJBMjU2R0NNS1ci...(截断)","token_type":"Bearer","expires_in":43199,"id_token":"eyJhbGciOiJSUzI1NiIs...(截断)"}
HTTP 200
三种机器凭证到此全部跑通。JWT Profile 的优势:私钥不出本机(PAT/secret 是共享密钥形态)、可按 key 粒度吊销与轮换,CI/CD 场景首选。
八、v1 管理 API 与 Admin API 实测
8.1 组织信息(management)
curl -s http://localhost:8113/management/v1/orgs/me -H "Authorization: Bearer <admin凭证>"
实测回显(全文):
{"org":{"id":"395667685880440323", "details":{"sequence":"5", "creationDate":"2026-10-18T14:05:19.401153Z", "changeDate":"2026-10-18T14:05:19.401153Z", "resourceOwner":"395667685880440323"}, "state":"ORG_STATE_ACTIVE", "name":"ZITADEL", "primaryDomain":"zitadel.localhost"}}
8.2 实例与域名(admin)
curl -s http://localhost:8113/admin/v1/instances/me -H "Authorization: Bearer <admin凭证>"
实测回显(节选,domains 数组完整保留前两项):
{"instance":{"id":"395667685880374787", "details":{"sequence":"30", "creationDate":"2026-10-18T14:05:19.401153Z", "changeDate":"2026-10-18T14:05:19.401153Z", "resourceOwner":"395667685880374787"}, "state":"STATE_RUNNING", "name":"ZITADEL", "version":"v4.19.5", "domains":[
{"details":{...}, "domain":"zitadel-x7o4aa.localhost", "generated":true},
...
]}}
要点:实例版本号(v4.19.5)直接可查;generated:true 的域名是初始化随机生成的实例域名(zitadel-x7o4aa.localhost),主域名 localhost 由 .env 的 ZITADEL_DOMAIN 注册(primary 标记,对照查询如下)。
curl -s -X POST http://localhost:8113/admin/v1/domains/_search \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' -d '{}'
实测回显(全文):
{"details":{"totalResult":"2", "viewTimestamp":"2026-10-18T14:12:57.728129Z"}, "result":[{"details":{...}, "domain":"zitadel-x7o4aa.localhost", "generated":true}, {"details":{...}, "domain":"localhost", "primary":true}]}
8.3 用户搜索(v2 ListUsers)
curl -s -X POST http://localhost:8113/v2/users \
-H "Authorization: Bearer <admin凭证>" -H 'Content-Type: application/json' \
-d '{"queries":[{"typeQuery":{"type":"TYPE_MACHINE"}}],"sortingColumn":"USER_FIELD_NAME_USER_NAME"}'
实测回显(节选,第二条用户记录截断):
{"details":{"totalResult":"2", "timestamp":"2026-10-18T14:07:19.301717Z"}, "result":[
{"userId":"395667878902244867", "details":{...}, "state":"USER_STATE_ACTIVE", "username":"svc-cicd", "loginNames":["svc-cicd"], "preferredLoginName":"svc-cicd", "machine":{"name":"CI/CD service account", "hasSecret":true}},
{...截断...}
]}
注意 v2 搜索端点的形态:
POST /v2/users(POST 即查询,条件在 body);同类还有POST /admin/v1/domains/_search的_search后缀约定。GET 幂等语义在 ZITADEL v2 API 里是「POST 查询、GET 单取」的组合。
九、错误响应与排障速查
本章回显均为故意构造的错误请求实测原文,可直接当排障特征库用。
9.1 401 两连
无凭证(错误码 16 = gRPC unauthenticated):
{"code": 16, "message": "auth header missing"}
HTTP 401
凭证无效(伪造 token,错误详情含定位码):
{"code":16, "message":"Errors.Token.Invalid (AUTH-7fs1e)", "details":[{"@type":"type.googleapis.com/zitadel.v1.ErrorDetail", "id":"AUTH-7fs1e", "message":"Errors.Token.Invalid"}]}
HTTP 401
9.2 授权类
PAT 会计有效但无管理角色(HTTP 状态是 404 而非 403,容易误判为路径错误):
{"code":5, "message":"membership not found (AUTHZ-cdgFk)", ...}
HTTP 404
9.3 OAuth 端点
内省用错了凭据类型(用机器用户的 user:secret 当 Basic 去调 /oauth/v2/introspect——它不是 OIDC 应用):
{"error":"unauthorized_client"}
HTTP 400
(对照 5.4 的正确用法:Basic 里必须是资源服务器侧 OIDC 应用的 clientId:clientSecret。)
9.4 排障决策表
| 现象 | 根因 | 处置 |
|---|---|---|
401 auth header missing | 请求无 Authorization 头 | 补 Bearer(v4.19 连 CreateSession 都要求) |
401 Errors.Token.Invalid | token 过期/伪造/实例不匹配 | 重取 token;核对 issuer |
404 membership not found | 认证通过但无目标资源的管理角色 | 授 User Grant/membership |
200 {"active":false} | 内省方不在 token 受众项目内 | 调整 scope 的 :aud 或用正确应用内省 |
400 unauthorized_client | introspect/token 的 Basic 凭据类型错误 | 用 OIDC 应用凭据,非机器用户 secret |
404 Instance not found | Host 头与实例注册域名不符 | 核对 ExternalDomain(见配置篇 4.3) |
十、curl 模板与要点速查
10.1 五个可直接复用的模板
# 1) client_credentials 取 token(client_id=用户名)
curl -s -u 'svc-cicd:<secret>' -X POST http://localhost:8113/oauth/v2/token \
-d 'grant_type=client_credentials&scope=openid urn:zitadel:iam:org:project:id:<project-id>:aud'
# 2) JWT Profile 取 token(先本地签 assertion)
curl -s -X POST http://localhost:8113/oauth/v2/token \
--data-urlencode "assertion=<JWT>" \
-d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=openid'
# 3) userinfo
curl -s http://localhost:8113/oidc/v1/userinfo -H "Authorization: Bearer <token>"
# 4) 资源服务器内省(Basic=OIDC 应用凭据)
curl -s -u '<clientId>:<clientSecret>' -X POST http://localhost:8113/oauth/v2/introspect -d "token=<token>"
# 5) 建会话(v4.19 需先有调用者身份)
curl -s -X POST http://localhost:8113/v2/sessions \
-H "Authorization: Bearer <调用者PAT>" -H 'Content-Type: application/json' \
-d '{"checks":{"user":{"loginName":"<loginName>"},"password":{"password":"<pwd>"}}}'
10.2 端点速查表(本篇全部实测项)
| 端点 | 方法 | 认证 | 实测结果 |
|---|---|---|---|
/.well-known/openid-configuration | GET | 无 | 发现文档(三、) |
/oauth/v2/keys | GET | 无 | JWKS(三、) |
/debug/healthz | GET | 无 | ok(三、) |
/v2/sessions | POST | login-client PAT | HTTP 201(四、) |
/v2/sessions/{id} | GET | PAT + x-session-token | factors 反查(四、) |
/v2/users/new | POST | admin 凭证 | 机器用户(五、) |
/v2/users/{id}/secret | POST | admin 凭证 | clientSecret(五、) |
/oauth/v2/token | POST | Basic / assertion | 两种 grant(五、七、) |
/oidc/v1/userinfo | GET | Bearer | sub(五、) |
/oauth/v2/introspect | POST | OIDC 应用 Basic | active 判定(五、) |
/v2/users/{id}/pats | POST | admin 凭证 | PAT 签发(六、) |
/auth/v1/users/me | GET | PAT / sessionToken | 自助信息(六、) |
/v2/users/{id}/keys | POST | admin 凭证 | JSON key(七、) |
/management/v1/orgs/me | GET | admin 凭证 / PAT | 组织信息 / 404 membership(六、八、) |
/management/v1/projects | POST | admin 凭证 | 建项目(五、) |
/management/v1/projects/{id}/apps/oidc | POST | admin 凭证 | 建 OIDC 应用(五、) |
/v2/users | POST | admin 凭证 | 机器用户列表(八、) |
/admin/v1/instances/me | GET | admin 凭证 | 实例详情(八、) |
/admin/v1/domains/_search | POST | admin 凭证 | 域名列表(八、) |
三条要点收束全篇:
- 认证先行:v4.19 所有写操作(含建会话)都需要调用者身份,PAT 是最快的「系统内身份」载体;
- 受众即授权边界:token 只对 scope
:aud指向的项目资源有效,introspection 与 API 调用都受它约束; - v1/v2 并存以 v2 优先:
/v2/*是官方推荐资源 API,/management/admin/auth v1处于维护态,新集成按 v2 设计(POST查询风格)。
参考链接
- API 概览(四族端点与域名路由):https://zitadel.com/docs/apis/introduction
- Session API v2:https://zitadel.com/docs/apis/resources/session_service_v2/session-service-v2-create-session
- User API v2(机器用户/secret/PAT/keys):https://zitadel.com/docs/apis/resources/user_service_v2/user-service-v2-add-machine-user
- OIDC 端点行为(token/introspect/userinfo):https://zitadel.com/docs/guides/integrate/recommended-setup#use-our-apis
- 机器用户指南(JWT Profile 示例):https://zitadel.com/docs/guides/integrate/service-users
- 本系列配套篇:《ZITADEL v4.19.5 介绍与选型指南》《ZITADEL Docker Compose 部署指南》《ZITADEL v4.19.5 配置参数详解》