intentic
Download the app
Download the app
Connected systems

Secrets

Stored values the agent can use without ever reading them

On this page(12 sections)

Write a secret, list which names exist, delete one. Revealing a value is the deliberate exception and the only route that hands one back; everywhere else the daemon substitutes a secret by reference at the moment a command runs.

12 calls. Pick one to open it, or use the list on the right.

POST/secretsStore a secret

Writes one name and value where the agent's references resolve it, without a restart: desired-state/.env once DevOps is active, the sandbox's own secret store before that.

What you send

FieldTypeWhere
keyrequiredThe name to store it under,…stringbody
valuerequiredThe valuestringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/secrets" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"key":"OPENAI_API_KEY","value":"…"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.set({
  "key": "OPENAI_API_KEY",
  "value": "…"
});
GET/secretsNames of the stored secrets

Which secrets exist here. Names only, never values.

What you send

Nothing. Call it as it is.

What comes back

FieldType
keysThe names that exist herestring[]
Try itanswered in this tab
curl
curl "$SANDBOX/secrets" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.list();
POST/secrets/generateMake and store a random secret

Makes a random value and stores it under a new name, where `set` would have put it, for a secret nobody has to find or paste (a session key, a signing secret, a password the task sets up itself). Answers the name and its length, never the value. Refused for a name something here already holds.

What you send

FieldTypeWhere
keyrequiredThe name to store it under:…stringbody
bytesHow much randomness, in bytesintegerbody
formatHow it is spelled: `hex` (0-9,…"hex" | "base64url" | "alnum"body

What comes back

FieldType
keyThe name it is stored understring
lengthHow many characters it is, which…integer
storedWhere it was kept: desired-state/.env once…"env" | "sandbox"
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/secrets/generate" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"key":"OPENAI_API_KEY","bytes":32,"format":"hex"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.generate({
  "key": "OPENAI_API_KEY",
  "bytes": 32,
  "format": "hex"
});
DELETE/secrets/{key}Delete a secret

Removes one by name.

What you send

FieldTypeWhere
keyrequiredWhich secret, by namestringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X DELETE "$SANDBOX/secrets/OPENAI_API_KEY" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.remove({
  "key": "OPENAI_API_KEY"
});
GET/secrets/inventoryEvery secret this sandbox holds, from everywhere

One view across all the places secrets live here: what exists, where it came from and whether it is working. Never any values. This one always answers, even before there is a store to write to.

What you send

Nothing. Call it as it is.

What comes back

FieldType
entriesOne entry per secret this sandbox…object[]
keyWhat identifies itstring
kindWhere it came from: you set…"env" | "generated" | "capability" | "provider"
labelA friendlier name, for entries that…string
statusWhether it exists and, for a…"missing" | "set" | "connected"
requiredByWhat is waiting on itobject[]
resourceIdWhich resourcestring
typeWhat kind of resource it isstring
storedAtWhere it actually lives, in wordsstring
revealableWhether its value can be shown…boolean
ciWhether a copy has been given…object
syncedWhether the pipeline has itboolean
pushedAtWhen it was last sent therestring
lastUseThe last time an agent actually…object
atWhen, in millisecondsnumber
laneHow it was used: a command,…"shell" | "code" | "browser"
detailWhere it went: the start of…string
approvedByWho released it for that use,…string
gateWho has to release this before…object
approversWho may release it, by emailstring[]
scopeHow far one release goes: `use`…"use" | "conversation"
hostsIts host guardobject
guardWhether a use off the list,…boolean
listThe hosts it goes to unasked…string[]
sourceWho set it: the owner, or…"owner" | "connector"
Try itanswered in this tab
curl
curl "$SANDBOX/secrets/inventory" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.inventory();
POST/secrets/revealShow one secret's value

The only call that hands a value back, and it is for the owner alone. Sent as a body rather than in the address, so the name never ends up in a log or a browser's history.

What you send

FieldTypeWhere
keyrequiredWhich secret, by namestringbody

What comes back

FieldType
valueThe value itselfstring
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/secrets/reveal" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"key":"OPENAI_API_KEY"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.reveal({
  "key": "OPENAI_API_KEY"
});
GET/secrets/gatesWhich credentials need somebody's approval

What is gated and who may release it. Names and addresses only, never values, and the agent may read it too: knowing a credential needs Bob is what stops it concluding the account is simply not connected.

What you send

Nothing. Call it as it is.

What comes back

