Skip to main content
Version: 3.102.8

Personal Access Token (PAT) for API Access

A Personal Access Token (PAT) is a pass issued as an opaque, revocable token (cpat-...) instead of a signed JWT. It is the recommended Access Pass method for authorizing service-to-service and partner API calls.

Why use a PAT instead of a JWT

JWT access tokenPAT (cpat-...)
ValidationSignature check, mostly local/offlineIntrospection call to cidaas at request time
RevocationOnly takes effect after expiry, unless actively checkedImmediately revocable — checked on every request
BindingScopes and claims baked into the tokenScopes, validity, and optional resource constraints are enforced centrally and can be changed without reissuing the token

Choose a PAT when you need:

  • Revocable, opaque tokens for long-lived service integrations (e.g. partner APIs).
  • Central, real-time checks of active status and scopes.
  • Optional token-to-API binding via targetResourceRef when scopes alone are not enough to distinguish which service a token may call.

How it works

Step 1: Create a PAT-enabled pass template

Most PAT integrations only need scopes — no Resource Catalog registration required.

POST /accesspass-srv/templates
{
"name": "partner-api-pat-template",
"description": "PAT template for partner API access",
"methods": ["pat"],
"maxValidity": {
"value": 30,
"unit": "days"
},
"systemConstraint": {
"scopes": ["analytics:read", "incident:write"]
}
}

See Create pass template.

Step 2: Issue the pass and receive the token

POST /accesspass-srv/passes
{
"passUserHolder": { "sub": "sub-partner-admin-01", "givenName": "Neha", "familyName": "Iyer" },
"passUser": { "sub": "sub-partner-admin-01", "givenName": "Neha", "familyName": "Iyer" },
"pass": {
"title": "Partner API PAT",
"passId": "PARTNER-PAT-0001",
"productId": "partner-api",
"productName": "Partner API",
"productInstanceId": "partner-api-v1",
"passTemplateId": "partner-api-pat-template",
"method": "pat",
"validFrom": "2026-03-20T09:00:00Z",
"validTo": "2026-04-19T09:00:00Z",
"systemConstraint": { "scopes": ["analytics:read", "incident:write"] }
}
}

The response contains the opaque token:

{
"success": true,
"data": {
"passId": "PARTNER-PAT-0001",
"token": "cpat-<opaque-token>"
}
}

Store this token securely on the partner/service side — it is not a JWT and cannot be decoded or introspected offline. See Create a new pass.

Step 3: Validate the PAT on every API request

Client applications call your protected API with Authorization: Bearer cpat-.... Your API introspects the token on each request rather than validating a signature locally:

POST /accesspass-srv/passes/pat/introspect
{
"token": "cpat-<opaque-token>",
"access_method": "pat",
"strictValidation": true,
"systemFields": { "scopes": ["analytics:read"] }
}

See Introspect (validate) a pass. A response with active: true and matching scopes authorizes the request.

Integrating introspection in your API (Go example)

If your service is built with Fiber and the cidaas go-interceptor library, use the PAT interceptor to enforce introspection-based checks per route. Deployments may also use the internal GitLab module (cidaas-go-interceptor/v4); confirm the package path for your environment.

patInterceptor, err := cidaasinterceptor.NewPatInterceptor(cidaasinterceptor.Options{
BaseURI: "https://<your-cidaas-domain>",
ClientID: "<api-client-id>",
})

app := fiber.New()
app.Get("/analytics",
patInterceptor.VerifyTokenByIntrospect(cidaasinterceptor.SecurityOptions{
Scopes: []string{"analytics:read"},
}),
handler,
)

If you are not using Go/Fiber, call the introspection endpoint directly from your own middleware before processing the request.

Step 4: Revoke a PAT

Because a PAT is checked by introspection on every request, revoking it takes effect immediately — no need to wait for expiry. Revoke it the same way as any other pass:

POST /accesspass-srv/passes/revoke
{
"passId": "PARTNER-PAT-0001",
"reason": "Partner integration decommissioned"
}

See Revoke a pass.

Endpoints used in this guide. For the full API surface, see the Access Pass API reference.

OperationMethodPathDescriptionLink
Create pass templatePOST/accesspass-srv/templatesPAT-enabled template with methods: ["pat"].View API
Create passPOST/accesspass-srv/passesIssues the pass and returns the cpat-... token.View API
Introspect passPOST/accesspass-srv/passes/pat/introspectValidates the token on each API request.View API
Revoke passPOST/accesspass-srv/passes/revokeImmediately revokes the PAT.View API

Optional: Bind the PAT to specific APIs (targetResourceRef)

Use this only when a token must be limited to specific catalog entries beyond scopes — for example, two APIs share the same scope but should accept different tokens.

  1. Register the APIs as catalog resources first — see Step 1 in Physical access control (managed via the Access Control service / Trustdesk, not accesspass-srv).
  2. Add targetResourceRef to the template, pass, and introspection request.

Template variant:

POST /accesspass-srv/templates
{
"name": "partner-api-pat-template",
"description": "PAT template scoped to Analytics API",
"methods": ["pat"],
"maxValidity": { "value": 30, "unit": "days" },
"systemConstraint": { "scopes": ["analytics:read", "incident:write"] },
"targetResourceRef": {
"resourceIds": ["api-analytics-v1"],
"resourceGroupIds": ["group:partner-apis"]
}
}

Pass variant — add to the pass object:

"targetResourceRef": { "resourceIds": ["api-analytics-v1"] }

Introspection variant — include targetResourceRef in the introspect body only when the pass or template defines it:

POST /accesspass-srv/passes/pat/introspect
{
"token": "cpat-<opaque-token>",
"access_method": "pat",
"strictValidation": true,
"systemFields": { "scopes": ["analytics:read"] },
"targetResourceRef": { "resourceIds": ["api-analytics-v1"] }
}

Checklist

  • Use method: "pat" on the template and pass instead of qrcode or other presentation methods.
  • Scope the PAT with systemConstraint.scopes — this is the primary access control for most integrations.
  • Add targetResourceRef only when you need to restrict which API/service the token works against beyond scopes.
  • Never expect to decode a PAT locally — always validate it via POST /accesspass-srv/passes/pat/introspect.
  • Revoke a PAT immediately when an integration ends; there is no need to wait for validTo.