Verentis

Identities & tokens

Identities, service principals & tokens

Who your extension acts as, how it gets a short-lived scoped token, and how permissions are enforced.

Verentis secures every call with short-lived, scoped access tokens. Understanding identities and tokens is essential to building an extension that can do its job — and no more.

Identities

Different callers act as different kinds of identity:

User

A human, signed in via OAuth/OIDC. Apps act on behalf of the signed-in user.

Service principal

A non-human identity for automation. Engine runs and background work act as a service principal — for example a workspace service provisioned to run an engine on a schedule or trigger.

App / OAuth client

An app with its own OAuth client identity (declared in its manifest) so it can request tokens and define its own scopes.

Access tokens are scoped

A token is not "all-or-nothing": it carries exactly the scopes that were both requested and granted. A scope is a fine-grained permission such as node.file.read or node.node.create. Your extension declares the permissions it needs; the platform mints a token limited to those.

Least privilege

Request only the scopes you use. Tokens are short-lived and audience-scoped, so a leaked token has a small blast radius — and admins are more likely to consent to a tightly-scoped extension.

How an extension gets a token

App (runtime). When your app runs in a workspace iframe, the platform injects short-lived tokens through the SDK bridge. You never see long-lived credentials; you call getToken()-style SDK APIs and the bridge returns a token scoped to the user and the app's granted permissions.

App (standalone development). While developing outside the platform, authenticate with an API key and exchange it for an access token. Same API surface, different bootstrap. See Authentication.

Execution engine. For each run, Verentis mints an engine token scoped to what the engine declared it needs and to the run's context (workspace, and where relevant the file/node boundary). The engine uses it via its language SDK to read inputs and write outputs.

Permissions vs. scopes vs. capabilities

Manifests express what an extension needs in a few related ways:

permissionsstring[]

The platform scopes the extension requires (e.g. node.file.read, node.node.create). These map to grants and bound the minted token.

scopesstring[]

Custom scopes the extension defines and registers in the catalog (e.g. smart-editor.document.export), so other callers can be granted them — enabling app-to-app and service-to-app authorization.

capabilitiesstring[]

Higher-level declarations of intent (e.g. file:read, file:write) used for display and coarse policy; back them with the matching permissions.

Requesting a permission doesn't grant it. Apps go through a consent step on install where an admin approves the requested permissions and scopes before the extension becomes active.

Next