EN IT

Authentication

Contit supports multiple authentication methods depending on your use case.

Methods

Method Use case Header
Client Credentials (OAuth2) Server-to-server, write operations Authorization: Bearer {token}
API Key Read-only public access, simple integrations X-Api-Key: {key} or ?api_key={key}
Personal Access Token (PAT) AI agents / MCP server, per-user tokens Authorization: Bearer ctpat_...
Authorization Code + PKCE User-facing applications (browser login) Authorization: Bearer {token}
Refresh Token Long-lived sessions Exchange at /connect/token

1. Get an access token

curl -X POST https://idp.contit.cloud/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"

Response:

{
  "access_token": "eyJhbGci...",
  "token_type": "Bearer",
  "expires_in": 3600
}

2. Use the token

curl https://api.contit.cloud/contents/myContentType \
  -H "Authorization: Bearer eyJhbGci..."

Token lifetime: 1 hour. Use the refresh token grant to renew without re-authenticating.


API Key

API Keys are suitable for read-only public access (e.g., frontend apps, public APIs).

# Via header
curl https://api.contit.cloud/contents/myContentType \
  -H "X-Api-Key: YOUR_API_KEY"

# Via query parameter
curl "https://api.contit.cloud/contents/myContentType?api_key=YOUR_API_KEY"

API Keys do not support write operations. For creating or updating content, use Client Credentials.


Personal Access Token (PAT)

Personal Access Tokens are tied to a single user and are designed to configure AI agents and the MCP server (Claude Code/Desktop or other tools). Unlike API Keys (tied to a workspace client), a PAT acts on behalf of the user who created it.

1. Generate the token

From the Contit console: Settings → Developer → Personal Access Tokens → Add. Choose a name, expiration, permissions (read / read-write) and optional per-content-type permissions. The token is shown only once at creation time: copy it immediately.

A PAT has the format ctpat_....

2. Use the token directly

The PAT can be used as a Bearer on all APIs: it is resolved automatically server-side.

curl https://api.contit.cloud/contents/myContentType \
  -H "Authorization: Bearer ctpat_xxxxxxxx"

3. Explicit exchange for a JWT (optional)

If you prefer to obtain a JWT access token from the PAT, use the pat grant:

curl -X POST https://idp.contit.cloud/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=pat&pat=ctpat_xxxxxxxx"

The resulting token contains the user's email claim, contit:workspaceId and the PAT's contit:permissions.


Introspection (centralized validation)

The POST /connect/introspect endpoint (RFC 7662) lets reserved apps validate a PAT centrally, without re-implementing verification. The call is authenticated with the installed app's credentials.

curl -X POST https://idp.contit.cloud/connect/introspect \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ctpat_xxxxxxxx&client_id=APP_CLIENT_ID&client_secret=APP_CLIENT_SECRET"

Response (valid token):

{
  "active": true,
  "token_type": "pat",
  "sub": "user-id",
  "email": "[email protected]",
  "name": "Jane Doe",
  "contit:workspaceId": "ws-id",
  "contit:permissions": ["read", "write"],
  "exp": 1750000000
}

For an invalid or expired token the response is { "active": false }.

In the .NET SDK you can use the ContitTokenValidator class:

var validator = new ContitTokenValidator(appClientId, appClientSecret);
var info = await validator.ValidateAsync(incomingToken);
if (info.Active)
{
    // info.UserId, info.WorkspaceId, info.CanRead, info.CanWrite
}

Custom claims

All access tokens issued by Contit contain custom claims:

Claim Description
contit:workspaceId The workspace ID the client belongs to
contit:permissions Comma-separated list: read, write, app.read, app.user
contit:clientLogActive Whether request logging is enabled for this client
contit:ctPermissions Per-content-type permissions (JSON, optional)

Authorization policies

Policy Required permission Used for
ReadAccess read GET and POST (search) operations
WriteAccess write PUT and DELETE operations
App.ReadAccess app.read App settings endpoints
App.UserAccess app.user Cross-workspace app operations

Per-content-type permissions

Each client can be configured to restrict access to specific content types, with independent read and write permissions.

Behavior

  • No configuration (default): the client has access to all content types, including those created in the future. Read and write are controlled by the global Readonly flag.
  • Permissions configured: the client can only access the listed content types, with read and write specified per content type. Content types created after the configuration are not accessible until explicitly added to the list.

Configuration

In the API Keys section of the workspace settings, select a client and enable "Restrict access by content type". For each content type you can enable:

Permission Description
Read The client can search and retrieve contents of this type
Write The client can create and update contents of this type
Delete The client can delete contents of this type

The three permissions are independent: for example, you can grant write access without delete.

Example

A client configured with:

  • articles: read + write + delete
  • categories: read only
  • products: read + write (no delete)

Can fully manage articles, only view categories, and create/update products without being able to delete them. It will not have access to other content types (e.g., pages).