> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runlayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Access Control Recipes

> Copy-paste policies for agent accounts, connectors, agents, skills, plugins, artifacts, teams, and organization permissions.

> [!WARNING]
>
> **Early Access Feature**: Policies beyond connectors are in early access and are not enabled for workspaces by default. Contact your Runlayer team to turn them on. Until then, only the connector recipes marked as working without early access apply.

Practical recipes for the most common access patterns. For how connector policies work, see [Connector Access Control](https://docs.runlayer.com/platform-policies.md). For every other resource type and the full list of actions, see [Agents, Skills, and More](https://docs.runlayer.com/access-control-resources.md).

## Prerequisites

* A Runlayer instance (referred to as `RUNLAYER_URL` below)
* A user API key, created in **Settings → Personal API keys**. Each recipe says whose key it needs
* `curl` and `jq` installed

```bash theme={null}
export RUNLAYER_URL="https://your-runlayer-instance.com"
export API_KEY="rl_..."  # User API key from Settings → Personal API keys
```

The recipes send policies through one helper, which reads the policy body from standard input:

```bash theme={null}
create_policy() {
  curl -s -X POST "$RUNLAYER_URL/api/v1/policies" \
    -H "x-runlayer-api-key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d @- | jq '{id, principal, effect, resource, actions}'
}
```

### Find the IDs you need

Policies name people, groups, and resources by ID. Look them up once and export them:

```bash theme={null}
# A person, by email
export USER_ID=$(curl -s "$RUNLAYER_URL/api/v1/users/?search=dana@example.com" \
  -H "x-runlayer-api-key: $API_KEY" | jq -r '.data[] | select(.email == "dana@example.com") | .id')

# A group, by name
export GROUP_ID=$(curl -s "$RUNLAYER_URL/api/v1/groups" \
  -H "x-runlayer-api-key: $API_KEY" | jq -r '.data[] | select(.name == "Support") | .id')

# An agent account, by name
export AGENT_ACCOUNT_ID=$(curl -s "$RUNLAYER_URL/api/v1/agent-accounts/" \
  -H "x-runlayer-api-key: $API_KEY" | jq -r '.data[] | select(.name == "billing-sync") | .id')
```

Looking up people and groups needs the **View user info** permission, which most admin roles have. Without it, ask an administrator for the IDs. Connector, agent, skill, plugin, artifact, and team IDs are in the URL when you open the resource in Runlayer, for example `/agents/<agent-id>`. Tool names in the connector recipes are examples; use the names listed on your connector's page.

> [!NOTE]
>
> An administrator with the security-policies permission can run every recipe, except that organization recipes also need them to hold the permission being granted or denied. Recipes on agents, skills, plugins, and artifacts can also be run by the resource's owner, or by anyone with `share` on it for the actions they hold themselves.

***

## Agent Accounts

Agent account recipes are written by an administrator with the security-policies permission: agent accounts aren't shareable, so their owners can't grant access to them. Each grant covers one account, or every account with `"all": true`.

### Let a person manage one account's security settings

**Scenario**: Dana runs the billing integration. She should be able to turn on DPoP, change the account's [server scoping](https://docs.runlayer.com/platform-agent-accounts.md#resource-scoping-enforcement), and adjust token lifetimes for the `billing-sync` account, without becoming an agent account administrator.

`edit_security` covers every security setting, and needs `edit` alongside it.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "user", "ids": ["$USER_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent_account", "ids": ["$AGENT_ACCOUNT_ID"] },
  "actions": ["view", "edit", "edit_security"],
  "description": "Dana manages security settings for billing-sync"
}
EOF
```

Dana can now change the account's security settings in **Settings → Agent Accounts**, or with her own API key:

```bash theme={null}
curl -s -X PATCH "$RUNLAYER_URL/api/v1/agent-accounts/$AGENT_ACCOUNT_ID" \
  -H "x-runlayer-api-key: $DANA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"require_dpop": true, "enforce_audience": true}' | jq '{id, require_dpop, enforce_audience}'
