Skip to content

Credential Vault

In the v0.4.3 dashboard this vault lives under Connections → Credentials. The mechanics below are unchanged; only the navigation moved.

Most sources 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 sources at it. The source's poll 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 the sensors that ingest and the Workers that act — anything consuming the same secret shape reuses one credential (a GitHub PAT, for example, is one github_token credential whether a GitHub sensor reads with it or a GitHub-issue Worker writes with it).

Credential types

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

TypeUsed bySecret shape
github_tokenGitHub sourceGitHub PAT with read access to the org/repos
slack_bot_tokenSlack sensor; slack_bot Worker delivery channel (UI label Slack Bot); @corveil chatBot token, xoxb-… (chat:write / reactions:write to deliver and ACK)
slack_signing_secretSlack Events API (/webhooks/slack/{token})Signing Secret from the Slack app Basic Information page — not the bot token
google_service_account_jsonGoogle Meet, Google Calendar, Google Drive, Gmail sourcesFull service-account key JSON
jira_api_tokenJira and Confluence Cloud sourcesAtlassian Cloud API token
linear_api_keyLinear sourceLinear personal API key (lin_api_…)
asana_patAsana sourceAsana personal access token (opaque; often 1/{gid}:{secret})
monday_api_tokenMonday.com sourceMonday.com personal API token
notion_tokenNotion sourceNotion internal integration token (ntn_… or legacy secret_…)
airtable_patAirtable sourceAirtable personal access token (pat…). Not a retired API key or an OAuth access token.
zoom_s2s_oauthZoom Transcripts sourceZoom Server-to-Server OAuth JSON: {"account_id","client_id","client_secret"}
atlassian_dc_patJira Data Center and Confluence Data Center sourcesData Center personal access token (opaque; no ATATT prefix)
shellcrm_api_keyshell-crm sourceshell-crm API key (client_id:client_secret)
microsoft_graphMicrosoft Teams, SharePoint / OneDrive, Outlook Calendar, and Outlook (email) sourcesEntra ID app registration as JSON: {"tenant_id","client_id","client_secret"}
gitlab_tokenGitLab sourceGitLab personal / group / project access token (glpat-…); read_api
bitbucket_access_tokenBitbucket sourceBitbucket Cloud access token (preferred), app password, or Atlassian API token
hubspot_access_tokenHubSpot sourceHubSpot private-app token or account Service Key (pat-…)
intercom_access_tokenIntercom sourceIntercom private-app access token (Authorization: Bearer). Not an OAuth marketplace token.
salesforce_connected_appSalesforce sourceConnected App JSON: {"login_url","client_id","client_secret"}
greenhouse_harvest_api_keyGreenhouse sourceGreenhouse Harvest API key (HTTP Basic username, empty password). Not a Job Board token.
lever_api_keyLever sourceLever API key (HTTP Basic username, empty password). Not an OAuth partner token.
workday_api_clientWorkday sourceWorkday API Client JSON: {"host","tenant","client_id","client_secret","refresh_token"}
pagerduty_api_keyPagerDuty sourcePagerDuty REST API key (Authorization: Token token=…). Not an OAuth access token.
zendesk_api_tokenZendesk sourceZendesk API token (HTTP Basic username {email}/token). Agent email and subdomain are sensor config, not this secret.
bamboohr_api_keyBambooHR sourceBambooHR API key (HTTP Basic username, password x). Company subdomain is sensor config, not this secret.
rippling_api_tokenRippling sourceRippling REST API token (Authorization: Bearer). Not an OAuth app-install token.
gusto_api_clientGusto sourceGusto App Integrations OAuth JSON: {"client_id","client_secret","refresh_token","redirect_uri","environment"?}. Refresh tokens are single-use; Corveil rotates the vault row after mint.
gong_access_keyGong sourceJSON {"access_key","access_key_secret"} from Gong Company Settings → API
aws_access_keyAmazon S3 source (optional)JSON {"access_key_id","secret_access_key","session_token"?}. Omit the credential to use the AWS default chain.

Other types (slack_webhook, generic_webhook) exist for Worker delivery channels and are not referenced by sensors. The Jenkins and Webhook sources use no vault credential — their webhook tokens are 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 source'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 source references a credential

When you create a source, 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 source declares; its value is the id returned by POST /api/credentials. Every source 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.