Skip to content

OIDC Clients

An OIDC client represents an application that authenticates users through Parako.ID. Each client has a unique client_id and, for confidential clients, a client_secret.

Parako.ID offers six client presets, each pre-configured with sensible OIDC defaults:

PresetAuth methodSecretPKCEUse case
Regular Web Applicationclient_secret_basicYesOptionalServer-rendered apps (Node.js, PHP, Ruby)
Single Page ApplicationnoneNoRequiredClient-side JavaScript (React, Vue, Angular)
Native / Mobile ApplicationnoneNoRequirediOS, Android, desktop apps
Machine-to-Machine (M2M)client_secret_basicYesNoBackend services, daemon processes
Device Flowclient_secret_postYesNoSmart TVs, CLIs, IoT (RFC 8628)
Management APIclient_secret_basicYesNoProgrammatic access to Parako.ID’s Management API

Each preset sets the application_type, grant_types, response_types, token_endpoint_auth_method, and scope to appropriate defaults. The preset is stored on the client record and is immutable after creation.

The fastest way to register a client is the interactive CLI:

Terminal window
yarn client add

The wizard prompts for:

  1. Client type
  2. Client name
  3. Redirect URIs (comma-separated)
  4. Allowed scopes

On success, it outputs the client_id and client_secret. Store the secret immediately — it is encrypted at rest and cannot be retrieved later.

Terminal window
yarn client list # List all registered clients
yarn client add # Add a new client (interactive)

The CLI is intentionally minimal. For inspecting, updating, removing, importing, or exporting clients, use the admin panel at /admin or the Management API. For a programmatic starting point, copy parako-rp.example.json (at the repo root) to parako-rp.jsonc and edit it directly.

Navigate to /admin and sign in with an admin or superadmin account. The OIDC Clients section provides a full web interface for client management.

  1. Click Add Client to open the creation form.
  2. Choose a preset — six cards are displayed, each with an icon, label, and short description:
    • Regular Web Application — server-side app with secure backend
    • Single Page Application — client-side JavaScript, public client with PKCE
    • Native / Mobile Application — iOS, Android, or desktop, public client with PKCE
    • Machine-to-Machine (M2M) — backend service using client credentials for your own resource servers
    • Device Flow — limited-input device, user authorizes on a separate screen (RFC 8628)
    • Management API — access the built-in Management API; select scopes after creation
  3. Fill in the quick-start fields: client name, description, redirect URIs, and post-logout redirect URIs.
  4. Optionally expand the OIDC Configuration section to customise grant types, response types, scopes, token endpoint auth method, PKCE enforcement, ID token signing algorithm, and subject type.
  5. Optionally expand Advanced Settings to set client_uri, logo_uri, policy_uri, tos_uri, contacts, tags, and default_max_age.
  6. For M2M clients, a resource indicators panel lets you define custom resource server URIs and their scopes.
  7. For Management API clients, a scope picker lists all parako:* Management API scopes grouped by domain (Clients, Users, Sessions, etc.).
  8. Click Create to save. The client secret is displayed once — copy it immediately.
  • Edit — all fields except client_id and preset can be modified.
  • Activate / Deactivate — toggle the active flag. Inactive clients are rejected at the token endpoint.
  • Regenerate Secret — issues a new secret and immediately invalidates the old one.
  • Delete — permanently removes the client after confirmation.

Clients defined in parako-rp.jsonc are loaded at startup and made available to the OIDC provider automatically. They are not shown in the admin panel — the admin panel only displays managed clients. To modify static clients, edit parako-rp.jsonc directly.

