Documentation Index
Fetch the complete documentation index at: https://glide-9da73dea.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Rotate the signing key for this agent’s sub-vault. Always requires principal step-up. Completes atomically with a policy_version bump.
| Field | Value |
|---|
| Name | vault.rotateSigner |
| Category | treasury |
| Required scope | treasury:rotate-signer |
| Idempotency key required | no |
Annotations
| Annotation | Value |
|---|
| Title | Rotate Vault Signer |
| Read-only | no |
| Destructive | yes |
| Idempotent | no |
| Open-world | no |
| Requires human approval | yes (step-up) |
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"new_signer_public_key": {
"type": "string",
"minLength": 1
},
"reason": {
"default": "scheduled_rotation",
"type": "string",
"enum": [
"scheduled_rotation",
"compromised_key",
"user_request",
"device_change"
]
},
"step_up_sigil": {
"type": "string",
"minLength": 1
}
},
"required": [
"new_signer_public_key",
"reason"
],
"additionalProperties": false
}
Output schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"proposal_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"new_policy_version": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"enqueued_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"proposal_id",
"new_policy_version",
"enqueued_at"
],
"additionalProperties": false
}
Auth
Caller’s grant must include the treasury:rotate-signer scope. Grants whose scope set is a superset of the required scope are accepted.
Request examples
# First call — no sigil: server returns step_up_url
curl -X POST https://mcp.glide.co/mcp/treasury \
-H "Authorization: Bearer $GLIDE_GRANT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "vault.rotateSigner",
"params": {
"new_signer_public_key": "0x04a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
"reason": "scheduled_rotation"
}
}'
# Second call — with redeemed sigil
curl -X POST https://mcp.glide.co/mcp/treasury \
-H "Authorization: Bearer $GLIDE_GRANT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "vault.rotateSigner",
"params": {
"new_signer_public_key": "0x04a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
"reason": "scheduled_rotation",
"step_up_sigil": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
}
}'
Response examples
Step-up required (always on first call)
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32003,
"message": "signer rotation requires principal biometric approval",
"data": {
"reason_id": "step_up_required",
"step_up_url": "https://app.glide.co/step-up/confirm?sigil=eyJhbGci..."
}
}
}
Success (after sigil redemption)
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"proposal_id": "f1e2d3c4-b5a6-4987-8765-432100fedcba",
"new_policy_version": 12,
"enqueued_at": "2026-05-04T14:30:00Z"
}
}
Errors
| Code | reason_id | Meaning |
|---|
-32000 | unauthenticated | Bearer token missing or expired. |
-32001 | unauthorized | Grant does not include treasury:rotate-signer. |
-32003 | step_up_required | Step-up is always required. data.step_up_url contains the biometric approval URL. |
-32602 | step_up_sigil_invalid | Sigil was already redeemed, expired, or minted for a different action (reason mismatch). |
-32602 | invalid_params | new_signer_public_key is empty or malformed. |
-32603 | internal_error | Transient fault. Retry from step 1 (get a fresh sigil). |
Step-up flow
vault.rotateSigner always requires principal step-up. There is no threshold — every rotation, including scheduled ones, requires biometric approval. The sigil is bound to the reason field, so a sigil minted for grant_issue is rejected here.
- Call
vault.rotateSigner with new_signer_public_key and reason. The server always returns -32003.
- Redirect the principal to
data.step_up_url (Privy biometric). On success, Glide mints a one-time sigil bound to reason: "rotate_signer".
- Re-submit with
step_up_sigil: "<sigil>". The server verifies the sigil’s expected_reason matches "rotate_signer" and that it was not already redeemed.
- On success, a multisig proposal is submitted on-chain.
proposal_id can be tracked in the Actions inbox. new_policy_version is the post-rotation policy version.