Skip to content

Credential Vault

Most sensors don't take a raw secret inline. Instead they reference a secret stored in the named credential vault by its id. You create the credential once, then point one or more sensors at it. The sensor worker resolves the id to the decrypted secret at poll time — the secret is never written into a sensor_configs row and never echoed back by the API.

The vault is org-scoped and admin-only: every endpoint requires an org admin. Credentials are shared between sensors and action channels that consume the same secret shape (a GitHub PAT, for example, is one github_token credential whether a sensor or a GitHub Issue action channel uses it).

Credential types

Each credential has a type that declares its shape. The types a sensor can reference:

TypeUsed bySecret shape
github_tokenGitHub sensorGitHub PAT with read access to the org/repos
slack_bot_tokenSlack sensorBot token, xoxb-…
google_service_account_jsonGoogle Meet, Google Drive sensorsFull service-account key JSON
jira_api_tokenJira sensorAtlassian Cloud API token
shellcrm_api_keyshell-crm sensorshell-crm API key (client_id:client_secret)

Other types (slack_webhook, generic_webhook) exist for action channels and are not referenced by sensors. The Jenkins sensor uses no vault credential — its webhook token is generated server-side at create time.

The live list for your instance:

bash
curl -sS https://your-corveil-host/api/credentials/types \
  -H "Authorization: Bearer <admin-session-or-key>"

Returns each registered type with its human-readable display name.

Create a credential

POST /api/credentials

json
{
  "type": "github_token",
  "name": "acme-readonly-pat",
  "secret": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
bash
curl -sS -X POST https://your-corveil-host/api/credentials \
  -H "Authorization: Bearer <admin-session-or-key>" \
  -H "Content-Type: application/json" \
  -d '{"type":"github_token","name":"acme-readonly-pat","secret":"ghp_..."}'

The response echoes the stored credential's metadata — including its id — but never the secret. The secret is validated at write time for the given type, so a malformed value is rejected with a 400 before it lands in the vault.

Copy the returned id; that's what you put in a sensor's credentials block.

List, read, update, delete

Method & pathPurpose
GET /api/credentialsList all credentials (metadata only). Add ?type=github_token to filter.
GET /api/credentials/{id}Fetch one credential's metadata.
PATCH /api/credentials/{id}Rename ({"name": "..."}) or rotate the secret ({"secret": "..."}).
DELETE /api/credentials/{id}Remove a credential.

How a sensor references a credential

When you create a sensor, the credentials block holds the credential id (a UUID), not the secret:

json
{
  "sensor_type": "github",
  "name": "Acme GitHub",
  "config": { "org": "acme" },
  "credentials": { "token": "6f1c2b8e-0a4d-4d6a-9f2e-1c3b5a7d9e11" }
}

The token key is the credential field the GitHub sensor declares; its value is the id returned by POST /api/credentials. Every sensor guide in this section lists exactly which credential type its credential field expects.

The Add sensor UI renders a dropdown of matching credentials for each credential field, so you rarely assemble this JSON by hand — but the same shape is what the API expects for programmatic setup.