```

She can't change the account's identity attributes, which stay with agent account administrators, or rotate its secret.

> [!NOTE]
>
> Connector security settings, such as ToolGuard scanning for a connector, come with the **Manage security policies** permission and can't be granted on a single connector. To give one person control over how an agent account authenticates to its connectors, grant `edit_security` on the account as shown here. To let them choose which connectors it uses, grant `edit_permissions` ([below](#agent-account-edit-permissions)).

### Let on-call rotate an account's credentials

**Scenario**: The **Platform On-Call** group must be able to [rotate the secret](https://docs.runlayer.com/platform-agent-accounts.md#credential-rotation) of the `billing-sync` account during an incident, and nothing else.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$ONCALL_GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent_account", "ids": ["$AGENT_ACCOUNT_ID"] },
  "actions": ["view", "rotate_credentials"],
  "description": "On-call can rotate billing-sync credentials"
}
EOF
```

A member of the group rotates with their own API key. The old secret stops working immediately, and the new one is returned once:

```bash theme={null}
curl -s -X POST "$RUNLAYER_URL/api/v1/agent-accounts/$AGENT_ACCOUNT_ID/rotate-credentials" \
  -H "x-runlayer-api-key: $ONCALL_API_KEY" | jq -r '.client_secret'
```

An account that backs a Runlayer agent is rotated from the agent instead; the endpoint above answers `400` and names the agent.

> [!WARNING]
>
> The new secret lets whoever holds it act as the account. Grant `rotate_credentials` only to people you would trust with the account's credentials.

### Let a team lead add connectors to an account

**Scenario**: Sam owns the `support-bot` account's integrations. He should decide which connectors and tools it can use, without changing its security settings.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "user", "ids": ["$SAM_USER_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent_account", "ids": ["$AGENT_ACCOUNT_ID"] },
  "actions": ["view", "edit_permissions"],
  "description": "Sam manages support-bot's connectors"
}
EOF
```

Sam can now [add a connector](https://docs.runlayer.com/platform-agent-accounts.md#who-can-add-a-connector) to the account in **Settings → Agent Accounts**, or with a connector policy naming the account:

```bash theme={null}
curl -s -X POST "$RUNLAYER_URL/api/v1/policies" \
  -H "x-runlayer-api-key: $SAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "principal": { "type": "agent", "ids": ["'$AGENT_ACCOUNT_ID'"] },
    "kind": "permission",
    "action": "allow",
    "scope": { "servers": ["'$SERVER_ID'"], "tools": ["search_tickets", "get_ticket"], "resources": "*" },
    "description": "support-bot can read Zendesk tickets",
    "conditions": []
  }' | jq '{id, principal, action, scope}'
```

Unless Sam administers agent accounts or connectors, or owns the connector, he can only give the account tools he can call himself, and can give it resources only if he can read every resource on the connector himself. **All tools** is saved as that list.

### Keep an owner from changing security settings or rotating

**Scenario**: Every agent account owner can change their account's security settings and rotate its secret. Your security team wants those two actions to stay with them for the production accounts.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "owner" },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "agent_account", "ids": ["$PROD_ACCOUNT_ID_1", "$PROD_ACCOUNT_ID_2"] },
  "actions": ["edit_security", "rotate_credentials"],
  "description": "Production accounts: security settings and rotation stay with Security"
}
EOF
```

Owners keep every other action. The deny names owners, so administrators and people you grant these actions to, as in the recipes above, keep them on accounts they don't own. It doesn't reach an account linked to a Runlayer agent: the agent's owner rotates that secret from the agent.

### Give the SOC an emergency off switch for every account

**Scenario**: The **SOC** group must be able to disable any agent account when it sees suspicious activity, but re-enabling should stay with the account's owner and the people who manage its security.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$SOC_GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent_account", "all": true },
  "actions": ["view", "edit"],
  "description": "SOC can disable any agent account"
}
EOF
```

`edit` covers disabling. Re-enabling needs `edit_security`, so the SOC can't undo its own decision or someone else's. To disable an account:

```bash theme={null}
curl -s -X PATCH "$RUNLAYER_URL/api/v1/agent-accounts/$AGENT_ACCOUNT_ID" \
  -H "x-runlayer-api-key: $SOC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false, "disabled_reason": "Unusual call volume, INC-4211"}' | jq '{id, is_active}'
