# Auth & OAuth

## Initialize authentication handoff between customer application and a BlueNexus application

> Initialize a secure user authentication handoff to redirect an authenticated user from a customer application to a BlueNexus application without re-authentication. This endpoint returns a short-lived handoff code to include when redirecting the user to the BlueNexus application.\
> \
> \*\*Access restriction:\*\* Whitelabel customer client only

```json
{"openapi":"3.0.0","info":{"title":"BlueNexus API","version":"1.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"Access Token","description":"Enter JWT access token","in":"header"}},"schemas":{"Init Authentication Handoff V1 Body":{"type":"object","properties":{"redirectUri":{"type":"string","description":"The redirect URI to send the user back to"},"intent":{"type":"string","description":"The intent of the authentication request","enum":["connections"]}},"description":"Request body for initializing authentication handoff","required":["redirectUri","intent"]},"Init Authentication Handoff V1 Response":{"type":"object","properties":{"code":{"type":"string","description":"The authentication handoff code"},"expiresAt":{"format":"date-time","type":"string","description":"The expiration date and time of the handoff code"}},"description":"Response body for initializing authentication handoff","required":["code","expiresAt"]},"Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"Generic error response","required":["error"]}}},"paths":{"/api/v1/auth/handoff/init":{"post":{"description":"Initialize a secure user authentication handoff to redirect an authenticated user from a customer application to a BlueNexus application without re-authentication. This endpoint returns a short-lived handoff code to include when redirecting the user to the BlueNexus application.\n\n**Access restriction:** Whitelabel customer client only","operationId":"init","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Init Authentication Handoff V1 Body"}}}},"responses":{"200":{"description":"Authentication handoff initialized successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Init Authentication Handoff V1 Response"}}}},"412":{"description":"Unable to determine client criterias for secure handoff"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error Response"}}}}},"summary":"Initialize authentication handoff between customer application and a BlueNexus application","tags":["Auth & OAuth"]}}}}
```

## Authenticate user

> Authenticate a user using a signed SIWE payload and an optional sessionId to continue an existing session. Returns access and refresh tokens as well as the session ID. The session ID can be stored for future authentication requests to continue on the same session.\
> \
> Confidential clients must pass their credentials using Basic Auth in the Authorization header. Public clients without secret must pass the client\_id in the body.\
> \
> \*\*Access restriction:\*\* Whitelabel customer client only

```json
{"openapi":"3.0.0","info":{"title":"BlueNexus API","version":"1.0"},"security":[{"basic-client":[]}],"components":{"securitySchemes":{"basic-client":{"type":"http","scheme":"basic","description":"OAuth Client credentials","bearerFormat":"Basic"}},"schemas":{"Authenticate V1 Body":{"type":"object","properties":{"client_id":{"type":"string","description":"Client ID to pass for public clients (no secret). Clients with a secret can use the Basic authorization headers instead (recommended)."},"client_secret":{"type":"string","description":"Client secret. Optional for public clients (no secret). Required for confidential clients. Clients with a secret can use the Basic authorization headers instead (recommended)."},"payload":{"description":"SIWE payload","allOf":[{"$ref":"#/components/schemas/SIWE Payload"}]},"signature":{"type":"string","description":"Signature of the SIWE payload"},"session_id":{"type":"string","description":"Session id to continue, if not provided a new session is created"}},"description":"Authenticate request body","required":["payload","signature"]},"SIWE Payload":{"type":"object","properties":{"domain":{"type":"string","description":"Domain requesting the login"},"address":{"type":"string","description":"Address of the user"},"statement":{"type":"string","description":"Statement of the login"},"uri":{"type":"string","description":"URI for the login"},"version":{"type":"string","description":"Version of the login"},"chain_id":{"type":"string","description":"Chain ID of the login"},"nonce":{"type":"string","description":"Nonce for the login"},"issued_at":{"type":"string","description":"Issued at time of the login"},"expiration_time":{"type":"string","description":"Expiration time of the login"},"invalid_before":{"type":"string","description":"Not before time of the login"},"resources":{"description":"Resources for the login","type":"array","items":{"type":"string"}}},"description":"Payload for login","required":["domain","address","statement","version","nonce","issued_at","expiration_time"]},"Authenticate V1 Response":{"type":"object","properties":{"session_id":{"type":"string","description":"Session id"},"token_type":{"type":"string","description":"Token type = Bearer","enum":["Bearer"]},"access_token":{"type":"string","description":"Access token"},"expires_in":{"type":"number","description":"Access token expiration time in seconds"},"refresh_token":{"type":"string","description":"Refresh token"},"refresh_expires_in":{"type":"number","description":"Refresh token expiration time in seconds"},"scope":{"type":"string","description":"Space-separated list of scopes."}},"description":"Authenticate response","required":["session_id","token_type","access_token","refresh_token"]},"OAuth Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"error_description":{"type":"string","description":"OAuth error description"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"OAuth error response","required":["error","error_description"]},"Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"Generic error response","required":["error"]}}},"paths":{"/api/v1/auth/authenticate":{"post":{"description":"Authenticate a user using a signed SIWE payload and an optional sessionId to continue an existing session. Returns access and refresh tokens as well as the session ID. The session ID can be stored for future authentication requests to continue on the same session.\n\nConfidential clients must pass their credentials using Basic Auth in the Authorization header. Public clients without secret must pass the client_id in the body.\n\n**Access restriction:** Whitelabel customer client only","operationId":"authenticate","parameters":[{"name":"Authorization","in":"header","description":"Basic auth credentials with client ID and secret. Optional, public clients without secret must pass the client_id in the body.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Authenticate V1 Body"}}}},"responses":{"200":{"description":"Authenticate response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Authenticate V1 Response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth Error Response"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error Response"}}}}},"summary":"Authenticate user","tags":["Auth & OAuth"]}}}}
```

