Aller au contenu

Dynamic Client Registration

Ce contenu n’est pas encore disponible dans votre langue.

Dynamic client registration lets any service register its own OAuth 2.0 client at runtime — no server restart, no shared config file. This makes stubIdP suitable as a single, shared OIDC server for a team or a multi-service test environment.

stubIdP implements:

  • RFC 7591 — OAuth 2.0 Dynamic Client Registration Protocol (POST /register)
  • RFC 7592 — OAuth 2.0 Dynamic Client Registration Management Protocol (GET/PUT/DELETE /register/:id)
Terminal window
# Open registration — any caller may register a client
npx @cerberauth/stubidp --enable-registration
# Protected registration — callers must present a bearer token
npx @cerberauth/stubidp --enable-registration --registration-initial-access-token mysecret

The startup table will show the registration endpoint:

| Registration URL | http://localhost:8484/register |
  1. Send a registration request

    Terminal window
    curl -X POST http://localhost:8484/register \
    -H 'Content-Type: application/json' \
    -d '{
    "client_name": "my-service",
    "redirect_uris": ["http://localhost:3000/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"]
    }'

    If you started with --registration-initial-access-token mysecret, add:

    -H 'Authorization: Bearer mysecret'
  2. Save the response

    {
    "client_id": "abc123",
    "client_secret": "s3cr3t",
    "registration_access_token": "rat_xyz...",
    "registration_client_uri": "http://localhost:8484/register/abc123",
    "redirect_uris": ["http://localhost:3000/callback"],
    ...
    }

    Store client_id, client_secret, and registration_access_token — you will need them later.

  3. Configure your application

    Use the returned client_id and client_secret exactly as you would with a statically configured client. The issuer and discovery URL remain unchanged:

    SettingValue
    Issuerhttp://localhost:8484
    Discovery URLhttp://localhost:8484/.well-known/openid-configuration
    Client IDvalue from registration response
    Client Secretvalue from registration response

Use the registration_access_token from the registration response to read, update, or delete the client.

Terminal window
curl http://localhost:8484/register/<client_id> \
-H 'Authorization: Bearer <registration_access_token>'

PUT replaces the full client object — supply all fields, not just the ones that changed.

Terminal window
curl -X PUT http://localhost:8484/register/<client_id> \
-H 'Authorization: Bearer <registration_access_token>' \
-H 'Content-Type: application/json' \
-d '{
"client_id": "<client_id>",
"redirect_uris": ["http://localhost:3001/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}'
Terminal window
curl -X DELETE http://localhost:8484/register/<client_id> \
-H 'Authorization: Bearer <registration_access_token>'

Each service in your stack can register its own client at startup and tear it down afterward, with no coordination needed:

Terminal window
# service-a bootstrap
CLIENT=$(curl -sX POST http://stubidp:8484/register \
-H 'Content-Type: application/json' \
-d '{"redirect_uris":["http://service-a/cb"],"grant_types":["authorization_code"]}')
CLIENT_ID=$(echo $CLIENT | jq -r .client_id)
CLIENT_SECRET=$(echo $CLIENT | jq -r .client_secret)
RAT=$(echo $CLIENT | jq -r .registration_access_token)
# ... run tests ...
# cleanup
curl -sX DELETE http://stubidp:8484/register/$CLIENT_ID \
-H "Authorization: Bearer $RAT"