2025-07-17 10:22:20 -04:00

355 lines
13 KiB
YAML

openapi: 3.1.0
info:
title: Lacpass Authentication Server
description: Authentication endpoints
version: 1.0.0
servers:
- url: 'http://localhost:8082'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: "Access token obtained via the Token endpoint."
schemas:
Account:
type: object
properties:
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
emailVerified:
type: boolean
attributes:
type: object
additionalProperties:
type: array
items:
type: string
UserRepresentation:
type: object
description: "Represents the current user's profile."
properties:
id:
type: string
readOnly: true
description: "User's ID."
username:
type: string
description: "User's username."
firstName:
type: string
description: "User's first name."
lastName:
type: string
description: "User's last name."
email:
type: string
format: email
description: "User's email address."
emailVerified:
type: boolean
readOnly: true
description: "Indicates if the user's email has been verified."
attributes:
type: object
additionalProperties:
type: string
description: "A map of custom user attributes."
SessionRepresentation:
type: object
description: "Represents an active user session."
properties:
id:
type: string
description: "Session ID."
ipAddress:
type: string
description: "IP address from which the session was initiated."
started:
type: integer
format: int64
description: "Timestamp of when the session started."
lastAccess:
type: integer
format: int64
description: "Timestamp of the last access in this session."
current:
type: boolean
description: "Indicates if this is the current session"
browser:
type: string
description: "Browser or user agent."
os:
type: string
description: "Operating system."
Error:
type: object
description: "Error"
properties:
error:
type: string
description: "Error type"
examples: ["invalid_request"]
error_description:
type: string
description: "Error description"
examples: ["Missing form parameter: grant_type"]
examples:
InvalidRequestError:
value:
error: "invalid_request"
error_description: "Missing form parameter: grant_type"
summary: "Invalid request"
InvalidUserCredentialsError:
value:
error: "invalid_grant"
error_description: "Invalid user credentials"
summary: "Invalid user credentials"
MaximumRefreshTokenUsesExceeded:
value:
error: "invalid_grant"
error_description: "Maximum allowed refresh token reuse exceeded"
summary: "Maximum allowed refresh token reuse exceeded"
# Group the endpoints into logical tabs.
tags:
- name: Authentication
description: "Endpoints for user authentication (OpenID Connect)."
- name: User
description: "Endpoints for user account"
paths:
/realms/{realm}/protocol/openid-connect/token:
post:
tags:
- Authentication
summary: "Get Token"
description: "Exchanges user credentials for an access and refresh tokens"
parameters:
- name: realm
in: path
required: true
schema:
type: string
examples: ["lacpass"]
description: "Name of the realm."
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
grant_type:
description: "Can be either `password` or `refresh_token`."
type: string
enum:
- password
- refresh_token
examples: ["password", "refresh_token"]
client_id:
description: "The ID of the client application."
type: string
enum:
- app
examples: ["app"]
refresh_token:
description: "Refresh token when `grant_type` refresh_token is used."
type: string
example: "eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1ZjA5MWRkYy1kNDQ3LTQ0OGYtODBmOS01NDUyYmRiMjM0ZjQifQ.eyJleHAiOjE3NTAxNzc3OTYsImlhdCI6MTc1MDA5MTM5NiwianRpIjoiNWJiMDNkMWQtYmY2Yy00MDZjLWI5NTktYmMzMjY4NjY3MjJlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgyL3JlYWxtcy9sYWNwYXNzIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgyL3JlYWxtcy9sYWNwYXNzIiwic3ViIjoiNjYwMWIzMjYtOTU5Yi00ZWNkLTliOGMtYTkzNThkNjAxYzRhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFwcCIsInNpZCI6IjRiODM5OWU3LTNjYzUtNDJjZi1hNTJhLWY3MmZkOTE1MGM0MyIsInNjb3BlIjoid2ViLW9yaWdpbnMgYmFzaWMgcHJvZmlsZSByb2xlcyBlbWFpbCBhY3IiLCJyZXVzZV9pZCI6IjZmNDRkMTkzLWQwODQtNGU5Yi1iMWY1LWNkNTI1OWQyZWY5NiJ9.8yv3KVAyiBNQ2q9rcO0_oHdEBfQ5eJfRLVoCsYRCQsLMwfdV9Jc4NOmIXc337artKwY8c6k0_1ILhud-STPuJg"
required: false
username:
type: string
description: "User's email. Required when `grant_type` is password."
examples: ["jdoe@example.com"]
required: false
password:
type: string
description: "User's password. Required when `grant_type` is password."
examples: ["secret-password"]
required: false
scope:
type: string
description: "The scopes being requested. `openid` scope should always be present"
examples: ["openid profile email"]
required: false
responses:
'200':
description: "Authentication successful."
content:
application/json:
schema:
type: object
properties:
access_token:
type: string
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
refresh_token:
type: string
example: "pvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
not-before-policy:
type: integer
example: 0
session_state:
type: string
example: "9c238c37-1021-43b3-a122-67301500a61d"
scope:
type: string
example: "profile email"
expires_in:
type: integer
example: 123058381
refresh_expires_in:
type: integer
example: 181283903
token_type:
type: string
example: "Bearer"
'401':
description: "Bad Request - a required parameter is missing or invalid."
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidRequest:
$ref: '#/components/examples/InvalidRequestError'
invalidUserCredentials:
$ref: '#/components/examples/InvalidUserCredentialsError'
MaximumRefreshTokenUsesExceeded:
$ref: '#/components/examples/MaximumRefreshTokenUsesExceeded'
/realms/{realm}/protocol/openid-connect/logout:
post:
tags:
- Authentication
summary: "Log Out"
description: "Logs the user out of their session. Requires the refresh token to fully invalidate the session."
parameters:
- name: realm
in: path
required: true
schema:
type: string
description: "The name of the realm."
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
client_id:
type: string
description: "The ID of the client application."
examples: ["my-app-client"]
refresh_token:
type: string
description: "The refresh token obtained during login."
responses:
'204':
description: "Logout successful."
/realms/{realm}/protocol/openid-connect/userinfo:
get:
summary: "Get User Information"
description: "This endpoint returns claims about the authenticated end-user."
tags:
- User
parameters:
- name: realm
in: path
required: true
description: "The name of the realm."
schema:
type: string
security:
- bearerAuth: [ ]
responses:
"200":
description: "Successful response with user resource."
content:
application/json:
schema:
type: object
properties:
sub:
type: string
description: "User's id on the realm."
name:
type: string
description: "Full name."
given_name:
type: string
description: "Given name or first name."
family_name:
type: string
description: "Surname or last name."
preferred_username:
type: string
description: "Preferred username."
email:
type: string
format: email
description: "E-mail address."
email_verified:
type: boolean
description: "Indicates if the user's email has been verified."
locale:
type: string
description: "Preferred language."
document_type:
type: string
description: "Identity document type"
enum:
- passport
- id
identifier:
type: string
description: "Document identifier"
example:
sub: "a8c6d49a-72c7-4402-a1b1-7a5e9f8b4d6c"
name: "John Doe"
given_name: "John"
family_name: "Doe"
preferred_username: "jdoe"
email: "johndoe@example.com"
email_verified: true
locale: "en"
document_type: "passport"
identifier: "F12345678"
"401":
description: "Unauthorized. The request is missing a valid bearer token."
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "unauthorized"
error_description:
type: string
example: "Bearer token not provided or is invalid."
"403":
description: "Forbidden. The provided token does not have the required permissions (e.g., missing 'openid' scope)."
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "insufficient_scope"
error_description:
type: string
example: "The 'openid' scope is required."