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 runOne edge in your network, with your provider keys and tool credentials.
You changeEach agent's base URL and MCP URLs point at the edge, and it authenticates with a Descles agent key.
Descles receivesNothing. 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
StandaloneNo 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.
TeamThe 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

  1. 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"}.
  2. 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 at GET /edge/bundle-key. Check it over a trusted channel before pinning it.
  3. Deploy: descles edge init --mode selfhost --control-plane https://control.internal --org <org> --bundle-key <key>, put the token in config/secrets/report-token (a legacy name; nothing is reported) and your provider key next to it, then descles edge up. Put your TLS ingress in front of it; remote members reach it over your VPN or an authenticated entry point.
  4. 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, then POST /control/agents/<id>/keys. POST /control/agents/<id>/revoke takes one away.
  5. 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 own policy.yaml stays 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 onlySet 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 CLIdescles 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.
Shell rules match the command the model asks to run. They are guardrails, not a sandbox: keep the harness's own sandbox, and put anything that must never be bypassed behind an MCP connector whose credential only the edge holds.

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: 50

Precedence: 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: allow

Matching: * 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_approval rule 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_file allow + **/.env deny) 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_approval

Matching 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.

Budget enforcement is live at the gateway: an employee or agent over its cap has the next request blocked, not merely charted. Policy set on your control plane is persisted there. Every edge can also load a floor from 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 trafficRouted by the edge to your provider, attributed to the agent, budgeted, recorded.
Tool calls a model proposesDenied or held before the runtime receives them.
MCP toolsExecuted by the edge with a credential only it holds, after policy and any approval.
Shell and file actionsChecked before they run in Claude Code and Hermes through hooks; not in Codex. Guardrails, not a sandbox.
Everything elseDirect 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 pilotsControl 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 workRemoving 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.