FieldType
gatesEvery gate in forceobject[]
subjectWhat is gated: a secret's name,…string
kindWhether this gate covers one stored…"secret" | "capability"
approversExactly who may release it, by…string[]
scopeHow far one release goes: `use`…"use" | "conversation"
Try itanswered in this tab
curl
curl "$SANDBOX/secrets/gates" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.gates();
PUT/secrets/gates/{subject}Put a credential behind named approvers

Names exactly who may release one secret or one connected account, and how far a single release goes. The owner's call alone. A signed-in browser or a mounted server cannot be released for one use, so those are always for the rest of the conversation.

What you send

FieldTypeWhere
subjectrequiredWhat is gated: a secret's name,…stringaddress
kindrequiredWhether this gate covers one stored…"secret" | "capability"body
approversrequiredExactly who may release it, by…string[]body
scoperequiredHow far one release goes: `use`…"use" | "conversation"body

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X PUT "$SANDBOX/secrets/gates/Fix%20the%20flaky%20parser%20test" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"kind":"secret","approvers":["…","…"],"scope":"use"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.setGate({
  "subject": "Fix the flaky parser test",
  "kind": "secret",
  "approvers": [
    "…",
    "…"
  ],
  "scope": "use"
});
DELETE/secrets/gates/{subject}Stop requiring approval for a credential

Removes one gate, so the agent can use that credential the way it uses any other. The owner's call alone.

What you send

FieldTypeWhere
subjectrequiredWhich gate, by the secret name…stringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X DELETE "$SANDBOX/secrets/gates/Fix%20the%20flaky%20parser%20test" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.removeGate({
  "subject": "Fix the flaky parser test"
});
GET/secrets/hostsWhich secrets are host-guarded, and where they may go

Every secret and connected account whose host guard is set, on or off, and its hosts. With the guard on, a use aimed off the list, or anywhere a command's text does not show, asks a person first, whatever the safety judge says. Names and hosts only, never values.

What you send

Nothing. Call it as it is.

What comes back

FieldType
guardsEvery secret whose host guard has…object[]
subjectWhich secret, by the name its…string
kindWhether this gate covers one stored…"secret" | "capability"
guardOn: a use off the list,…boolean
hostsWhere it goes without asking while…string[]
sourceWho set it: the owner, or…"owner" | "connector"
Try itanswered in this tab
curl
curl "$SANDBOX/secrets/hosts" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.hosts();
PUT/secrets/hosts/{subject}Turn a secret's host guard on or off, and set its hosts

Replaces one secret's host guard. Anybody who may use secrets can turn it on or take hosts away; turning it off or adding a host is the owner's: from the agent it raises a card for the owner in the live conversation and waits for their answer.

What you send

FieldTypeWhere
subjectrequiredWhich secret, by name, or which…stringaddress
kindWhether the subject is a secret…"secret" | "capability"body
guardrequiredWhether a use off the list,…booleanbody
hostsrequiredThe whole new liststring[]body
conversationIdWhich conversation to ask the owner…stringbody

What comes back

FieldType
guardWhether the guard is on nowboolean
hostsWhere it goes without asking while…string[]
approvedByWho approved the change, when it…string
Try itanswered in this tab
curl
curl -X PUT "$SANDBOX/secrets/hosts/Fix%20the%20flaky%20parser%20test" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"kind":"secret","guard":true,"hosts":["sandbox-a1b2c3d4e5f6.intentic.dev","sandbox-a1b2c3d4e5f6.intentic.dev"],"conversationId":"nightly-changelog"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.setHosts({
  "subject": "Fix the flaky parser test",
  "kind": "secret",
  "guard": true,
  "hosts": [
    "sandbox-a1b2c3d4e5f6.intentic.dev",
    "sandbox-a1b2c3d4e5f6.intentic.dev"
  ],
  "conversationId": "nightly-changelog"
});
POST/secrets/requestAsk a named person to release a credential

Raises the release card in the live conversation and waits for one of the people named on it. Refused, rather than held, when there is nobody to ask: an unattended turn, no live conversation, or a click with no verified identity behind it.

What you send

FieldTypeWhere
subjectrequiredWhat to ask for: the secret's…stringbody
whyOne line on what it is…stringbody
conversationIdWhich conversation to raise the card…stringbody

What comes back

FieldType
grantedAlways true: a refusal is an…true
approvedByWho released itstring
messageWhat the grant means in practice,…string
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/secrets/request" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"subject":"Fix the flaky parser test","why":"…","conversationId":"nightly-changelog"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.secrets.request({
  "subject": "Fix the flaky parser test",
  "why": "…",
  "conversationId": "nightly-changelog"
});
More in Connected systems

Type to search every page, in the docs and the API reference.