mikakimikaki.org

Connect a Web application with mikaki OpenID Connect

To try the public IdP in your browser, open the public integration demo. This guide is for developers connecting a Web application whose backend holds a private signing key. It covers registration, login, code exchange and application session creation. For user sign-in instructions, read Getting started.

Connect using OpenID Connect#

mikaki acts as an OpenID Connect Provider (OP). Applications act as Relying Parties (RPs), using the Authorization Code flow with PKCE S256.

Discover endpoints and the signing key URL from:

https://auth.mikaki.org/.well-known/openid-configuration

The normal integration uses the openid scope and ES256 private_key_jwt client authentication. An administrator registers clients in advance.

What to register#

Use a separate client for each environment. Provide the operator with the application name, hostname, exact HTTPS callback URLs and an ES256 public JWK with its key ID. Keep the private key in your backend; do not send it to mikaki. Public dynamic client registration is unavailable.

Native public clients have separate registration, authentication and callback rules.

Before requesting registration, use application integration requests to prepare the needed information and review steps.

1. Start login#

Generate fresh random state, nonce and a PKCE code_verifier for each login. Store them in the backend with the start time and browser transaction. Restrict the post-login return path to a validated application-local destination.

Send these URL-encoded parameters to the discovered authorization_endpoint:

ParameterValue
client_idRegistered client ID
redirect_uriExact registered callback URL
response_type / scopecode / openid
state / nonceValues generated for this login
code_challengeSHA-256 of the verifier, encoded as base64url without trailing =
code_challenge_methodS256

mikaki handles passkey authentication and connection approval. Your application does not receive the passkey or mikaki's SSO cookie.

2. Exchange the code on callback#

Match state to the stored transaction and check that the response's iss exactly equals https://auth.mikaki.org. Reject errors, expired transactions and previously handled callbacks. Keep authorization codes out of access logs.

From the backend, POST application/x-www-form-urlencoded to the discovered token_endpoint. Include grant_type=authorization_code, the returned code, registered redirect_uri, stored code_verifier, client_id, client_assertion and client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

The client assertion is an ES256 JWT signed with the registered private key. Its header's kid identifies the registered public key. Set iss and sub to the client ID and aud to the exact discovered token endpoint URL. Use a fresh jti for every request, with iat and exp within the operator's lifetime policy. After a lost response, restart login rather than replaying the code or assertion.

Verify the ID Token using JWKS and allowed signing algorithms. Check issuer, audience, expiry, issued-at time, the sent nonce and required auth_time. Map the issuer and sub pair to an application-local user. The subject is neither an email address nor mikaki's common account ID.

The Access Token is for UserInfo; it is not authorization for your application's API or proof of an active session. If fetching UserInfo, match its sub to the verified ID Token.

3. Create an application session#

Before issuing a cookie, managed RPs call POST https://auth.mikaki.org/session/check from their backend. This is a mikaki-specific extension. Send JSON containing client_id, client_assertion_type, a new client_assertion and the ID Token's sid.

Assertion purposeURL used as aud
Code exchangeDiscovered token_endpoint
Session checkhttps://auth.mikaki.org/session/check

Create a new JWT and jti for the session check. A token-exchange assertion cannot be reused. For active=true, match sub and auth_time to the ID Token. Measure lease_ttl from the start of the check and cap its deadline at parent SSO expires_at. Use the returned values rather than assuming a fixed check interval.

Limit the application session to the earlier of the idle deadline determined by app_idle_timeout and parent SSO expiry. A delayed active response must never restore a revoked session.

Issue an application-host-only cookie with Secure, HttpOnly and SameSite=Lax. Do not share its Domain with mikaki. Recheck protected requests after the lease expires. An OP outage cannot extend the lease, and a failed initial check cannot create a new session.

Connect logout#

Register post-logout return URLs and Back-Channel Logout receivers separately. Validate signed logout notifications and revoke the corresponding application sessions. Verify that protected operations stop at the session-check deadline even if a notification never arrives.

When integration fails#

  1. Check that issuer, client ID and callback URL belong to the same registered environment. Paths, trailing slashes and query strings matter.
  2. Check that the callback belongs to the same browser's unprocessed transaction. Do not use fixed state or nonce values to make a test pass.
  3. For code exchange, check the stored PKCE value, key kid, assertion aud, clock and lifetime. Keep private keys, codes and tokens out of diagnostic logs and public issues.
  4. For session checks, use a fresh assertion and a sid issued to the same client. Treat active=false as failure and restart login.

Current integration scope#

The normal production scope is openid. Name release has separate consent, operational settings and qualification requirements; ordinary login does not provide the Vault name or note. Do not assume support for the email scope, dynamic registration or general FAPI integration.

Registration alone does not establish interoperability. Test code exchange, invalid state/nonce/PKCE/signatures, replay, revocation, logout and OP outage from the actual application. Implementation status distinguishes local test evidence from certification.

For the standard flow, see OpenID Connect Core and the PKCE specification. mikaki-specific details are in the RP integration guide, client registration instructions and session-check contract.