---
title: Principal and Application
description: Applications, users, and the session-bound identities that act on their behalf.
pageType: concept
keywords: [principal, application, credential type, DCR, session, identity, client secret]
---

A **principal** is the identity that acts in Caracal. At token-exchange time, the principal is always an **application** — a registered client that presents credentials to the STS to obtain a mandate. This page explains how applications are structured, how they authenticate, and how the principal appears in policy input.

## What an application is

An application is a Caracal-registered client within a zone. It represents a service, agent process, automation script, or any other system that exchanges credentials for mandates. Applications belong to exactly one zone.

Applications are stored in the `applications` table with these attributes:

| Field | Description |
| ----- | ----------- |
| `id` | UUID; the `application_id` carried in mandates as `client_id` |
| `zone_id` | The zone this application belongs to |
| `name` | Human-readable label |
| `registration_method` | `"managed"` (created via API) or `"dcr"` (Dynamic Client Registration) |
| `credential_type` | How the application authenticates; see below |
| `traits` | Optional string tags used in policy decisions |
| `consent` | Whether user consent is required for this application |

## Credential types

The `credential_type` field determines how the STS authenticates the application at token exchange:

| Type | Description |
| ---- | ----------- |
| `token` | Bearer token exchanged for a mandate — the default for machine clients |
| `password` | Client ID + secret (OAuth 2.0 client credentials) |
| `public-key` | Asymmetric key assertion |
| `url` | Callback URL-based assertion |
| `public` | No client authentication — for public clients |

For most agent workloads, `token` or `password` are the appropriate choices.

## How the application authenticates

At token exchange (`POST /oauth/2/token`), the application presents its credentials in one of:

- `client_secret` form field — symmetric secret stored as a hash in the database
- `client_assertion` form field — signed assertion for public-key clients

The STS looks up the application by `application_id` and `zone_id`, verifies the credential, and then proceeds to OPA evaluation. No mandate is issued before the application credential is validated.

## The principal in policy input

When the STS runs an OPA evaluation, the `input.principal` object represents the authenticated application:

```json
{
  "principal": {
    "type": "application",
    "id": "app-uuid",
    "zone_id": "zone-uuid",
    "credential_type": "token",
    "agent_session_id": "session-uuid"
  }
}
```

Policies can gate on any of these fields. The `id` is the application UUID; use it when writing policies that restrict access to specific applications. The `agent_session_id` links to the agent session in the Coordinator, useful for policies that gate on session state.

## The `traits` field

Applications have an optional `traits` string array. Traits are arbitrary labels — for example, `["trusted-internal", "finance-team"]` — that the application carries into the OPA input via `actor_claims`. Policies can inspect traits to grant broader access to specific application categories without hardcoding UUIDs.

## Users and grants

Caracal does not include a built-in user directory. A `user_id` is an opaque string passed by the calling application; Caracal stores it in the grant but does not validate it against any identity provider.

A **grant** binds a `(application_id, user_id, resource_id)` triple to a set of scopes, representing that the specified application is authorized to access the resource on behalf of the specified user. Grants are the connection point between an application and a resource — without a grant, the application has no access to the resource regardless of policy.

In a typical agent workflow, the `user_id` in a grant represents the end user who delegated the agent to act on their behalf. The agent application holds the grant; the user identity is carried for audit and policy purposes.

## Dynamic Client Registration

If the zone has `dcr_enabled = true`, applications can be registered dynamically via RFC 7591 Dynamic Client Registration. DCR-registered applications go through the same OPA evaluation as managed applications.

## What a principal is not

The `principal` in Caracal always identifies an application at the time of token exchange, not a human user. Human users are represented indirectly through grants that bind a `user_id` to an application's access rights. The human's identity is present in the OPA context via `actor_claims` if a user session token is carried, but the principal type is still `"application"`.

## Next steps

- [Zone](./zone/) — the tenancy boundary each application belongs to
- [Resource and Grant](./resource-grant/) — how grants bind applications to resource access
- [Policy](./policy/) — using `input.principal` in policy rules