```

An account linked to a Runlayer agent can't be disabled this way: the request answers `400` and names the agent. See [Respond to a compromised agent](https://docs.runlayer.com/platform-agent-accounts.md#compromised-agent) for what to do next.

***

## Connectors

Connector policies are written by administrators with the security-policies permission. Once early access is on, someone granted `share` on the connector can also run the team and rate-limit recipes and the organization-wide allow, within the actions they hold. The recipes naming groups need the security-policies permission. The connector recipes below work the same way as [connector policies](https://docs.runlayer.com/platform-policies.md#access-rule-examples); this format adds team and organization principals, rate limits, and a single format across resources.

### Let a team use a connector

**Scenario**: Everyone on the **Data Platform** [team](https://docs.runlayer.com/platform-teams.md) should be able to use the Snowflake connector, including people who join the team later.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "team", "ids": ["$TEAM_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["view", "use", "call_tool:*", "read_resource:*"],
  "description": "Data Platform team uses Snowflake"
}
EOF
```

### Let everyone use a connector except contractors

**Scenario**: The whole organization uses the Notion connector, except the **Contractors** group.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "org" },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["view", "use", "call_tool:*", "read_resource:*"],
  "description": "Everyone uses Notion"
}
EOF

create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$CONTRACTORS_GROUP_ID"] },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["view", "use", "call_tool:*", "read_resource:*"],
  "description": "Contractors can't use Notion"
}
EOF
```

The deny wins for contractors whatever other allows match them. The deny on its own also works without early access.

### Give a group read-only tools

**Scenario**: The **Support** group can look up GitHub issues but not open or close them. This recipe also works without early access.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["view", "use", "call_tool:search_issues", "call_tool:get_issue", "read_resource:*"],
  "description": "Support can read GitHub issues"
}
EOF
```

### Cap how often a connector is called

**Scenario**: Nobody, person or agent account, should send more than 100 Salesforce tool calls an hour.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "any" },
  "kind": "rate_limit",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["call_tool:*"],
  "rate_limit": { "max_calls": 100, "window": "hour", "per": "user" },
  "description": "100 Salesforce calls per hour per user"
}
EOF
```

`any` covers agent accounts acting on their own; `org` covers only people, and agents acting for them. Use `"per": "session"` to cap a single agent run or chat instead, or `"per": "org"` for one shared budget. Refused calls appear in the [audit log](https://docs.runlayer.com/platform-audit-logs.md) as **Tool Call Rate Limited**.

### Require approval for a risky tool

**Scenario**: Every Stripe refund waits until the person it runs for approves it. [Approval rules](https://docs.runlayer.com/platform-policies.md#human-approval) are in beta; see [Who approves](https://docs.runlayer.com/platform-agents.md#hitl).

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "any" },
  "kind": "approval_requirement",
  "resource": { "type": "connector", "ids": ["$SERVER_ID"] },
  "actions": ["call_tool:create_refund"],
  "description": "Refunds need approval"
}
EOF
```

***

## Agents

The agent's owner, or anyone with `share` on it, can run these recipes. The share dialog's **Can use** and **Can edit** levels write the same policies for you.

### Let a group run an agent without editing it

**Scenario**: The **Support** group uses the **Ticket Triage** agent but shouldn't change its instructions or tools.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent", "ids": ["$AGENT_ID"] },
  "actions": ["view", "run"],
  "description": "Support runs Ticket Triage"
}
EOF
```

Running the agent still needs access to the connectors it uses. See [Agents](https://docs.runlayer.com/platform-agents.md) for how connector access applies to runs. Add `copy` to let them make personal copies in Runlayer Go; the share dialog's **Can use** level includes it.

### Add a co-maintainer who can't re-share

**Scenario**: Priya helps maintain the agent. She should edit it, but not decide who else gets access. The **Editor** preset includes `share`, so list the actions instead.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "user", "ids": ["$PRIYA_USER_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "agent", "ids": ["$AGENT_ID"] },
  "actions": ["view", "run", "edit"],
  "description": "Priya co-maintains Ticket Triage"
}
EOF
```

### Keep one person out of an agent shared with everyone

