AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Managing Agent

skill-tkhq-turnkey-agent-skills-managing-agent · by tkhq

Day-2 operations for a provisioned Turnkey agent: debug denied transactions, update policies (spending limits, allowlists), rotate API keys, revoke access, and add chains. Requires root credentials. For initial agent setup, use provisioning-agent.

No reviews yet
0 installs
22 views
0.0% view→install

Install

$ agentstack add skill-tkhq-turnkey-agent-skills-managing-agent

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-tkhq-turnkey-agent-skills-managing-agent)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Managing Agent? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Managing an Agent

> Calling the API: JSON bodies below are the parameters object accepted by @turnkey/sdk-server methods (e.g. create_api_keysclient.createApiKeys(...), update_policyclient.updatePolicy(...)). See the root [SKILL.md](../../SKILL.md#calling-the-api) for SDK setup and full endpoint-to-method mapping.

Independent recipes for day-2 agent operations. Each section is self-contained — find the one that matches your situation.

All recipes run with root credentials (or credentials with sufficient policy permissions). These are admin operations, not actions the agent performs on itself.

Base URL: https://api.turnkey.com

Rules (mandatory)

  1. Human confirmation before any policy change. Display the updated policy and explain what changes. Wait for explicit approval.
  2. Before deleting an agent user, verify it is the intended non-root agent. Deleting users is permanent. If the target might be a root, admin, or human user — or you cannot confirm the target is the disposable provisioned agent — do not call delete_users; stop and ask the human to confirm the exact user.

Prerequisites

Requires root API credentials. All recipes run with root/admin access, not agent credentials.

TURNKEY_API_PUBLIC_KEY=    # Root API key — public component (hex)
TURNKEY_API_PRIVATE_KEY=   # Root API key — private component (P-256 hex)
TURNKEY_ORGANIZATION_ID=   # Turnkey organization UUID

Use the getting-started skill if you still need to verify credentials.


My agent's transaction was denied

Use get_policy_evaluations to see exactly which policy blocked it and why.

POST /public/v1/query/get_policy_evaluations
{
  "organizationId": "",
  "activityId": ""
}

The response contains a policyEvaluations array. Each entry shows a policy and its outcome:

| Outcome | Meaning | |---------|---------| | OUTCOME_ALLOW | This policy permitted the action | | OUTCOME_DENY_EXPLICIT | This policy explicitly blocked the action (a DENY matched) | | OUTCOME_DENY_IMPLICIT | No ALLOW policy matched — blocked by default deny | | OUTCOME_REQUIRES_CONSENSUS | Policy requires multi-party approval before proceeding | | OUTCOME_ERROR | Policy evaluation errored (likely a no-short-circuit issue — see managing-policies) |

Common causes:

  • OUTCOME_DENY_EXPLICIT: A DENY policy's condition matched. Check the spending cap or address allowlist. Either lower the transaction amount / change the destination, or update the DENY policy with the human's approval.
  • OUTCOME_DENY_IMPLICIT: No ALLOW policy matched. The agent's ALLOW policy condition doesn't cover this action. Check that wallet.id, chain-specific conditions, or consensus expressions match.
  • OUTCOME_ERROR: A policy condition errored during evaluation. Most common cause: mixing wallet.id and private_key.id in one condition (no-short-circuit rule). Split into separate policies.

Do not broaden policies without revisiting the original constraint decisions with the human. A denied transaction may be the policy working correctly.

For full debugging examples, see [references/policy-debugging-examples.md](references/policy-debugging-examples.md).


I need to change spending limits or allowed addresses

Find the policy to update

POST /public/v1/query/list_policies
{
  "organizationId": ""
}

Identify the relevant policy by name (e.g., deny-large-eth for spending cap, agent-eth-allowlist for address restrictions).

Update the policy

Confirm the change with the human before submitting.

POST /public/v1/submit/update_policy

Example — increase spending cap from 0.1 ETH to 0.5 ETH:

{
  "policyId": "",
  "policyName": "deny-large-eth",
  "policyEffect": "EFFECT_DENY",
  "policyCondition": "eth.tx.value > 500000000000000000",
  "policyNotes": "Block transfers above 0.5 ETH (was 0.1 ETH)"
}

Example — add a new address to the allowlist:

{
  "policyId": "",
  "policyName": "agent-eth-allowlist",
  "policyEffect": "EFFECT_ALLOW",
  "policyConsensus": "approvers.any(user, user.tags.contains(''))",
  "policyCondition": "wallet.id == '' && eth.tx.to in ['0xAddr1', '0xAddr2', '0xNewAddr3']",
  "policyNotes": "Added 0xNewAddr3 to allowlist"
}

After updating, list policies again and confirm the full active set with the human.

For more examples, see [references/policy-update-examples.md](references/policy-update-examples.md).


I need to rotate the agent's API key

Rotate without downtime. Each step must succeed before proceeding.

Step 1: Generate a new P-256 key pair locally.

Step 2: Register the new public key (sign this with the root or old agent key):

POST /public/v1/submit/create_api_keys
{
  "userId": "",
  "apiKeys": [{
    "apiKeyName": "agent-key-v2",
    "publicKey": "",
    "curveType": "API_KEY_CURVE_P256"
  }]
}

Step 3: Verify the new key works (sign this with the new key):

POST /public/v1/query/whoami
{
  "organizationId": ""
}

If this returns the agent's user details, the new key is working.

Step 4: Delete the old key (sign this with the new key):

POST /public/v1/submit/delete_api_keys
{
  "userId": "",
  "apiKeyIds": [""]
}

Step 5: Update the agent's runtime environment with the new TURNKEY_API_PUBLIC_KEY and TURNKEY_API_PRIVATE_KEY.

For the complete rotation workflow with full request/response, see [references/key-rotation-examples.md](references/key-rotation-examples.md).


I need to revoke agent access immediately

For emergency shutdown of a provisioned agent, prefer deleting the agent user. This immediately revokes all of that user's credentials and avoids the delete_api_keys failure case where Turnkey refuses to leave a surviving user with zero valid auth methods.

Safety gate — do not skip: before deletion, confirm the target is the intended disposable, non-root agent user. Check the user record and match it against the operator's intent (agent user ID, name, tags, and known provisioning notes). If the user might be root/admin/human, or if you cannot confirm it is the agent, do not delete it. Stop and ask the human to confirm the exact user first.

POST /public/v1/query/get_user
{
  "organizationId": "",
  "userId": ""
}

After the safety gate passes, present the deletion call, warn that it is permanent and irreversible, and wait for explicit human confirmation:

POST /public/v1/submit/delete_users
{
  "userIds": [""]
}

This takes effect immediately when the request succeeds: the deleted agent user can no longer authenticate or sign. When responding to a compromise or shutdown request, state this explicitly so the operator knows access has stopped.

Use delete_api_keys only when removing one compromised key from a user that will still have another valid credential (for example, after key rotation). Do not use it to delete the user's only credential; Turnkey will reject that with user missing valid credential.

If the safety gate does not pass, do not delete the user. Instead, stop and ask for operator review; if the goal is only to stop signing while identity is investigated, use a narrowly-scoped DENY policy or remove the agent-specific ALLOW policy with explicit human approval.

After revoking access, optionally clean up:

  • Delete the agent's policies (if they were user-specific and no longer needed)
  • The wallet remains — it may hold funds that need to be transferred first

I need to add a new chain to the agent's wallet

Derive a new account

POST /public/v1/submit/create_wallet_accounts
{
  "walletId": "",
  "accounts": [{
    "curve": "CURVE_ED25519",
    "pathFormat": "PATH_FORMAT_BIP32",
    "path": "m/44'/501'/0'/0'",
    "addressFormat": "ADDRESS_FORMAT_SOLANA"
  }]
}

For Bitcoin, remember the dual-account requirement (compressed key + address at same path). See the managing-wallets skill.

Update policies for the new chain

Adding a chain account does NOT automatically grant the agent permission to sign on it. If the agent's ALLOW policy only references eth.tx.* conditions, it won't cover Solana, Tron, Tempo, or Bitcoin transactions.

You may need to:

  1. Create a new ALLOW policy for the new chain (e.g., solana.tx.* for Solana, tron.tx.* for Tron, tempo.tx.* for Tempo, bitcoin.tx.* for Bitcoin)
  2. Create chain-specific DENY guardrails (e.g., Solana transfer cap, Tron amount cap in SUN, program restrictions)
  3. Verify the agent can sign on the new chain with a test payload

Confirm all policy changes with the human before creating them.


Troubleshooting

Key rotation: new key doesn't work after registration Verify the public key format is correct (hex-encoded P-256). Check that the curveType is API_KEY_CURVE_P256. Try whoami signed with the new key to isolate the issue.

Policy update has no effect List all policies to check for conflicting DENY policies that override the updated ALLOW. Remember: DENY always wins.

Agent still has access after key deletion Verify the specific compromised or retired key was deleted. If the goal is full emergency shutdown for a disposable non-root agent, use the get_user safety gate plus delete_users flow above instead of trying to remove every API key; Turnkey rejects deleting a user's only valid credential.

New chain added but agent can't sign on it Policies are chain-specific. An ALLOW with eth.tx.to in [...] doesn't cover Solana, Tron, Tempo, or Bitcoin. Create a separate policy with the appropriate namespace (solana.tx.*, tron.tx.*, tempo.tx.*, bitcoin.tx.*).

Related Skills

  • provisioning-agent — initial agent setup (run this first)
  • managing-policies — full policy reference, language, anti-patterns
  • managing-users — user and API key details
  • managing-wallets — wallet accounts and chain support
  • signing-transactions — what the agent does with its wallet

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.