Skip to content

Authorization for product agents

The requester, reviewer, and acting account may differ. A practical execution contract binds approval to exact work and checks current authority before the effect happens.

By Daniel Ternyak5 min readSources checked September 29, 2026

A finance lead approves twelve invoice reminders. A worker sends the reminders later, using a shared billing connection. Three identities matter: the person requesting the work, the connection performing the send, and the person allowed to approve that connection’s use.

Authorization decides who may perform an operation on particular objects. Approval records agreement to a particular proposal. Neither replaces the other. A prompt telling the agent to respect permissions is not the enforcement layer.

Choose the acting identity explicitly

ModelUseful whenDecision the team must make
Requester’s accessThe agent works inside the person’s existing product accessWhat happens when the session expires or access is revoked?
Agent’s own grantsA shared or scheduled agent performs a bounded team jobWho can grant, use, review, and revoke the agent’s access?
Connected accountThe operation reaches email, CRM, or another serviceWho may direct that connection, and what can that connection do?

Notion documents personal Agent access and separate permissions for Custom Agents. Sharing a Custom Agent can expose work through grants the interacting person does not hold directly. The behavior is a deliberate delegation model, not evidence that every agent should inherit a creator’s credentials. Notion sharing and permissions

Select the model before designing the card. The card should name the destination workspace and recognizable acting account. Credentials stay server-side.

Bind product context on the server

The authenticated session or registered standing rule supplies the tenant and acting identity. Model-generated arguments should not select an arbitrary tenant, impersonated user, or stronger connection.

Every read and write needs the appropriate object-level check. A valid invoice ID only identifies an object; the ID does not grant access. OWASP’s object authorization guidance requires checking access to the requested object, rather than relying on knowing an ID. OWASP API1: broken object level authorization

Search needs the same scope. A correct write check does not fix a search result that revealed another workspace’s customer or balance. Error messages should also avoid exposing restricted objects.

Save the proposal before accepting a decision

A browser approval request should carry a proposal ID and version. The browser should not send new message text and recipients under the same approval ID.

The example below is an illustrative application record, not an SDK schema. A protected server stores the complete messages and locked invoice IDs; the short record exposes references to those stored values.

json
{
  "proposalId": "proposal_184",
  "version": 3,
  "tenantId": "workspace_A",
  "capability": "billing.reminders.send",
  "capabilityVersion": "2",
  "actingConnectionId": "billing_mail_A",
  "selectionId": "locked_selection_184",
  "messageBundleId": "reviewed_messages_184_v3",
  "expiresAt": "2026-10-02T17:00:00Z",
  "requiredReview": "finance_lead",
  "recovery": "Sent email cannot be recalled"
}

An approval record binds the reviewer to version 3. Editing a recipient or message produces version 4 and another review. The exact card fields should come from the saved proposal.

Check authority where the effect happens

A useful commit path performs the following checks with server-owned values:

  1. Load the proposal under the authenticated tenant. Reject a missing, expired, already consumed, or mismatched version.
  2. Confirm the reviewer may approve the named operation through the acting connection.
  3. Recheck the acting connection, capability rollout, and current object permissions.
  4. Read the exact reviewed objects and reject changed eligibility or a changed recipient under the declared stale-state policy.
  5. Reserve the operation’s unique ID, then dispatch the exact approved arguments.
  6. Store per-object results and the external service’s identifiers. Unknown delivery stays unknown until reconciled.

The checks and local writes need a transaction or another mechanism that prevents a change between validation and commitment. An external service cannot usually share that transaction. Use that service’s conditional writes and idempotency support where available, and keep a local operation ledger.

A timeout after an email provider accepts the message is not permission to send again. Look up the existing result using the operation ID or provider receipt. The runtime guide explains duplicate prevention and uncertain outcomes.

Treat background authority as a lifecycle

A schedule stores the owner, actor, scope, limits, rule version, and expiration policy. The worker must resolve current grants at execution; yesterday’s serialized access check is insufficient.

When a creator leaves, pause or reassign the rule according to the chosen identity model. When a connection is revoked, stop further effects through that connection. Disabling a capability should affect workers and API callers as well as the tool menu.

A model-visible tool list narrows the agent’s choices. A feature flag narrows the rollout. A backend policy narrows authority. Keep those responsibilities distinct, and enforce the relevant checks together at execution.

Test the boundaries with adversarial cases

TestExpected product result
Change the invoice ID to another tenant’s invoiceNo data returned and no write
Change message text after approvalVersion mismatch; revised proposal required
Approve as a teammate outside the delegated finance roleDecision rejected
Revoke the connection while review is pendingNo send; a visible blocked result
Disable the send capability during a runFurther sends blocked where enforceable; completed sends retained
Replay the same approval twiceSame recorded operation; no duplicate email
Put an instruction to send elsewhere inside an invoice noteNote treated as data; no broader authority

Prompt injection means untrusted content tries to instruct the agent. Permission checks limit effects but do not establish that an authorized send is wise. The proposal, human review, data handling, and evaluation cases still need their own checks.

Skills and the capability platform covers shared ownership and rollout. Proactive rules covers the limits that survive a long-running job.

The pattern#