# Bebrikic ID OAuth 2.0 integration prompt Base URL: https://id.bebrikic.online Protocol: OAuth 2.0 Authorization Code Audience: backend developers integrating a Bebrikic ecosystem service with Bebrikic ID. ## What Bebrikic ID is Bebrikic ID is the account and identity layer for the Bebrikic ecosystem. It handles sign in, registration, profiles, roles, badges, Prime and Apex access, OAuth integrations, security settings, and API access for connected services. Use this file when an agent needs to implement "Sign in with Bebrikic ID" or explain the integration flow to a developer. ## Integration flow 1. Create an OAuth client. Endpoint: POST /web/api/admin/oauth/clients Access: owner only, web session required. Request JSON: ```json {"name":"NYRP","redirect_uri":"https://nyrp.ru/auth/bebrikic/callback"} ``` Response JSON: ```json {"client_id":"cli_...","client_secret":"sec_..."} ``` Store `client_secret` only on the server. 2. Generate `state`. Create a random 16 to 32 character string. Store it in the user's session and verify it in the callback to protect against CSRF. 3. Generate PKCE values. Create a `code_verifier` with 43 to 128 characters from `A-Z`, `a-z`, `0-9`, `.`, `_`, `~`, and `-`. Create `code_challenge` as base64url without padding of `SHA256(code_verifier)`. Store `code_verifier` in the user's server-side session until the callback completes. 4. Redirect the user to authorization. Endpoint: GET /oauth/authorize Example: ```text /oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://nyrp.ru/auth/bebrikic/callback&state=STATE&code_challenge=CODE_CHALLENGE&code_challenge_method=S256 ``` The `redirect_uri` must match the registered redirect URI exactly. The `response_type` must be `code`. The `code_challenge_method` must be `S256`. 5. Exchange the code for an access token. Endpoint: POST /oauth/token This request must be server to server. Request JSON: ```json {"grant_type":"authorization_code","client_id":"CLIENT_ID","client_secret":"CLIENT_SECRET","code":"code_xxx","redirect_uri":"https://nyrp.ru/auth/bebrikic/callback","code_verifier":"CODE_VERIFIER"} ``` Send the same `redirect_uri` value that was used in the authorization request. Send the original `code_verifier` that produced `code_challenge`. Response JSON: ```json {"access_token":"JWT","token_type":"bearer"} ``` 6. Fetch the user profile. Endpoint: GET /me Header: ```text Authorization: Bearer ACCESS_TOKEN ``` The profile response includes `id`, `username`, `email`, and profile fields. 7. Create the local session in the integrating service. Typical backend sequence: - receive `code` and `state` on the callback; - verify `state` against the stored session value; - exchange `code`, `redirect_uri`, and `code_verifier` for `access_token`; - call `/me`; - create or update the local user; - create the local session. ## Security rules - Do not send `client_secret` to the browser. - Do not store `access_token` in frontend JavaScript. - Store tokens in a server-side session. - Do not log client secrets, authorization codes, access tokens, or bearer headers. - Treat authorization codes as one-time values. - Validate that `redirect_uri` matches the registered URI before relying on a callback. - Send `grant_type=authorization_code` and the same `redirect_uri` during token exchange. - Use PKCE with `code_challenge_method=S256`; do not use `plain`. - Keep `code_verifier` server side and send it only to `/oauth/token`. - Keep `state` unpredictable and bind it to the current browser session. ## Common errors - `401` on `/oauth/token`: `client_secret` is wrong, the code expired, or the code was already used. - `400 Unsupported grant_type`: `grant_type` is missing or is not `authorization_code`. - `400 Invalid client`: `client_id` or the authorization redirect does not match a registered OAuth client. - `400 Invalid redirect_uri`: token exchange used a different `redirect_uri` than the authorization request. - `400 PKCE S256 is required`: `code_challenge_method` is missing, `plain`, or any value other than `S256`. - `401 Invalid code_verifier`: `code_verifier` does not match the stored `code_challenge`. - Reusing the same `code` fails because authorization codes are one-time values. ## Minimal route map ```text /oauth/authorize -> code -> /oauth/token -> access_token -> /me ``` ## Public references - Homepage: https://id.bebrikic.online/ - API documentation: https://id.bebrikic.online/docs/ - AI context: https://id.bebrikic.online/llms.txt - Security contact: https://id.bebrikic.online/.well-known/security.txt