Secrets
These endpoints manage your company's secrets: credentials that tools can use in outgoing HTTPS requests but that no read ever returns. You can create and rotate secrets, change their allowed hosts and bound tools, seal them, read their audit log, and run the two-person reveal flow for REVEALABLE secrets. No endpoint returns a secret's value except /reveal, and only to the person whose request was approved.
Base URL
https://api.autessa.com/autessa_poweruser/secrets
All endpoints are POST with a JSON body. Authenticate with a poweruser key or temporary credential in the Authorization header (no Bearer prefix):
Authorization: pwrusr:{id}:{secret}
The builder and the CLI call the same operations, with the same request and response shapes, at https://api.autessa.com/secrets/<op> using the person's own sign-in. This page documents the Poweruser path. A poweruser key never counts as a person, so /reveal on this path always fails with MACHINE_IDENTITY_CANNOT_REVEAL, even for a permanent key. Reveal from the builder, or with autessa secrets reveal signed in with your own CLI login.
Every call is checked against the caller's access to the secret: USE, REVEAL, or MANAGE, as described under Access levels. Scoped keys need the matching endpoint keys; list them with /user/available-endpoints.
Secrets are shared through the standard sharing endpoints with the resource type SECRET; there is no secret-specific share endpoint. There, READ means Use, WRITE means Reveal, and ADMIN means Manage. Ownership can be transferred, and every sharing change is written to the secret's audit log. See Sharing and Access.
Access levels
| Level | Endpoints |
|---|---|
USE | /list, /get, and using the secret from tools |
REVEAL | Everything in USE, plus /reveal-request on a REVEALABLE secret |
MANAGE | Everything, plus /update, /rotate, /seal, /delete, /audit, /reveal-approve, /reveal-deny, and sharing |
The owner always has MANAGE. Company admins get no automatic access: only the owner and the people, teams, and roles a secret is shared with can see or use it. /reveal-cancel and /reveal are only for the person who made the request.
The secret object
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
name- Type
- string
- Description
Unique name within the company. Tools and scripts refer to the secret by this name.
- Name
description- Type
- string
- Description
What the secret is for.
- Name
mode- Type
- string
- Description
SEALED(never viewable) orREVEALABLE(viewable through an approved reveal request).
- Name
last4- Type
- string | null
- Description
The value's last four characters, when
showLast4is on and the value is at least 12 characters long. Otherwisenull.
- Name
showLast4- Type
- boolean
- Description
Whether
last4is shown.
- Name
allowedHosts- Type
- array<string>
- Description
Exact hostnames the value may be sent to.
- Name
boundToolIds- Type
- array<string>
- Description
IDs of the tools that may use the secret no matter who runs them. Empty means any tool, run by someone with at least
USE.
- Name
version- Type
- integer
- Description
Starts at 1 and increases by one on every rotation.
- Name
ownerId- Type
- string
- Description
ID of the owner.
- Name
ownerEmail- Type
- string
- Description
Email of the owner.
- Name
createdAt- Type
- string
- Description
When the secret was created (ISO-8601, UTC).
- Name
updatedAt- Type
- string
- Description
When the secret was last changed.
- Name
rotatedAt- Type
- string | null
- Description
When the value was last rotated, or
nullif never.
- Name
myPermission- Type
- string
- Description
The caller's access:
USE,REVEAL, orMANAGE.
- Name
pendingRevealRequests- Type
- integer
- Description
Number of reveal requests waiting for a decision. Only included when the caller has
MANAGE.
The object never contains the value.
{
"secretId": "3f6c2a9e-8d41-4b7a-9c0e-5b2f1d7a4e10",
"name": "acme-api-key",
"description": "Acme production API key",
"mode": "SEALED",
"last4": "x9Qa",
"showLast4": true,
"allowedHosts": ["api.acme.com"],
"boundToolIds": [],
"version": 1,
"ownerId": "9a0d3c55-6e2b-4f81-b7a4-1c8e2d9f6a03",
"ownerEmail": "dana@example.com",
"createdAt": "2026-10-16T17:02:11Z",
"updatedAt": "2026-10-16T17:02:11Z",
"rotatedAt": null,
"myPermission": "MANAGE",
"pendingRevealRequests": 0
}
The reveal request object
- Name
requestId- Type
- string
- Description
ID of the request.
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
secretName- Type
- string
- Description
Name of the secret.
- Name
requesterId- Type
- string
- Description
ID of the person who asked.
- Name
requesterEmail- Type
- string
- Description
Email of the person who asked.
- Name
reason- Type
- string
- Description
The reason the requester gave.
- Name
status- Type
- string
- Description
PENDING,APPROVED,DENIED,EXPIRED,USED, orCANCELLED.
- Name
approverEmail- Type
- string
- Description
Email of the person who approved or denied the request. Absent while pending.
- Name
decidedAt- Type
- string
- Description
When the request was approved or denied. Absent while pending.
- Name
expiresAt- Type
- string
- Description
While pending: 7 days after the request was made. Once approved: 15 minutes after approval, the deadline for
/reveal.
- Name
usedAt- Type
- string
- Description
When the value was revealed. Absent until then.
- Name
createdAt- Type
- string
- Description
When the request was made.
{
"requestId": "b7e1c0d4-2a95-4f3e-8c61-0d9a7f2e5b38",
"secretId": "6d0a4b2c-1f9e-4c73-a5b8-2e7d9c0f1a64",
"secretName": "vendor-portal-password",
"requesterId": "5c2e8f41-7d3a-4b90-a6e2-8f1b0c4d7e59",
"requesterEmail": "sam@example.com",
"reason": "Logging in to the vendor portal to download the Q3 invoices.",
"status": "PENDING",
"expiresAt": "2026-10-23T17:10:00Z",
"createdAt": "2026-10-16T17:10:00Z"
}
The audit event object
- Name
eventId- Type
- string
- Description
ID of the event.
- Name
action- Type
- string
- Description
One of
CREATE,UPDATE,ROTATE,SEAL,DELETE,SHARE,USE,USE_DENIED,REVEAL_REQUEST,REVEAL_APPROVE,REVEAL_DENY,REVEAL, orREVEAL_DENIED.
- Name
actorEmail- Type
- string
- Description
Email of the person who acted. For
USEevents from scheduled and triggered runs, the person who set up the run.
- Name
detail- Type
- object
- Description
What happened, depending on the action: for example
toolId,executionId, andhostforUSE(hostishmacfor signature checks),requestIdfor reveal events, and the names of the changed fields forUPDATE. Never contains the value.
- Name
createdAt- Type
- string
- Description
When the event happened.
{
"eventId": "e41b9c07-3f2d-4a68-9b15-7c0e2d8a6f94",
"action": "USE",
"actorEmail": "dana@example.com",
"detail": {
"toolId": "a1c4e7f0-9b2d-4e35-8a61-3f7c0d9b2e48",
"executionId": "c2d5f8a1-0e3b-4f46-9b72-4a8d1e0c3f59",
"host": "api.acme.com"
},
"createdAt": "2026-10-16T17:30:42Z"
}
Create Secret POST/create
Stores a new secret. The value is encrypted and is never returned by this or any other read. The caller becomes the owner, with MANAGE access.
Request Body
- Name
name- Type
- string
- Description
Unique name within the company: lowercase letters, numbers,
_,., and-, starting with a letter or number, 2 to 100 characters. Can't be changed later.
- Name
description- Type
- string
- Description
What the secret is for.
- Name
mode- Type
- string
- Description
SEALEDorREVEALABLE.
- Name
value- Type
- string
- Description
The secret value, up to 16 KB.
- Name
allowedHosts- Type
- array<string>
- Description
Exact hostnames the value may be sent to, such as
api.acme.com. At least one and at most 50. Hostnames only: no wildcards, schemes, paths, or ports. Hosts are trimmed and stored in lowercase, and duplicates are dropped.
- Name
boundToolIds- Type
- array<string>
- Description
IDs of the tools that may use the secret no matter who runs them. Omit, or send
[], to let any tool use it when run by someone with at leastUSE.
- Name
showLast4- Type
- boolean
- Description
Show the value's last four characters in reads (only for values of 12 characters or more). Defaults to
false.
Response
The secret object.
curl https://api.autessa.com/autessa_poweruser/secrets/create \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "acme-api-key",
"description": "Acme production API key",
"mode": "SEALED",
"value": "'"$ACME_API_KEY"'",
"allowedHosts": ["api.acme.com"],
"showLast4": true
}'
List Secrets POST/list
Lists the secrets the caller has at least USE access on.
Request Body
- Name
pageSize- Type
- integer
- Description
Maximum number of secrets to return. Defaults to 50; at most 200.
- Name
pageToken- Type
- string
- Description
The
nextPageTokenfrom the previous response.
- Name
search- Type
- string
- Description
Only return secrets whose name or description contains this text.
Response
- Name
secrets- Type
- array<object>
- Description
- Name
nextPageToken- Type
- string
- Description
Pass as
pageTokento get the next page. Absent on the last page.
curl https://api.autessa.com/autessa_poweruser/secrets/list \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"pageSize": 50, "search": "acme"}'
Get Secret POST/get
Fetches one secret, by ID or by name. Send one of the two.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
name- Type
- string
- Description
Name of the secret.
Response
The secret object.
curl https://api.autessa.com/autessa_poweruser/secrets/get \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "acme-api-key"}'
Update Secret POST/update
Changes a secret's settings. Each field you send replaces the stored one, and fields you leave out keep their values. The value is changed with /rotate and the mode with /seal; the name can't be changed. Needs MANAGE.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
description- Type
- string
- Description
New description.
- Name
allowedHosts- Type
- array<string>
- Description
Replaces the allowed hosts. At least one and at most 50.
- Name
boundToolIds- Type
- array<string>
- Description
Replaces the bound tools. Send
[]to unbind every tool.
- Name
showLast4- Type
- boolean
- Description
Turns the last-four display on or off.
Response
The secret object.
curl https://api.autessa.com/autessa_poweruser/secrets/update \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{
"secretId": "3f6c2a9e-8d41-4b7a-9c0e-5b2f1d7a4e10",
"allowedHosts": ["api.acme.com", "sandbox.api.acme.com"],
"boundToolIds": ["a1c4e7f0-9b2d-4e35-8a61-3f7c0d9b2e48"]
}'
Rotate Secret POST/rotate
Replaces the value and increases version by one. Executions that start after the rotation use the new value. Needs MANAGE.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
value- Type
- string
- Description
The new value, up to 16 KB.
Response
The secret object, with the new version and rotatedAt.
curl https://api.autessa.com/autessa_poweruser/secrets/rotate \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{
"secretId": "3f6c2a9e-8d41-4b7a-9c0e-5b2f1d7a4e10",
"value": "'"$NEW_ACME_API_KEY"'"
}'
Seal Secret POST/seal
Makes a REVEALABLE secret SEALED, permanently. Every open reveal request on it becomes CANCELLED. A sealed secret can never be made revealable again. Needs MANAGE.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
Response
The secret object, with mode set to SEALED.
curl https://api.autessa.com/autessa_poweruser/secrets/seal \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"secretId": "6d0a4b2c-1f9e-4c73-a5b8-2e7d9c0f1a64"}'
Delete Secret POST/delete
Deletes the secret and erases its value. Tools that still use it fail with SECRET_USE_DENIED. Needs MANAGE.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
Response
- Name
deleted- Type
- boolean
- Description
truewhen the secret was deleted.
curl https://api.autessa.com/autessa_poweruser/secrets/delete \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"secretId": "3f6c2a9e-8d41-4b7a-9c0e-5b2f1d7a4e10"}'
{ "deleted": true }
Get Audit Log POST/audit
Returns the secret's audit events. Needs MANAGE.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
pageSize- Type
- integer
- Description
Maximum number of events to return. Defaults to 50; at most 200.
- Name
pageToken- Type
- string
- Description
The
nextPageTokenfrom the previous response.
Response
- Name
events- Type
- array<object>
- Description
- Name
nextPageToken- Type
- string
- Description
Pass as
pageTokento get the next page. Absent on the last page.
curl https://api.autessa.com/autessa_poweruser/secrets/audit \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"secretId": "3f6c2a9e-8d41-4b7a-9c0e-5b2f1d7a4e10", "pageSize": 100}'
Request a Reveal POST/reveal-request
Asks to see the value of a REVEALABLE secret. A different person with MANAGE must approve the request. Needs REVEAL. On a SEALED secret this fails with SECRET_SEALED. A request nobody decides on expires after 7 days.
Request Body
- Name
secretId- Type
- string
- Description
ID of the secret.
- Name
reason- Type
- string
- Description
Why you need the value, up to 500 characters. Shown to approvers and kept in the audit log.
Response
The reveal request object, with status PENDING.
curl https://api.autessa.com/autessa_poweruser/secrets/reveal-request \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{
"secretId": "6d0a4b2c-1f9e-4c73-a5b8-2e7d9c0f1a64",
"reason": "Logging in to the vendor portal to download the Q3 invoices."
}'
List Reveal Requests POST/reveal-requests
Lists reveal requests you made, or requests waiting for you to approve or deny.
Request Body
- Name
scope- Type
- string
- Description
MINE(the default) for requests you made, orTO_APPROVEfor other people's requests on secrets you haveMANAGEon.
- Name
secretId- Type
- string
- Description
Only requests for this secret.
- Name
status- Type
- string
- Description
Only requests in this status:
PENDING,APPROVED,DENIED,EXPIRED,USED, orCANCELLED.
Response
- Name
requests- Type
- array<object>
- Description
curl https://api.autessa.com/autessa_poweruser/secrets/reveal-requests \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"scope": "TO_APPROVE", "status": "PENDING"}'
Approve a Reveal POST/reveal-approve
Approves a pending request. The requester then has 15 minutes to view the value, once. Needs MANAGE. Nobody can approve their own request: that fails with SELF_APPROVAL_NOT_ALLOWED, even for the owner.
Request Body
- Name
requestId- Type
- string
- Description
ID of the reveal request.
Response
The reveal request object, with status APPROVED and expiresAt 15 minutes from now.
curl https://api.autessa.com/autessa_poweruser/secrets/reveal-approve \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"requestId": "b7e1c0d4-2a95-4f3e-8c61-0d9a7f2e5b38"}'
Deny a Reveal POST/reveal-deny
Denies a request that is pending, or approved but not yet used. Needs MANAGE.
Request Body
- Name
requestId- Type
- string
- Description
ID of the reveal request.
- Name
reason- Type
- string
- Description
Why the request was denied. Shown to the requester.
Response
The reveal request object, with status DENIED.
curl https://api.autessa.com/autessa_poweruser/secrets/reveal-deny \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"requestId": "b7e1c0d4-2a95-4f3e-8c61-0d9a7f2e5b38", "reason": "Use the shared vendor login instead."}'
Cancel a Reveal POST/reveal-cancel
Withdraws a request. Only the person who made it can cancel it.
Request Body
- Name
requestId- Type
- string
- Description
ID of the reveal request.
Response
The reveal request object, with status CANCELLED.
curl https://api.autessa.com/autessa_poweruser/secrets/reveal-cancel \
-H "Authorization: $POWERUSER_KEY" \
-H "Content-Type: application/json" \
-d '{"requestId": "b7e1c0d4-2a95-4f3e-8c61-0d9a7f2e5b38"}'
Reveal the Value POST/reveal
Returns the value for an approved request, once. On success the request becomes USED; to see the value again, make a new request.
- Only the person who made the request can call it.
- The request must be
APPROVEDand within 15 minutes of approval. - The requester must still have
REVEALaccess. If it was removed after approval, the call fails withINSUFFICIENT_SECRET_PERMISSION. - Only a person can reveal: in the builder, or with
autessa secrets revealsigned in with their own CLI login. On this Poweruser path the call always fails withMACHINE_IDENTITY_CANNOT_REVEAL, as it does for app client keys, script and tool executions, public app site keys, and scheduled or triggered runs.
Request Body
- Name
requestId- Type
- string
- Description
ID of the approved reveal request.
Response
- Name
value- Type
- string
- Description
The secret value.
- Name
secretName- Type
- string
- Description
Name of the secret.
- Name
version- Type
- integer
- Description
The secret's version at the time of the reveal.
autessa secrets reveal --requestId b7e1c0d4-2a95-4f3e-8c61-0d9a7f2e5b38
{
"value": "Wint3r-Harbor-2026!",
"secretName": "vendor-portal-password",
"version": 3
}
From a custom app: SecretService
Custom apps built from the Autessa app template include a SecretService that wraps these endpoints with the same request style as the template's other services. It has create, list, get, update, rotate, seal, and delete, each taking the request body documented above and returning the same response.
As with the app's other poweruser calls, the app must be allowed the secrets endpoints it uses in its hosting permissions.
// Adjust the relative path to the template's autessa/services folder.
import { SecretService } from "./autessa/services/secret";
const secret = await SecretService.create({
name: "acme-api-key",
mode: "SEALED",
value: formValues.apiKey,
allowedHosts: ["api.acme.com"],
});
const { secrets } = await SecretService.list({ search: "acme" });
await SecretService.rotate({ secretId: secret.secretId, value: formValues.newApiKey });
SecretService has no reveal methods, and an app's own credentials can't reveal a value. An app is a good place to let people enter or rotate a key; reading it back is only possible for a signed-in person, in the builder or the CLI.
Errors
Errors return the HTTP status below and a body with the code and a plain-language message:
{
"errors": ["You need Manage access to this secret to rotate it."],
"errorCode": "INSUFFICIENT_SECRET_PERMISSION",
"error": {
"code": "INSUFFICIENT_SECRET_PERMISSION",
"message": "You need Manage access to this secret to rotate it."
}
}
| Code | HTTP | When |
|---|---|---|
SECRET_NOT_FOUND | 404 | No secret with that ID or name, or you have no access to it. |
SECRET_NAME_TAKEN | 409 | Another secret in the company already has that name. |
INVALID_SECRET_NAME | 400 | The name doesn't follow the naming rules. |
INVALID_ALLOWED_HOSTS | 400 | allowedHosts is empty or has more than 50 entries, or an entry isn't a plain hostname (for example it has a wildcard, scheme, path, or port). |
INVALID_SECRET_REQUEST | 400 | Another field is missing or invalid: no value, an unknown mode, a value over 16 KB, a missing or too-long reason, an unknown scope or status, a bound tool that isn't one of your company's tools, or a bad pageToken. |
SECRET_SEALED | 403 | A reveal was requested or attempted on a SEALED secret. |
INSUFFICIENT_SECRET_PERMISSION | 403 | Your access level doesn't allow this operation, or your Reveal access was removed after your request was approved. |
SELF_APPROVAL_NOT_ALLOWED | 403 | You tried to approve your own reveal request. |
REVEAL_REQUEST_NOT_APPROVED | 409 | /reveal was called on a request that isn't approved, or was already used. |
REVEAL_REQUEST_EXPIRED | 409 | More than 15 minutes have passed since approval. Make a new request. |
MACHINE_IDENTITY_CANNOT_REVEAL | 403 | /reveal was called on the Poweruser path, or by an app key, a script or tool execution, a site key, or a scheduled or triggered run. |