Agent skill

Tenuo Denial Triage

by tenuo-ai in tenuo-ai/tenuo

Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority.

Apache-2.0Auto-check passedSecurity

Install Tenuo Denial Triage

skills CLI
$ npx skills add tenuo-ai/tenuo --skill tenuo-denial-triage -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install tenuo-ai/tenuo tenuo-denial-triage --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/tenuo-ai/tenuo.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/tenuo-denial-triage .claude/skills/tenuo-denial-triage && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
tenuo-denial-triage
GitHub stars
103
Token cost
~2.3k tokens
SKILL.md length
1,237 words
Files
1
Skills in repo
4
Repo updated
First seen
Licence
Apache-2.0

At a glance

Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority.

  • Works in 4 steps: The exact error. Class or code, message,… → The decision point. Which verifier… → The presented authority, from the SDK's… → …
  • Agent step fails with a Tenuo denial
  • SKILL.md covers Collect the facts before…, Classify the denial, Rank the fixes and stop at the… and Prove the fix, plus 1 more section
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Tenuo Denial Triage is an agent skill from tenuo-ai/tenuo. Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority. Use when a call, test, or agent step fails with a Tenuo denial, monotonicity, proof-of-possession, chain, expiry, approval, or unknown-argument error. Do not use to design new authority from scratch (use tenuo-warrant), to add enforcement to a boundary (use tenuo-agent-authorization), or for a review-only audit (use tenuo-audit).

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Security, covering Authorization and RBAC. It works with Model Context Protocol, Python, Rust and TypeScript. The repository describes itself as: Task-scoped authorization for AI agents. Cryptographic warrants constrain tools and arguments, prevent privilege escalation at every delegation hop, and produce signed evidence… The licence is Apache-2.0.

When your agent uses it

  • Agent step fails with a Tenuo denial
  • Proof-of-possession
  • Unknown-argument error
  • Design new authority from scratch (use tenuo-warrant)

Example prompts

  • “/tenuo-denial-triage”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. The exact error. Class or code, message, hint, and the field or tool it names. Keep the text; do not paraphrase it away.
  2. The decision point. Which verifier denied: an in-process guard, an MCP server, a gateway, a sidecar, a worker. And which link: root trust…
  3. The presented authority, from the SDK's own diagnostics, not from reading code. In Python, why_denied() on the warrant for the exact tool…
  4. The call as the verifier saw it. Tool name, every argument after normalization and injection, the holder key that signed, and the…

What it can do on your machine

Read from SKILL.md and the folder at commit c8f2bd0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Tenuo Denial Triage loads about 2.3k tokens when it runs. Until then it costs about 113 tokens; SKILL.md has 1,237 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~113
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from tenuo-ai/tenuo at commit c8f2bd0, republished under its Apache-2.0 licence (© tenuo-ai). 1,237 words, ~2,336 tokens.