FieldTypeDescription
client_idstringUnique identifier (auto-generated or custom)
client_secretstringSecret for confidential clients (encrypted at rest)
client_namestringHuman-readable name
application_typestringweb, native, or spa (per OIDC spec + extension)
redirect_urisstring[]Allowed redirect URIs after authentication
post_logout_redirect_urisstring[]Allowed redirect URIs after logout
grant_typesstring[]Allowed grant types
response_typesstring[]Allowed response types
scopestringSpace-separated allowed scopes
token_endpoint_auth_methodstringHow the client authenticates at the token endpoint
require_pkcebooleanWhether PKCE is required
id_token_signed_response_algstringAlgorithm for signing ID tokens (default: RS256)
subject_typestringpublic or pairwise
allowedResourcesstring[]Resource server URIs this client can request tokens for (RFC 8707)
resourcesScopesstringSpace-separated scopes for resource server access
isInternalClientbooleanWhether this is a first-party/internal client for your organization

First-party apps: Set isInternalClient to true for your organization’s own applications (e.g., your main web app, internal tools). These first-party clients are trusted and skip the user consent screen — all requested scopes are granted automatically. Third-party clients (isInternalClient: false, the default) always require explicit user consent. This flag cannot be set via Dynamic Client Registration and is reserved for clients created through the admin panel or CLI.

Specifically, when isInternalClient is true:

  • Consent bypass — the consent screen is skipped entirely; all requested scopes are auto-granted.
  • Auto-grant — authorization grants are created automatically without user approval.
  • DCR blocked — this flag cannot be set via Dynamic Client Registration; it is reserved for admin-provisioned clients only.
FieldTypeDescription
descriptionstringFree-text description for admin reference
activebooleanWhether the client is active (default: true)
presetstringClient preset (web, spa, native, m2m, device, api_management) — immutable after creation
client_uristringURL of the client’s home page
logo_uristringURL of the client’s logo
policy_uristringURL of the client’s privacy policy
tos_uristringURL of the client’s terms of service
tagsstring[]Arbitrary tags for filtering and grouping
contactsstring[]Contact email addresses for the client owner
default_max_agenumberDefault maximum authentication age in seconds

The standard flow for web and mobile applications. The client redirects the user to Parako.ID’s authorization endpoint, receives an authorization code, and exchanges it for tokens.

PKCE (Proof Key for Code Exchange) is required by default for public clients and recommended for all clients (OAuth 2.1 standard).

Terminal window
# Grant types: authorization_code, refresh_token
# Response types: code

For machine-to-machine communication where no user is involved. The client authenticates directly with its client_id and client_secret.

Terminal window
curl -X POST https://your-parako.example.com/oidc/v1/token \
-u "CLIENT_ID:CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "scope=parako:clients:read" \
-d "resource=urn:parako:api:v1"

For devices with limited input capabilities (smart TVs, IoT). The device displays a user code, and the user authenticates on a separate device.

/oidc/v1/device/auth
# Grant type: urn:ietf:params:oauth:grant-type:device_code
# User code lifetime: 600 seconds

Confidential clients and native apps can request refresh tokens by including offline_access in the scope. Refresh tokens are rotated on each use by default.

Resource Indicators allow clients to specify which API (resource server) they are requesting a token for. This enables audience-restricted tokens — each access token is scoped to a single resource server.

Parako.ID ships with a built-in resource server at urn:parako:api:v1. Clients with the Management API preset have this resource pre-configured. Tokens issued for this resource are JWTs with aud: "urn:parako:api:v1".

Scopes follow the parako:<domain>:<action> taxonomy:

ScopeDescription
parako:clients:readView OIDC client applications and their configuration
parako:clients:writeCreate and update OIDC client applications
parako:clients:deletePermanently delete OIDC client applications
parako:users:readView user accounts, profiles, and activity logs
parako:users:writeCreate, update, lock/unlock users and reset passwords
parako:users:deleteAnonymize or permanently remove user accounts
parako:sessions:readView active OIDC sessions
parako:sessions:revokeRevoke individual or bulk OIDC sessions
parako:grants:readView authorization grants issued to clients
parako:grants:revokeRevoke authorization grants
parako:jwks:readView JSON Web Key Sets and key lifecycle state
parako:jwks:rotateTrigger key rotation, retire expired keys
parako:audit:readQuery the audit trail and activity log
parako:audit:writeCreate entries in the audit trail
parako:config:readView application configuration
parako:config:writeModify application configuration
parako:social:readView social login provider configurations
parako:social:writeConfigure social login providers
parako:stats:readView aggregate dashboard stats and system health
parako:webhooks:manageCreate, update, and delete webhook subscriptions
parako:registration-tokens:readView issued DCR initial access tokens
parako:registration-tokens:writeCreate DCR initial access tokens
parako:registration-tokens:deleteRevoke DCR initial access tokens