**Scenario**: The **Expense Helper** agent is shared with the whole organization, but an intern shouldn't run it.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "user", "ids": ["$USER_ID"] },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "agent", "ids": ["$AGENT_ID"] },
  "actions": ["run"],
  "description": "Interns can't run Expense Helper"
}
EOF
```

The agent may still appear in their agent list; running it answers `403`. The agent's owner can deny anyone. Someone with `share` can deny only named users or agent accounts who don't own the agent, and only actions they hold themselves.

***

## Skills and Plugins

The skill or plugin's owner, or anyone with `share` on it, can run the single-resource recipes. Recipes that use `"all": true` need an administrator.

### Roll out a skill to a team

**Scenario**: The **Code Review** skill should be available to everyone on the **Platform** team.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "team", "ids": ["$TEAM_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "skill", "ids": ["$SKILL_ID"] },
  "actions": ["view", "use"],
  "description": "Platform team uses Code Review"
}
EOF
```

Choose whether shared skills sync to members' devices in the team's **Device sync** setting. See [Teams](https://docs.runlayer.com/platform-teams.md#share-and-use-assets).

### Offer a plugin by department

**Scenario**: Everyone whose identity provider lists them in Engineering should get the **Engineering Toolkit** plugin, including people hired later.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "attributes", "attributes": { "department": "Engineering" } },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "plugin", "ids": ["$PLUGIN_ID"] },
  "actions": ["view", "use"],
  "description": "Engineering uses the Engineering Toolkit"
}
EOF
```

Attributes match exactly, so `Engineering` doesn't match `engineering`. The plugin's connectors keep their own policies.

### Block a group from every skill

**Scenario**: The **Contractors** group shouldn't use any skill, including skills shared with the whole organization.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$CONTRACTORS_GROUP_ID"] },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "skill", "all": true },
  "actions": ["use"],
  "description": "Contractors can't use skills"
}
EOF
```

Swap `skill` for `plugin` to do the same for plugins.

***

## Artifacts

The artifact's owner, or anyone with `share` on it, can run these recipes. See [Sharing artifacts](https://docs.runlayer.com/artifacts/sharing.md) for the share dialog.

### Let a group download a report

**Scenario**: The **Finance** group needs to open and download the quarterly spend report an agent produced.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$FINANCE_GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "artifact", "ids": ["$ARTIFACT_ID"] },
  "actions": ["view", "download"],
  "description": "Finance downloads the Q3 spend report"
}
EOF
```

### Let a teammate manage who sees an artifact

**Scenario**: Alex takes over distribution of the report. He should edit it, share it, and change or remove access others granted. This is the **Manager** preset.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "user", "ids": ["$ALEX_USER_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "artifact", "ids": ["$ARTIFACT_ID"] },
  "actions": ["view", "download", "edit", "share", "manage_access"],
  "description": "Alex manages the Q3 spend report"
}
EOF
```

***

## Teams

Team membership and adding assets to a team follow [team roles](https://docs.runlayer.com/platform-teams.md#team-roles-and-asset-access). In policies, a team is most useful as a principal: grant a team access once and everyone who joins later gets it.

### Give a team access to everything it works with

**Scenario**: The **Data Platform** team uses one agent, one skill, and one connector. Name the team in each policy instead of its members.

```bash theme={null}
grant_team() {  # grant_team <resource type> <resource id> <actions as a JSON list>
  create_policy <<EOF
{
  "principal": { "type": "team", "ids": ["$TEAM_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "$1", "ids": ["$2"] },
  "actions": $3,
  "description": "Data Platform team: $1 access"
}
EOF
}

grant_team agent "$AGENT_ID" '["view", "run"]'
grant_team skill "$SKILL_ID" '["view", "use"]'
grant_team connector "$SERVER_ID" '["view", "use", "call_tool:*", "read_resource:*"]'
```

When someone joins or leaves the team, directly or through a [group added to the team](https://docs.runlayer.com/platform-teams.md#manage-membership-with-groups), their access follows.

### Keep a group out of team management

**Scenario**: Some contractors hold a role that includes team management, but they shouldn't create or manage teams.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$CONTRACTORS_GROUP_ID"] },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "org" },
  "actions": ["create_team"],
  "description": "Contractors can't manage teams"
}
EOF
```

`create_team` is part of the broader team-management permission, so the deny removes all of it. See [Organization permissions](https://docs.runlayer.com/access-control-resources.md#organization-permissions).

***

## Organization Permissions

Organization recipes are written by an administrator with the security-policies permission who holds the permission being granted or denied. They change one permission for specific people without changing their role.

### Let compliance read every audit log

**Scenario**: The **Compliance** group reviews [audit logs](https://docs.runlayer.com/platform-audit-logs.md) across the organization, but shouldn't get the rest of the Security Admin role.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$COMPLIANCE_GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "org" },
  "actions": ["view_audit_logs_all"],
  "description": "Compliance reads every audit log"
}
EOF
```

Redacted content stays redacted. Add `view_unredacted_content` only if they need to see it.

### Let finance export usage data, by department

**Scenario**: Anyone in the Finance department exports usage data for chargeback.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "attributes", "attributes": { "department": "Finance" } },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "org" },
  "actions": ["export_usage_data"],
  "description": "Finance exports usage data"
}
EOF
```

### Let IT reassign resources when someone leaves

**Scenario**: The **IT Helpdesk** group transfers agents, skills, and other resources from people who leave the company.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$HELPDESK_GROUP_ID"] },
  "kind": "permission",
  "effect": "allow",
  "resource": { "type": "org" },
  "actions": ["transfer_resource_ownership"],
  "description": "Helpdesk transfers ownership during offboarding"
}
EOF
```

