Softwell Identity

Developer documentation

Integrate your application with Softwell Identity using OpenID Connect (OIDC) and OAuth 2.0.

Discovery

Most OIDC client libraries can configure themselves automatically from the discovery document. Point your library at:

https://login.softwell.it/o/.well-known/openid-configuration

The JWKS (public keys for verifying ID token signatures) is published at https://login.softwell.it/o/.well-known/jwks.json

Endpoints

Purpose Method URL
OIDC Discovery GET https://login.softwell.it/o/.well-known/openid-configuration
JWKS (public keys) GET https://login.softwell.it/o/.well-known/jwks.json
Authorization GET https://login.softwell.it/o/authorize/
Token POST https://login.softwell.it/o/token/
UserInfo GET POST https://login.softwell.it/o/userinfo/
Token revocation POST https://login.softwell.it/o/revoke_token/
Token introspection POST https://login.softwell.it/o/introspect/

Scopes & Claims

Available scopes

openid Required. Issues an ID token and authenticates the user.
profile User's full name, first name, last name, and avatar picture.
email User's email address and whether it has been verified.

Claims

Claim Scope Type Description
sub openid string (UUID) Stable unique user identifier. Permanent for the lifetime of the account.
name profile string Full display name.
given_name profile string First name.
family_name profile string Last name.
picture profile string (URL) Avatar image URL. Omitted if the user has not uploaded a picture.
email email string Email address.
email_verified email boolean true when the user has confirmed their email address.

sub is a UUID and is permanent for the lifetime of the account. Use it — not the email — as the stable foreign key on your side.

Authorization Code Flow (PKCE)

1 — Generate a code verifier and challenge

import secrets, hashlib, base64

code_verifier  = secrets.token_urlsafe(64)
digest         = hashlib.sha256(code_verifier.encode()).digest()
code_challenge = base64.urlsafe_b64encode(digest).rstrip(b'=').decode()

2 — Redirect the user to the authorization endpoint

GET https://login.softwell.it/o/authorize/
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.example.com/callback
  &scope=openid%20profile%20email
  &state=RANDOM_OPAQUE_VALUE
  &code_challenge=CODE_CHALLENGE
  &code_challenge_method=S256

The user will be asked to log in (if not already) and approve the requested scopes. After approval the browser is redirected to your redirect_uri with code and state query parameters.

3 — Exchange the code for tokens

POST https://login.softwell.it/o/token/
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://yourapp.example.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET   # confidential clients only
&code_verifier=CODE_VERIFIER
{ "access_token": "…", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "…", "scope": "openid profile email", "id_token": "…" }

4 — Fetch user information

GET https://login.softwell.it/o/userinfo/
Authorization: Bearer ACCESS_TOKEN
{ "sub": "9f3a1b2c-…", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "email": "jane@example.com", "email_verified": true, "picture": "https://login.softwell.it/accounts/avatar/9f3a1b2c-…/" }

Token lifetimes & management

Lifetimes

access_token — 1 hour refresh_token — 30 days (rotated on every use)

Refresh

POST https://login.softwell.it/o/token/
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET   # confidential clients only

Revoke (call on sign-out)

POST https://login.softwell.it/o/revoke_token/
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

token=TOKEN_TO_REVOKE

Security notes

  • Always validate the state parameter on the callback to prevent CSRF attacks.
  • Always validate the ID token signature (via JWKS) and check iss, aud, and exp before creating a session.
  • Use HTTPS for all redirect URIs in production.
  • Revoke the refresh token when the user signs out of your application.
  • Use sub — not email — as the stable foreign key; email addresses can change.