Scopes are classified by risk tier — read, write, or destructive — which drives recommended TTLs and audit severity.

M2M clients can target your own resource servers. Configure the allowedResources array with your resource URIs and set resourcesScopes to the space-separated scopes your resource server accepts. Tokens can be issued as jwt (with the resource URI as aud) or opaque depending on your resource server’s needs.

Parako.ID supports RFC 7591 Dynamic Client Registration when enabled in configuration:

{
"features": {
"oidc": {
"dynamic_client_registration": {
"enabled": true,
},
},
},
}

Security note: When DCR is enabled, require_initial_access_token is always enforced regardless of configuration. Open registration (without an initial access token) is never permitted to prevent unauthorized client creation.

Dynamic registration requires an initial access token. Generate one via the Management API using a client with the parako:registration-tokens:write scope (see Management API Scopes).

Terminal window
curl -X POST https://your-parako.example.com/oidc/v1/register-rp \
-H "Authorization: Bearer INITIAL_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_name": "Dynamic App",
"redirect_uris": ["https://app.example.com/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}'

Client management is also available programmatically through the REST Management API. All endpoints require a valid access token with the appropriate scope, issued for the urn:parako:api:v1 resource.

MethodEndpointScopeDescription
GET/api/v1/clientsparako:clients:readList all clients
POST/api/v1/clientsparako:clients:writeCreate a new client
GET/api/v1/clients/:client_idparako:clients:readGet a single client
PUT/api/v1/clients/:client_idparako:clients:writeFull update
PATCH/api/v1/clients/:client_idparako:clients:writePartial update
DELETE/api/v1/clients/:client_idparako:clients:deleteDelete a client
POST/api/v1/clients/:client_id/activateparako:clients:writeActivate a client
POST/api/v1/clients/:client_id/deactivateparako:clients:writeDeactivate a client
POST/api/v1/clients/:client_id/secretparako:clients:deleteRegenerate secret
GET/api/v1/clients/:client_id/statsparako:clients:readClient usage stats
MethodEndpointScopeDescription
GET/api/v1/registration-tokensparako:registration-tokens:readList active IATs
POST/api/v1/registration-tokensparako:registration-tokens:writeCreate a new IAT
GET/api/v1/registration-tokens/:jtiparako:registration-tokens:readGet a single IAT
DELETE/api/v1/registration-tokens/:jtiparako:registration-tokens:deleteRevoke an IAT

Client secrets are encrypted at rest using the ENCRYPTION_KEY from your .env file.

To rotate a client’s secret:

Terminal window
# Via Management API
curl -X POST https://your-parako.example.com/api/v1/clients/CLIENT_ID/secret \
-H "Authorization: Bearer API_TOKEN"

You can also rotate the secret from the admin panel at /admin → OIDC Clients → select the client → Rotate Secret.

The old secret is immediately invalidated. Update your application with the new secret before the next token request.

Token lifetimes are configurable per token type:

TokenDefault TTLDescription
Access token3,600s (1 hour)Short-lived token for API access
ID token3,600s (1 hour)Identity assertion
Refresh token86,400s (24 hours)Long-lived token for obtaining new access tokens
Authorization code600s (10 min)One-time use, exchanged for tokens
Device code600s (10 min)User code for device flow
Client credentials3,600s (1 hour)Machine-to-machine token
Grant3,600s (1 hour)User authorization grant
Session86,400s (24 hours)Browser session
Backchannel auth600s (10 min)CIBA backchannel authentication request
Interaction600s (10 min)OIDC login/consent interaction

Configure TTLs in the oidc.token_ttl section of your configuration file or via the admin panel.