### Stop a group from creating agents

**Scenario**: The **Contractors** group can use agents shared with them, but shouldn't build their own.

```bash theme={null}
create_policy <<EOF
{
  "principal": { "type": "group", "ids": ["$CONTRACTORS_GROUP_ID"] },
  "kind": "permission",
  "effect": "deny",
  "resource": { "type": "org" },
  "actions": ["create_agent"],
  "description": "Contractors can't create agents"
}
EOF
```

Creating an agent, or a personal copy of one, answers `403`. They keep using agents shared with them, through their [agent policies](#agents), and keep creating artifacts. To take agents away entirely, deny `use_agents` instead.

> [!NOTE]
>
> Organization permission changes can take up to five minutes to reach every request. You can't change or remove an organization deny that applies to you unless you hold `manage_admins`.

***

## Review and Undo

List the policies on one resource, and delete one you no longer need. Listing needs the security-policies permission.

```bash theme={null}
# Policies on one agent account
curl -s "$RUNLAYER_URL/api/v1/policies?resource_type=agent_account&resource_id=$AGENT_ACCOUNT_ID" \
  -H "x-runlayer-api-key: $API_KEY" | jq '.data[] | {id, principal, effect, actions, description}'

# Change a policy's actions
curl -s -X PUT "$RUNLAYER_URL/api/v1/policies/$POLICY_ID" \
  -H "x-runlayer-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"actions": ["view", "edit"]}' | jq '{id, actions}'

# Delete a policy
curl -s -X DELETE "$RUNLAYER_URL/api/v1/policies/$POLICY_ID" \
  -H "x-runlayer-api-key: $API_KEY"
```

Every change is recorded in the [audit log](https://docs.runlayer.com/platform-audit-logs.md) as a policy event.

## Troubleshooting

| Response | Cause | Fix |
| - | - | - |
| `409` `unified_policy_engine_inactive` | Early access isn't turned on for your workspace | Contact your Runlayer team, or use a connector recipe that works without early access |
| `403` | You don't have the security-policies permission, `share` on the resource, or the actions you're granting. Before early access, owners and people with `share` may get `403` instead of `409` | Ask the resource's owner or an administrator |
| `400` mentioning a super admin | The change would leave no super admin able to manage admins and policies | Keep at least one super admin outside the deny |
| `400` `target not found` | A resource ID doesn't exist in your organization | Check the ID in the resource's URL |
| `422` | The body doesn't match the policy shape, for example `"ids": ["*"]` or an `agent_account` principal | Use `org` or `any` for everyone, and `agent` for agent accounts |

## Related Documentation

* [Connector Access Control](https://docs.runlayer.com/platform-policies.md) - Connector policies, conditions, and approvals
* [Agents, Skills, and More](https://docs.runlayer.com/access-control-resources.md) - Every resource type, its actions, and who can write policies
* [Agent Accounts](https://docs.runlayer.com/platform-agent-accounts.md) - Identities for autonomous agents and services
* [Agent Account Authentication Recipes](https://docs.runlayer.com/cookbook-agent-accounts.md) - Tokens, delegations, and session grants
* [Teams](https://docs.runlayer.com/platform-teams.md) - Sharing resources with groups of people


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.