Skip to Content

Scopes API

Scope helpers work with any object that has a scopes: string[] property. This includes DelegationResult from both verifyDelegation and verifyPresentation.


hasScope

Checks if a result contains a specific scope.

function hasScope(result: { scopes: string[] }, scope: string): boolean

Example

import { hasScope } from "@credat/sdk"; if (hasScope(result, "email:read")) { // Agent has email:read permission }

hasAnyScope

Checks if a result contains at least one of the given scopes.

function hasAnyScope(result: { scopes: string[] }, scopes: string[]): boolean

Example

import { hasAnyScope } from "@credat/sdk"; if (hasAnyScope(result, ["files:read", "files:write"])) { // Agent has at least one file permission }

hasAllScopes

Checks if a result contains all of the given scopes.

function hasAllScopes(result: { scopes: string[] }, scopes: string[]): boolean

Example

import { hasAllScopes } from "@credat/sdk"; if (hasAllScopes(result, ["email:read", "email:send"])) { // Agent has complete email access }

getAllScopes

Returns a copy of the scopes array.

function getAllScopes(result: { scopes: string[] }): string[]

Example

import { getAllScopes } from "@credat/sdk"; const scopes = getAllScopes(result); // ["email:read", "email:send", "calendar:write"]

validateConstraints

Validates delegation constraints against a request context. Returns an array of violations --- empty if all constraints pass.

function validateConstraints( constraints: DelegationConstraints | undefined, context: ConstraintContext, ): ConstraintViolation[]

Parameters

ParameterTypeRequiredDescription
constraintsDelegationConstraints | undefinedYesConstraints from the verified delegation
contextConstraintContextYesThe current request context to validate against

ConstraintContext

FieldTypeDescription
transactionValuenumber | undefinedThe transaction value to check against maxTransactionValue
domainstring | undefinedThe target domain to check against allowedDomains
rateLimitnumber | undefinedCurrent rate count to check against rateLimit
[key: string]unknownCustom context fields for custom constraints

ConstraintViolation

FieldTypeDescription
constraintstringName of the violated constraint
messagestringHuman-readable violation description

Example

import { verifyDelegation, validateConstraints } from "@credat/sdk"; const result = await verifyDelegation(token, { ownerPublicKey }); if (result.valid) { const violations = validateConstraints(result.constraints, { transactionValue: 5000, domain: "api.stripe.com", }); if (violations.length > 0) { console.error("Constraint violations:", violations); // [{ constraint: "maxTransactionValue", message: "5000 exceeds max 1000" }] } }

Notes

  • Returns an empty array if constraints is undefined (no constraints = no violations)
  • Only checks built-in constraints (maxTransactionValue, allowedDomains, rateLimit) against matching context fields
  • Skips checks where the context field is not provided (e.g., no domain in context = skip allowedDomains check)
  • For custom constraints, use the manual approach

Usage pattern

A typical scope check in an API handler:

import { verifyPresentation, hasScope, hasAllScopes } from "@credat/sdk"; async function handleRequest(presentation, challenge) { const result = await verifyPresentation(presentation, { challenge, ownerPublicKey, agentPublicKey, }); if (!result.valid) { return { status: 401, error: "Unauthorized" }; } // Route-level scope check if (!hasScope(result, "api:read")) { return { status: 403, error: "Missing api:read scope" }; } // Operation-level scope check if (operation === "delete" && !hasScope(result, "api:delete")) { return { status: 403, error: "Missing api:delete scope" }; } // Proceed return { status: 200, data: "..." }; }
Last updated on