Pricing Install

Sign in with someones.computer

This platform is an OpenID Connect (OIDC) identity provider. Your site sends a person here to sign in, and gets back a signed token that says who they are. They never make an account with you, and you never hold a password.

This is the one page here that isn't about the /cli contract. It needs no API token. An identity-provider client is a separate credential, and the flow runs in the person's browser rather than on your server.

What you get

Claim Always What you get
sub Yes The account's permanent identifier, 128 bits. Key your own records on this
email Yes The address the account signs in with
email_verified Yes Whether the account has opened a confirmation link here. Read it. It reports the account's real state, not a constant
nonce When you send one Exactly what you sent

sub never changes, and this platform never reuses one. An address can change. Match on sub.

An ordinary client learns nothing else. It doesn't learn whether the person administers this platform, or which organizations they belong to. Those claims exist, and they're for relying parties this platform runs itself. See the provider notes in the main repo.

Getting a client

There is no dynamic registration. Ask an operator to register you at /admin/oidc-clients, and give them:

A name The consent screen shows it to the person
Your redirect URIs One per line, http:// or https://

You get a client_id and a client_secret back. The page shows the secret once and keeps only a hash of it. Nobody can read it back to you later, so a lost secret means registering again.

Ask for the "Any approved account" kind. The other kind admits only administrators of this platform, which is almost certainly not what you want.

Redirect URIs match exactly

Both /oidc/authorize and /oidc/token compare every redirect URI byte for byte. There is no prefix match and no wildcard. A trailing slash you didn't register is a different URI.

Register every callback you use, including the local one you develop with.

The flow

This provider offers the authorization_code grant and no other. Start from the discovery document rather than writing these paths down:

GET /.well-known/openid-configuration
  1. Send the person to /oidc/authorize with client_id, redirect_uri, response_type=code, scope=openid email, and a state you generate. Add a nonce if your library uses one.
  2. They sign in here and agree. They arrive back at your redirect_uri with code and your state. Check that the state matches.
  3. Exchange the code at /oidc/token from your server, with your client_secret. The code is single-use and lives 60 seconds.
  4. Verify the id_token with the key at /.well-known/jwks.json.

/oidc/userinfo answers the same identity claims, if your library prefers to read them there: sub, plus email and email_verified when you asked for the email scope. Call it once, straight after the exchange, with the access_token as a bearer token.

scope must contain openid, and may contain email. This provider refuses anything else with error=invalid_scope, so don't send profile.

The proof key for code exchange, S256, is always welcome, and mandatory if the operator ticked that box on your registration. Send it. Your library almost certainly does already.

What it won't do

Not there Instead
Refresh tokens The access token lives 5 minutes, for one /oidc/userinfo call. Keep your own session after sign-in, the way you would with any other provider
Logout, of any kind There is no end_session_endpoint and no back-channel logout. Signing out here doesn't sign the person out of your site
Any grant but authorization_code Client credentials included. This provider authenticates people, not machines. Machines use an API token
Dynamic client registration Ask an operator. /oauth/register exists, but it belongs to the Model Context Protocol (MCP) authorization server, which is a different thing

When it refuses

You see It means
404 from /oidc/authorize Unknown client_id, or a redirect_uri that isn't on your registration. Nothing redirects. The URI itself is what this check doubts, so sending a browser to it would be the attack the check stops
error=invalid_scope You asked for a scope beyond openid email, or left out openid
error=invalid_request A code_challenge_method other than S256, or none on a client that requires one
error=access_denied The person pressed deny, or may not use this client. The two share one code on purpose: do the same thing for both, which is to stop and offer your own sign-in
invalid_client from /oidc/token Wrong client_id or client_secret
invalid_grant from /oidc/token The code is unknown, expired, or already spent. Or the redirect_uri doesn't match the one you authorized with

This provider rate-limits repeated refusals per source, across /oidc/authorize, /oidc/token and /oidc/userinfo together. A working client never touches that budget. Only a rejection spends it.

One key, no rotation

The issuer signs with one key under one kid. Read it from /.well-known/jwks.json rather than pinning it, and honour the kid in the token header, so a future rotation doesn't break you.

← All developer pages