Download SKILL.mdSave it as .claude/skills/tenuo-denial-triage/SKILL.md (or your agent's skills folder).
name
tenuo-denial-triage
description
Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority. Use when a call, test, or agent step fails with a Tenuo denial, monotonicity, proof-of-possession, chain, expiry, approval, or unknown-argument error. Do not use to design new authority from scratch (use tenuo-warrant), to add enforcement to a boundary (use tenuo-agent-authorization), or for a review-only audit (use tenuo-audit).

Tenuo Denial Triage

A denial is the system working. Find out whether the caller, the policy, or the configuration is wrong, then fix that with the smallest possible increase in authority. Never route around the verifier, and never make a test pass by widening what the agent may do.

Announce at start: "I'm using the tenuo-denial-triage skill to find why this call was denied and the narrowest fix."

Collect the facts before changing anything

  1. The exact error. Class or code, message, hint, and the field or tool it names. Keep the text; do not paraphrase it away.
  2. The decision point. Which verifier denied: an in-process guard, an MCP server, a gateway, a sidecar, a worker. And which link: root trust, an intermediate warrant, the leaf, the proof-of-possession, or an approval gate.
  3. The presented authority, from the SDK's own diagnostics, not from reading code. In Python, why_denied() on the warrant for the exact tool and arguments, diagnose() on the warrant, explain() on the caught error, and info() for configuration. In TypeScript, session.inspect() and tenuo.explain(session, tool, args). In Rust, the Diagnostics helper's explain_denial, why_denied, and explain_authority. From a shell, tenuo inspect and tenuo verify. When the denial happened in another process, start from the receipt: its decision code, action, request hash, and trusted-roots hash say what the verifier saw. Confirm every diagnostic name against the installed package version before relying on it.
  4. The call as the verifier saw it. Tool name, every argument after normalization and injection, the holder key that signed, and the timestamp. Argument names and types matter as much as values.

Write a one-screen triage note before editing:

text
Error:          <class or code>: <message>
Denied check:   tool | constraint(<field>) | unknown field | expiry | PoP | chain | monotonicity | revocation | approval | configuration
Decision point: <component> at <file:line or service>, chain link: <root | intermediate | leaf | PoP>
Presented:      tools=<...> constraints=<...> holder=<key id> expires=<...>
Call:           tool=<...> args=<normalized map> signer=<key id>
Cause:          caller | policy | configuration | expected denial

Classify the denial

Denied checkWhat it meansUsual cause
Tool not authorizedThe warrant never carried this toolCaller named the wrong tool, or the issuer never granted it
Constraint on a named argumentThe value is outside the envelopeCaller sent the wrong value, or the envelope is narrower than the legitimate task
Unknown field, closed-worldThe call carries an argument the policy never namedCaller sends something the effect does not need, or a needed argument was never named
ExpiredStale authorityHolder reused a warrant past its TTL
Proof-of-possession, wrong holder, signature mismatchThe proof does not match the leaf holder, tool, or argumentsWrong signing key, arguments changed after signing, tool string mismatch, clock skew
Untrusted root, broken chain, parent requiredThe verifier does not trust or cannot link the chainWrong issuer for this verifier, parents not presented, chain assembled out of order
MonotonicityA child claims more than its parentDelegation design widened instead of narrowing
RevokedAuthority was withdrawnExpected; do not resurrect
Presentation context: audience, nonce, replayThe proof was not made for this enforcement point, or was already usedCaller or transport: present to the party you address, with a fresh proof per call; never disable the check
Approval required or insufficientA gate firedExpected; obtain approval or narrow the exemption
ConfigurationNo trusted roots, no warrant in context, missing keyWiring, not authority

An expected denial is finished when you say so. Do not turn it into a change.

Rank the fixes and stop at the first that works

  1. Fix the call. Right tool name, right argument names and types, values normalized the way the verifier normalizes them, the proof signed by the leaf holder over the final arguments, a fresh warrant instead of a stale one. If the effect never reads an argument, remove it from the presented call; do not name it in the policy. A value is material when the effect stores, forwards, logs, or acts on it, even if it does not change which effect runs; a material value needs a bounded constraint, never a wildcard. Do not change the effect to consume a value in order to justify naming it.
  2. Stay inside the envelope. If the task is narrower than the warrant, narrow the child. If the issuer can mint authority that fits the task, request that warrant. Neither changes any policy.
  3. Widen minimally, at the issuer, by naming exactly the new legitimate values. Add the one recipient to the allowed set. Raise a maximum to the number the task needs. Name a newly required argument with the tightest constraint that admits the real values: an exact value, a small set, a bounded range, a path under a root, a URL limited to named domains. Free text the effect keeps gets a regular expression that bounds its length and character set, where the SDK offers one. If it does not, use another supported bounded constraint, such as an exact value or a small allowlist. Keep every material value in the signed and verified arguments. If no supported constraint fits, remove the value from the entire call, including the effect, only when the task permits omission; otherwise stop and report the unsupported requirement. Removing a value only from the presentation leaves the effect consuming unchecked data. Keep the TTL and delegation depth as they were.
  4. Last resort, with a written justification in the report: an unconstrained wildcard on a named argument that the call must carry and the effect ignores. Never on a value the effect keeps.
Show full SKILL.md (367 more words)Show less

Never do these to clear a denial:

  • Opt out of closed-world mode (_allow_unknown or its equivalents) to admit an unknown field. Name the field or drop it.
  • Leave the capability open to any arguments, whether by a policy that names none or by the SDK's explicit any-arguments form, or put a wildcard or a match-everything pattern on a material argument: one the effect stores, forwards, logs, or acts on.
  • Remove a constraint, or replace a path or URL constraint with a plain string glob.
  • Lengthen the TTL because a warrant expired. Re-issue instead.
  • Add the caller's own key, a test key, or any new root to the verifier's trusted roots.
  • Enable an optional-warrant, observe-only, shadow, or development mode on the verifier.
  • Catch the denial and call the effect anyway, or add a route to the effect that skips the verifier.
  • Edit verifier trust, proof-of-possession, or gate settings from the caller's side. Those belong to the verifier's owner, who changes them through their own review.

If the only fix you can find is on that list, stop and report that the request needs new authority from the issuer or a design change. Hand new authority design to tenuo-warrant and missing enforcement to tenuo-agent-authorization.

Prove the fix

  • The previously denied legitimate call now reaches the effect exactly once, through the same path the application uses.
  • Every previously denied illegitimate case still produces zero effects. Rerun the existing denial tests; do not delete or weaken one to make the change fit.
  • Add a test for the new boundary: the value just past the widened edge is still denied.
  • If the preferred constraint is unavailable, prove that the fallback still verifies the material value, or that omission removes it from the effect as well. When neither is possible, the call must remain denied with zero effects.
  • If you changed a policy, state the authority delta as before-and-after envelopes, one line per changed capability or argument.

Report

text
Denied check:     <from the triage note>
Decision point:   <component>, chain link <...>
Cause:            caller | policy | configuration | expected denial
Fix applied:      <one sentence>
Authority delta:  <capability.argument>: <before> -> <after>   (or "none")
Unchanged:        verifier trusted roots, proof-of-possession, closed-world mode, TTL, delegation depth
Tests:            <n> prior denials still zero effects; legitimate call allowed once; new edge denied
Residual risk:    <what the widened envelope now admits that it did not before>

Do not claim the fix proves replay resistance, revocation, exactly-once execution, or that the effect completed downstream. If the denial revealed a missing or bypassable boundary, say so and route that work to tenuo-agent-authorization; a review-only question about what a warrant permits goes to tenuo-audit.

© tenuo-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/tenuo-denial-triage of tenuo-ai/tenuo.

Open the folder on GitHubat commit c8f2bd0

Compare with similar skills

Tenuo Denial Triage next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Tenuo Denial Triage compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Tenuo Denial Triage this skilltenuo-ai/tenuo103—~2.3kAutomated safety check: PassApache-2.0
MCP SDK Tier Auditmodelcontextprotocol/conformance130—~4.4kAutomated safety check: PassCustom licence
Sponsio Agent Safety SetupSponsioLabs/Sponsio454—~12kAutomated safety check: PassApache-2.0
Security Reviewgithub/awesome-copilot40k1 repos~2.3kAutomated safety check: NotesMIT
MCP Server Builderanthropics/skills180k63 repos~2.3kAutomated safety check: PassApache-2.0
MCP Server BuildershareAI-lab/learn-claude-code78k4 repos~1.2kAutomated safety check: PassMIT

Similar skills

  • MCP SDK Tier Audit

    modelcontextprotocol/conformance

    Official

    Comprehensive tier assessment for an MCP SDK repository against SEP-1730.

    130 GitHub stars~4.4k tokensUpdated 6 days ago
    MobileAuto-check passed
  • Sponsio Agent Safety Setup

    SponsioLabs/Sponsio

    Installs, tunes and enforces Sponsio contracts that block unsafe tool calls in LLM agents, covering setup, auditing, observe mode and flipping to enforce.

    454 GitHub stars~12k tokensUpdated yesterday
    AI & LLM EngineeringAuto-check passed
  • Security Review

    github/awesome-copilot

    Official

    AI-powered codebase security scanner that reasons about code like a security researcher — tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching…

    40k GitHub starsUsed in 1 repo~2.3k tokens
    SecurityAuto-check: notes
  • MCP Server Builder

    anthropics/skills

    Official

    Guides the design and implementation of Model Context Protocol servers in TypeScript or Python, from tool naming and error messages to evaluation.

    180k GitHub starsUsed in 63 repos~2.3k tokens
    Agent WorkflowsAuto-check passed
  • MCP Server Builder

    shareAI-lab/learn-claude-code

    Walks through building MCP servers in Python or TypeScript that expose tools, resources and prompts to Claude, with templates, registration and testing.

    78k GitHub starsUsed in 4 repos~1.2k tokens
    Agent WorkflowsAuto-check passed
  • Adds Firecrawl's /scrape endpoint to application code to pull markdown, HTML, links, screenshots or structured data from a single known URL.

    190k GitHub starsUsed in 1 repo~944 tokens
    Data & AnalyticsAuto-check passed

More from tenuo-ai/tenuo

  • Add or retrofit Tenuo authorization for AI-agent tools and effects.

    103 GitHub stars~2.3k tokensUpdated yesterday
    Auto-check passed
  • Tenuo Warrant

    tenuo-ai/tenuo

    Create or delegate Tenuo warrants from natural-language authority requirements.

    103 GitHub stars~4.9k tokensUpdated yesterday
    Auto-check passed
  • Tenuo Audit

    tenuo-ai/tenuo

    Audit, explain, or compare existing Tenuo warrants and delegation chains.

    103 GitHub stars~3.6k tokensUpdated yesterday
    Auto-check passed

Questions about Tenuo Denial Triage

What does Tenuo Denial Triage do?

Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority. Tenuo Denial Triage is an agent skill from tenuo-ai/tenuo. Diagnose a denied Tenuo call and make the legitimate call work with the smallest change to authority.

When should I use Tenuo Denial Triage?

Tenuo Denial Triage fits situations like: agent step fails with a Tenuo denial; proof-of-possession; unknown-argument error; design new authority from scratch (use tenuo-warrant).

How do I install Tenuo Denial Triage in Claude Code?

Run `npx skills add tenuo-ai/tenuo --skill tenuo-denial-triage -a claude-code`. Or copy the skill folder (skills/tenuo-denial-triage in tenuo-ai/tenuo) into .claude/skills/tenuo-denial-triage in your project. Claude Code loads it when a task matches its description.

How do I install Tenuo Denial Triage in Codex?

Run `npx skills add tenuo-ai/tenuo --skill tenuo-denial-triage -a codex`. Or copy the skill folder (skills/tenuo-denial-triage in tenuo-ai/tenuo) into .agents/skills/tenuo-denial-triage in your project. Codex loads it when a task matches its description.

Can I use Tenuo Denial Triage in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add tenuo-ai/tenuo --skill tenuo-denial-triage -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/tenuo-denial-triage, .gemini/skills/tenuo-denial-triage, .github/skills/tenuo-denial-triage and .opencode/skills/tenuo-denial-triage in your project.

What does Tenuo Denial Triage need to run?

SKILL.md names no scripts, command-line tools or credentials: Tenuo Denial Triage is instructions for the agent only.

Does Tenuo Denial Triage access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Tenuo Denial Triage safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Tenuo Denial Triage use?

Tenuo Denial Triage is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Tenuo Denial Triage use?

About 2.3k tokens (SKILL.md is roughly 9.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Tenuo Denial Triage?

Skills that share tags, products or a category with Tenuo Denial Triage: MCP SDK Tier Audit (modelcontextprotocol/conformance, 130 stars), Sponsio Agent Safety Setup (SponsioLabs/Sponsio, 454 stars), Security Review (github/awesome-copilot, 40k stars) and MCP Server Builder (anthropics/skills, 180k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Tenuo Denial Triage?

tenuo-ai (a GitHub organization) maintains it in tenuo-ai/tenuo, which has 103 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 10, 2026.

Source: tenuo-ai/tenuo on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.