On this page

Authentication and authorization

Markdown

How Glossia authenticates users and authorizes API access.

Authentication methods

Glossia supports two authentication methods depending on the context.

Browser sessions

When you sign in through the web interface, Glossia uses session-based authentication. You authenticate via a third-party provider (GitHub or GitLab) using the Assent library. After a successful sign-in, a session cookie is set and used for subsequent requests.

Bearer tokens (OAuth 2.1)

For API access (such as from the CLI or other tools), Glossia implements OAuth 2.1 with the authorization code flow and PKCE. Clients obtain a Bearer token and include it in the Authorization header:

Authorization: Bearer <access_token>

OAuth 2.1 flow

1. Dynamic client registration

Clients register themselves by calling POST /oauth/register with their metadata. This follows RFC 7591.

{
  "client_name": "My Tool",
  "redirect_uris": ["http://localhost:8080/callback"],
  "grant_types": ["authorization_code"]
}

The server returns client_id and client_secret.

2. Authorization request

The client redirects the user to /oauth/authorize with PKCE parameters:

GET /oauth/authorize?response_type=code&client_id=<id>&redirect_uri=<uri>&code_challenge=<challenge>&code_challenge_method=S256&state=<state>

PKCE is required for all clients. Only the S256 challenge method is supported.

3. Token exchange

After the user approves, the client exchanges the authorization code for tokens at POST /oauth/token:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=<code>&redirect_uri=<uri>&client_id=<id>&code_verifier=<verifier>

The response includes an access token and optionally a refresh token.

4. Token refresh

When an access token expires, use the refresh token:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=<token>&client_id=<id>&client_secret=<secret>

Scopes

Scopes control what actions a token can perform. They follow the object:action pattern.

Scope Description
user:read Read user profile information
user:write Update user profile
account:read List accounts you can access (personal and organization accounts)
organization:read Read organization details (and list your organizations)
organization:write Create or update organizations
organization:delete Delete organizations
organization:admin Administrative organization actions
members:read Read organization members and invitations
members:write Manage organization members and invitations
project:read Read projects
project:write Create or update projects
project:admin Administrative project actions
project:delete Delete projects
voice:read Read voice configuration
voice:write Create or update voice configuration
voice:admin Administrative voice actions
glossary:read Read glossary entries
glossary:write Create or update glossary entries
glossary:admin Manage glossary settings

Authorization model

Glossia enforces two layers for the REST API and MCP server:

  1. Scope check: the access token must include the required object:action scope.
  2. Resource-level policy: the current user must be authorized for the specific resource via Glossia.Policy.

Scopes represent the maximum capability of a token. The policy system enforces the actual permission for a specific resource.

Write actions (like *:write, *:delete, and *:admin) are also denied when the user's account does not have access (accounts.has_access == false).

Roles

Role Description
self The user accessing their own resources
organization_member A member of the organization that owns the resource
organization_admin An administrator of the organization that owns the resource
account_owner The owner of the account that owns the resource
public_account The account is public (read-only)
no_access Denies write actions when the user account has no access

Role permissions

Scope self organization_member organization_admin account_owner public_account no_access*
user:read Yes Yes
user:write Yes
account:read Yes Yes Yes Yes
organization:read Yes Yes
organization:write Yes Yes
organization:delete Yes Yes
organization:admin Yes Yes
members:read Yes Yes
members:write Yes Yes
project:read Yes Yes Yes Yes
project:write Yes Yes Yes Yes
project:admin Yes Yes Yes
project:delete Yes Yes Yes
voice:read Yes Yes Yes Yes
voice:write Yes Yes Yes Yes
voice:admin Yes Yes Yes
glossary:read Yes Yes Yes
glossary:write Yes Yes Yes
glossary:admin Yes Yes

no_access* indicates that the rule is denied for write/admin/delete actions when accounts.has_access == false, even if the relationship check would otherwise allow it.

Discovery endpoints

Glossia publishes metadata at standard well-known URLs so clients can discover endpoints automatically.

OAuth Authorization Server Metadata (RFC 8414)

GET /.well-known/oauth-authorization-server

Returns the issuer, endpoints, supported scopes, grant types, and code challenge methods.

Protected Resource Metadata (RFC 9728)

GET /.well-known/oauth-protected-resource

Returns the resource identifier, authorization servers, supported scopes, and bearer methods.

Rate limiting

OAuth endpoints are rate limited per IP address:

Endpoint Limit
POST /oauth/register 5 requests per minute
POST /oauth/token 30 requests per minute
POST /oauth/revoke 30 requests per minute
POST /oauth/introspect 30 requests per minute

When rate limited, the server returns HTTP 429 (Too Many Requests).