Descles documentation
The organization layer for AI agents
Descles has two parts. The edge is an open-source gateway you run in your network: agents send their model calls and tool calls through it, it holds your provider keys and tool credentials, enforces policy and approvals, and records what happened. For teams, the control plane manages identities, delegation from admins to members to agents, and policy, and signs them into a bundle the edge pulls. You run it too, next to the edge: nothing is hosted by Descles. On top of both: organization context shared between agents, and skills mined from agent runs.
Overview
| You run | One edge in your network, with your provider keys and tool credentials. |
|---|---|
| You change | Each agent's base URL and MCP URLs point at the edge, and it authenticates with a Descles agent key. |
| Descles receives | Nothing. The edge and the Team control plane run on your infrastructure and report nothing to Descles; the paid parts check an offline, signed license. |
Run Descles in your network (the edge)
An organization runs one edge, or one per network or region; nobody installs one per person. The source, signed releases and the full list of metadata the edge reports are at github.com/chiatzenw-cur/descles.
go install github.com/chiatzenw-cur/descles/cmd/descles@latest # CLI: edge init/up, connect, doctor, approvals
| Standalone | No Descles account. Agent keys are hashes in a file and policy is a YAML file. The edge sends no reports to Descles; requests still reach the model providers and tool servers you configure. |
|---|---|
| Team | The edge pulls a signed, time-limited bundle of identities, grants and policy from your own control plane about every 30 seconds, and reports nothing. Provider keys, prompts, tool results and records stay on the edge. |
# standalone descles edge init --dir my-edge --providers anthropic # prints an agent key once echo "$ANTHROPIC_API_KEY" > my-edge/config/secrets/anthropic-key descles edge up --dir my-edge # docker compose up + health check
For org admins
- Run the Team control plane (delivered to design partners as an image with an offline license) behind your internal TLS ingress, for example
https://control.internal. Create the organization with its admin token:POST /control/orgs {"name":"Acme","slug":"acme"}. - Create the edge's sync token, which can only fetch bundles:
POST /control/orgs/<org>/keys {"scopes":["edge.sync"]}, and read the key that signs your bundles atGET /edge/bundle-key. Check it over a trusted channel before pinning it. - Deploy:
descles edge init --mode selfhost --control-plane https://control.internal --org <org> --bundle-key <key>, put the token inconfig/secrets/report-token(a legacy name; nothing is reported) and your provider key next to it, thendescles edge up. Put your TLS ingress in front of it; remote members reach it over your VPN or an authenticated entry point. - Set the policy (the same YAML as below) with
POST /control/policy, and give each member's agent an identity and a key:POST /control/orgs/<org>/agents, thenPOST /control/agents/<id>/keys.POST /control/agents/<id>/revoketakes one away. - Approvals are decided on the edge at
/admin/with its admin token, where the arguments are shown. A revocation takes effect at the edge's next refresh; an edge that cannot reach the control plane stops accepting calls when its bundle expires (10 minutes by default). The edge's ownpolicy.yamlstays a floor the control plane can tighten but never loosen.
For members
Get an agent key from your admin. Then point your agent at your company's edge; nobody installs an edge of their own:
| Endpoint only | Set the base URL (ANTHROPIC_BASE_URL=https://descles.internal/anthropic or OPENAI_BASE_URL=https://descles.internal/v1) and your agent key, and point MCP clients at https://descles.internal/mcp/<connector>. Model calls and company tools are then governed. Nothing to install. |
|---|---|
| With the CLI | descles connect claude-code|codex|hermes --edge https://descles.internal --key <key> writes the settings for you and installs hooks, so Claude Code and Hermes check shell and file actions with the edge before they run. descles doctor checks that nothing bypasses the edge. Codex has no pre-execution hook. |
Organization context and skills
Context. On the enterprise edge, extractors turn tool results into facts about your customers, people and projects, each with its source, the agent or sync that produced it, and the labels you assign to that source, which decide who may read it. Facts come from two places: calls agents make, and a scheduled sync that reads whole systems through the edge's own connectors (for example every account in the CRM, paged, hourly). The sync runs as system:sync under your organization policy; a tool that needs approval is refused. Unchanged records do not add history. Agents read facts with org_context, org_search and org_why, filtered to their clearance. Everything stays in your network.
Skills. Descles imports agent runs from the edge's records, finds the steps they repeat, and drafts a procedure. The edge never records arguments, so a person binds them and approves the draft; nothing runs before that, and an edited procedure must be reviewed again. The reviewed procedure is written two ways: a skill (instructions a model follows) and a workflow (steps run with no model). Both run through the edge, where policy and approvals still apply. Measured results.
Console
Each edge serves its own console at https://<your-edge>/admin/, behind the edge's admin token: pending approvals, recent activity, the policy in effect (with a check and a replay of recent calls), and on the enterprise edge the organization context and how its sync is doing. There is no hosted console.
Pending approvals, with the arguments an approver needs to see, are decided on the edge itself at https://<your-edge>/admin/ with the edge's admin token, or with descles approvals list | approve <id> | deny <id>. The edge can also notify approvers through a webhook such as Slack (DESCLES_EDGE_APPROVAL_WEBHOOK_FILE); the notice carries the tool and agent, not the arguments.
Policy — writing rules
Policy decides what an agent may do with the tools it proposes. The edge evaluates it on every model call, MCP call and hooked shell or file action, before anything executes:
deny— the tool call is stripped from the model response; the runtime never sees it.require_approval— the call is replaced with a pending-approval placeholder and an approval is opened for an operator.allow(or no rule) — the call passes.
Most-restrictive wins: deny > require_approval > allow. Tool names are matched with . and _ normalized (shell.rm matches what providers may emit as shell_rm), and trailing * wildcards are supported.
# policy.yaml — YAML or JSON. Serve it with DESCLES_POLICY_FILE on startup
# or edit it live in the console (Policy page). JSON inline via DESCLES_POLICY.
defaults:
tools:
shell.rm: deny # nobody deletes files through an agent
service.delete: deny
require_approval:
- github.create_issue # always ask a human first
budget:
daily_usd: 10 # default daily spend cap per agent
groups: # group-wide rules (group = your Agents page
backend: # groups: team or person containers)
tools:
shell.kubectl.delete: require_approval
shell.kubectl.rollout: require_approval
budget:
daily_usd: 25
agents: # per-agent overrides — highest precedence
backend-deploy-bot: # (the agent id from your console)
tools:
deploy_to_prod: allow # explicit allow overrides the group rule
budget:
daily_usd: 50Precedence: agent rules > the agent’s group rules > defaults. An explicit allow at a higher layer overrides a deny/approval below it; within one layer, deny beats approval. Unlisted tools are allowed.
Argument-scoped rules (arg_tools)
Rules inside arg_tools match a tool call’s arguments, not just its name — the finest grain wins. They are evaluated before the plain tools rules of the same layer, and they inherit the same layer precedence (agent > group > defaults) and allow-override semantics. Each entry lists a tool, glob patterns per argument key (path, command, query, url, … — any key the runtime sends), and a decision:
defaults:
tools:
read_file: allow # plain rule: reading is fine…
arg_tools:
- tool: read_file # …but these paths are never readable
args:
path: ["**/.env", "**/secrets/**"]
decision: deny
- tool: terminal
args:
command: ["rm -rf*"] # destructive shells always ask a human
decision: require_approval
agents:
deploy-bot:
arg_tools:
- tool: terminal # a finer allow at the top layer wins
args:
command: ["git push*"]
decision: allowMatching: * matches any run of characters; a leading **/ matches any directory depth (**/.env also matches a bare .env). A rule matches when every listed argument key matches at least one of its globs; if the argument is missing or structured, its compact JSON form is matched. Among several matching argument rules, deny > require_approval > allow.
Caveat: argument matching on shell command strings is best-effort — rmdir, cd x && rm *, aliases and escapes all dodge a string glob, so treat a command deny as a speed bump, not a wall. Denies on structured keys like path / url are reliable; for a hard execution boundary use a sandbox or an action gateway.
Per-tool status labels
The console’s tool inventory (Policy page) labels each declared or used tool with the state of its effective defaults-layer rules:
- allowed — no rule (or an explicit allow) applies; calls pass unless a lower/higher layer says otherwise.
- approval — a plain
require_approvalrule holds every call for a human. - denied — a plain deny rule blocks every call; the runtime never sees it.
- partial — argument-scoped (
arg_tools) rules refine the tool: the plain disposition may be allow/approval but specific argument globs (e.g.read_fileallow +**/.envdeny) decide per call.
Status is computed from the defaults layer of the effective policy; per-agent overrides in agents can still change the outcome for a specific key. Skills declared by your runtime are just tools with skill names — they get the same status treatment as any other tool.
Tool names are runtime-specific
Rules match the tool names your agent actually declares — Descles does not invent names. If your agent’s tools are terminal, execute_code, web_search (e.g. a Hermes-style runtime), a rule for shell.rm governs nothing. Starter presets for common runtimes:
# Claude Code / Anthropic-style tools
defaults:
tools:
Bash: require_approval # name is exactly what the tool declares
Read: allow
Edit: require_approval
Write: deny
WebFetch: allow
require_approval:
- Bash
- Edit
# Hermes-style / Codex-style tools
defaults:
tools:
terminal: require_approval
execute_code: deny
web_search: allow
read_file: allow
patch: require_approvalMatching is exact after normalizing . and _ as the same separator (a rule for shell.rm also matches a tool named shell_rm). There is no fuzzy matching — an unknown spelling simply does not match, so a typo’d rule is silently inert. Check the Now in effect card after applying to confirm the rules you intended are live.
DESCLES_POLICY_FILE.Self-hosting
Self-hosting means running the edge. It is public: install the CLI with go install github.com/chiatzenw-cur/descles/cmd/descles@latest, or deploy the container image ghcr.io/chiatzenw-cur/descles-edge by digest. Releases are signed with cosign, carry build provenance and an SBOM, and rebuild bit-for-bit from the source; how to verify a release. The provider still receives the requests you route to it.
What each control covers
| Model traffic | Routed by the edge to your provider, attributed to the agent, budgeted, recorded. |
|---|---|
| Tool calls a model proposes | Denied or held before the runtime receives them. |
| MCP tools | Executed by the edge with a credential only it holds, after policy and any approval. |
| Shell and file actions | Checked before they run in Claude Code and Hermes through hooks; not in Codex. Guardrails, not a sandbox. |
| Everything else | Direct SaaS or API calls that do not go through the edge are outside what Descles governs. |
Security model
- Identity — every agent key is bound to an agent (a member or a service); attribution comes from the key, never from client headers. The edge accepts a key only if the signed bundle it pulled lists it.
- Data boundary — prompts, responses, tool arguments and provider keys stay on the edge. The edge reports only listed metadata, and it is open source so you can check.
- Tenant isolation — your org sees only its own members, agents, policy and reported metadata; platform views (signups, audit chain) stay with Descles.
- Tool policy — policy can strip a denied tool call from the model response or replace it with a pending-approval placeholder before the runtime ever executes it.
- Audit chain — governance events append to a signed hash chain; tampering breaks verification.
What Descles should remember for the company
Descles records grants, policy decisions, approvals and execution status, keeps organization context that agents share within their clearance, and turns repeated work into skills a person reviews (see Context and skills). An MCP call marked succeeded means the upstream call returned successfully, not that the business goal succeeded; outcomes are measured separately, from labels you record or a checker you run.
Proposed, not shipped: suggestions for policy rules based on repeated human decisions; skills with branches and native-tool steps; inheriting read permissions from source systems; and one-time approval of a bounded plan. Rule changes and wider agent autonomy require human review and outcome evidence. Raw records remain exportable.
Limits & roadmap
| Edge (open source) | Model gateway (Chat Completions, Responses, Anthropic Messages), MCP gateway with credentials only the edge holds, pre-execution checks of shell and file actions for Claude Code and Hermes through hooks, approvals decided on the edge for one attempt of the exact call, local records, standalone or managed mode with signed time-limited bundles. |
|---|---|
| Paid, in pilots | Control plane (team invites, bounded delegation, context labels, policy), organization context on the enterprise edge with scheduled sync of source systems, skills mined from edge records with review and measurement, hash-chained audit of governance events. |
| Next work | Removing records from context when they are deleted upstream (today they stay, with their last-seen time), inheriting permissions from source systems instead of labels you assign, skills with branches and native-tool steps, a fuller local console on the edge (activity, organization context, skill review), approving from the hosted console with split rendering (arguments fetched from the edge by the approver's browser), portable delegation receipts, broader MCP transports and outcome reconciliation. Actions that do not go through the edge, such as direct SaaS or API calls, are outside what Descles can govern. |
Complaints, suggestions, or a roadmap vote? Write to outreach@descles.com. See also terms, privacy and refunds.