## OAuth token exchange

> Either exchange an authorization code for an access token or refresh an access token using a refresh token.

```json
{"openapi":"3.0.0","info":{"title":"BlueNexus API","version":"1.0"},"security":[{"client-auth":[]},{"basic-client":[]}],"components":{"securitySchemes":{"basic-client":{"type":"http","scheme":"basic","description":"OAuth Client credentials","bearerFormat":"Basic"}},"schemas":{"Token V1 Body":{"type":"object","properties":{"grant_type":{"type":"string","description":"OAuth grant type","enum":["authorization_code","refresh_token"]},"code":{"type":"string","description":"Authorization code. Required for the authorization_code grant type."},"redirect_uri":{"type":"string","description":"Redirect URI. Required for the authorization_code grant type. It must match the redirect URI used to obtain the authorization code."},"client_id":{"type":"string","description":"Client ID."},"client_secret":{"type":"string","description":"Client secret."},"code_verifier":{"type":"string","description":"PKCE code verifier. Required for the authorization_code grant type."},"refresh_token":{"type":"string","description":"Refresh token. Required for the refresh_token grant type."}},"description":"Token exchange request body","required":["grant_type"]},"Token V1 Response":{"type":"object","properties":{"token_type":{"type":"string","description":"Token type = Bearer","enum":["Bearer"]},"access_token":{"type":"string","description":"Access token"},"expires_in":{"type":"number","description":"Access token expiration time in seconds"},"refresh_token":{"type":"string","description":"Refresh token"},"refresh_expires_in":{"type":"number","description":"Refresh token expiration time in seconds"},"scope":{"type":"string","description":"Space-separated list of scopes."}},"description":"Token exchange response","required":["token_type","access_token","refresh_token"]},"OAuth Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"error_description":{"type":"string","description":"OAuth error description"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"OAuth error response","required":["error","error_description"]},"Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"Generic error response","required":["error"]}}},"paths":{"/api/v1/auth/token":{"post":{"description":"Either exchange an authorization code for an access token or refresh an access token using a refresh token.","operationId":"token","parameters":[{"name":"Authorization","in":"header","description":"Basic auth credentials with client id and secret. If undefined, falls back to client id and secret in the body. Whatever the method, the client ID is required. Client without secret should use the body.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token V1 Body"}}}},"responses":{"200":{"description":"Token exchange response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token V1 Response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth Error Response"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error Response"}}}},"4XX":{"description":"OAuth error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth Error Response"}}}}},"summary":"OAuth token exchange","tags":["Auth & OAuth"]}}}}
```

## Revoke an auth session

> Revoke an auth session from an access token or a refresh token.

```json
{"openapi":"3.0.0","info":{"title":"BlueNexus API","version":"1.0"},"security":[{"client-auth":[]},{"basic-client":[]}],"components":{"securitySchemes":{"basic-client":{"type":"http","scheme":"basic","description":"OAuth Client credentials","bearerFormat":"Basic"}},"schemas":{"Revoke V1 Body":{"type":"object","properties":{"token":{"type":"string","description":"Token to revoke, either access or refresh token."},"token_type_hint":{"type":"string","description":"Token type hint, indicating if the provided token is either an access or a refresh token.","enum":["access_token","refresh_token"]},"client_id":{"type":"string","description":"Client ID. Could be passed in the body or as a Basic Authorization header as the preferred method. Whatever the method, the client ID is required."},"client_secret":{"type":"string","description":"Client secret. Could be passed in the body or as a Basic Authorization header as the preferred method."}},"description":"Revoke access token or refresh token request body","required":["token"]},"OAuth Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"error_description":{"type":"string","description":"OAuth error description"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"OAuth error response","required":["error","error_description"]},"Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"Generic error response","required":["error"]}}},"paths":{"/api/v1/auth/revoke":{"post":{"description":"Revoke an auth session from an access token or a refresh token.","operationId":"revoke","parameters":[{"name":"Authorization","in":"header","description":"Basic auth credentials with client id and secret. If undefined, falls back to client id and secret in the body. Whatever the method, the client ID is required. Client without secret should use the body.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revoke V1 Body"}}}},"responses":{"200":{"description":"No content for the revoke response, as per OAuth specification."},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth Error Response"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error Response"}}}}},"summary":"Revoke an auth session","tags":["Auth & OAuth"]}}}}
```

## Get authorization scopes

> Get all available authorization scopes.

```json
{"openapi":"3.0.0","info":{"title":"BlueNexus API","version":"1.0"},"paths":{"/api/v1/auth/scopes":{"get":{"description":"Get all available authorization scopes.","operationId":"getAll","parameters":[],"responses":{"200":{"description":"Available authorization scopes retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Get Authorization Scopes V1 Response"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error Response"}}}}},"summary":"Get authorization scopes","tags":["Auth & OAuth"]}}},"components":{"schemas":{"Get Authorization Scopes V1 Response":{"type":"object","properties":{"scopes":{"description":"List of available scopes","type":"array","items":{"$ref":"#/components/schemas/Authorization Scope"}}},"description":"Get available authorization scopes response","required":["scopes"]},"Authorization Scope":{"type":"object","properties":{"scope":{"type":"string","description":"Scope"},"description":{"type":"string","description":"Scope description"}},"description":"Authorization scope details","required":["scope","description"]},"Error Response":{"type":"object","properties":{"error":{"type":"string","description":"Error message"},"message":{"type":"string","description":"Additional error details or context"},"statusCode":{"type":"number","description":"HTTP status code"}},"description":"Generic error response","required":["error"]}}}}
```
