Booting neural core...
Booting neural core...
portal.cybernethicc.com/api/v1Vault is a password manager, Secret Send and a Secrets Manager for your apps. This API is the programmatic surface: read Secrets Manager values from CI, scripts and servers with a service token, and open Secret Send links. Everything else (items, organisations, KMS, certificates, SSH CA, privileged access, scanning) is used through the Portal.
Zero-knowledge boundary
Plaintext of stored items and Secret Send payloads is encrypted in your browser before reaching the server. The API endpoints in this reference deal inciphertext_b64,iv_b64, andtag_b64, encryption keys never leave your client.
Two auth mechanisms, depending on the endpoint.
Service tokens are scoped to a single Secret Project + optional environment list. They carry the key material needed to decrypt that project's secrets server-side, so the holder never needs the master password. Used by CI runners, scripts, and tunnel clients.
Authorization: Bearer cyb_<token_id_prefix>_<key_fragment>Mint a service token from portal.cybernethicc.com/vault → project → Service tokens. The plaintext is shown once at creation; rotate by issuing a new one and revoking the old.
Secret Send links carry a URL-safe token in the path. No header needed. The token is consumed on first successful read for burn-on-read secrets.
GET /api/v1/public/vault/secrets/<url_token>Public, programmatic Vault endpoints. JWT-only routes (item CRUD, vault unlock, passkey, TOTP) are not listed, those are driven by the portal UI.
/api/v1/public/vault/secretsFetch decrypted secrets via service token/api/v1/public/vault/secrets/{token}Consume a Secret Send (burn-on-read)/api/v1/public/vault/secrets/{token}Open a password-protected Secret Send/api/v1/vault/secretsCreate a Secret Send (Portal session only)/api/v1/vault/secrets/{id}Revoke a Secret Send (Portal session only)The common CI pattern: store credentials in a Vault Secret Project, issue a service token scoped to that project + environment, and read values from a script.
/api/v1/public/vault/secrets| Field | Required | Notes |
|---|---|---|
env | no | Environment slug (e.g. prod, staging). Token must include this env in its scope. |
decrypt | no | Set to server for server-side decryption using the key fragment in the token. Omit to get ciphertext (for client-side decrypt). |
curl -fsS "https://portal.cybernethicc.com/api/v1/public/vault/secrets?env=prod&decrypt=server" \
-H "Authorization: Bearer cyb_6fc0b1c2789ed180_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"{
"project_slug": "billing-api",
"env_slug": "prod",
"values": {
"DB_PASSWORD": "s3cret-prod-pw",
"STRIPE_API_KEY": "sk_live_..."
}
}401 { "error": { "code": "UNAUTHORIZED", "message": "Token revoked or unknown" } }
401 { "error": { "code": "UNAUTHORIZED", "message": "Missing Authorization header" } }
403 { "error": { "code": "FORBIDDEN", "message": "Token has no access to the requested env(s)" } }Audit trail. Every fetch with a service token writes a row to the Vault audit log (visible in the portal). The row records the project, the token name/id prefix, the env, the source IP, and the user agent.
Receive-side endpoint for the public Secret Send link. Returns the encrypted blob plus metadata; decrypt locally using the password / key fragment shipped out-of-band.
/api/v1/public/vault/secrets/{token}curl -fsS https://portal.cybernethicc.com/api/v1/public/vault/secrets/abc123def456{
"data": {
"ciphertext_b64": "GpKx...",
"iv_b64": "qY1n...",
"tag_b64": "lZmd...",
"burn_on_read": true,
"views_remaining": 0,
"has_password": false
}
}Each successful read counts as a view. Once the last view is used (immediately for a burn-on-read secret) the link stops working and later requests return 404. A password-protected secret answers the GET with {"data":{"password_required":true}}; send the password with POST to the same URL as {"password":"..."}. A wrong password returns 403, and too many wrong attempts lock the link for an hour (429).
404 { "error": { "code": "NOT_FOUND", "message": "Secret not found or already viewed" } }
403 { "error": { "code": "FORBIDDEN", "message": "Wrong password." } }
429 { "error": { "code": "TOO_MANY_REQUESTS", "message": "Too many wrong passwords. Try again in an hour." } }Service tokens have three pieces of state inside them, packed into a single bearer string:
Token format:
cyb_<token_id_prefix>_<base64url_key_fragment>Authorization: Bearer. Every use writes an audit row with IP + user agent.401 UNAUTHORIZED.Treat the token like a password. Anyone holding the plaintext can read every secret in the token's scope. Do not commit tokens to git; do not paste them into shared chats. Use the portal's built-in Secret Send (with a burn-on-read link) to hand a token to a teammate.
App secrets for your services, organised as projects and environments (for example dev, staging, prod). Every value is encrypted with a per-project key before it is stored. You manage projects in the Portal and read them from your apps with a service token.
.env file into an environment in one step.A command-line client, cybernethicc-secrets, wraps this API (list, get, pull to a .env file, and run -- your-command with the secrets as environment variables). Ask support for a build for your platform.
Two modes. The default keeps the service zero-knowledge at request time: you receive ciphertexts and decrypt them with the key fragment inside your token. decrypt=server returns plaintext over TLS, which is the easy path for shell scripts and CI.
# plaintext, one environment
curl -fsS "https://portal.cybernethicc.com/api/v1/public/vault/secrets?env=prod&decrypt=server" \
-H "Authorization: Bearer cyb_<token_id_prefix>_<key_fragment>"{
"project_slug": "billing-api",
"env_slug": "prod",
"values": {
"DATABASE_URL": "postgres://...",
"REDIS_URL": "redis://..."
}
}Without env, every environment the token can read is returned under envs. In server mode a value can reference another key in the same environment with ${KEY}, which is resolved before it is returned.
# load straight into a shell
eval "$(curl -fsS "https://portal.cybernethicc.com/api/v1/public/vault/secrets?env=prod&decrypt=server" \
-H "Authorization: Bearer $CYB_TOKEN" | jq -r '.values | to_entries[] | "export \(.key)=\(.value|@sh)"')"Default (client) mode returns the wrapped project key and the encrypted values:
{
"project_slug": "billing-api",
"pek_wrap_b64": "...",
"pek_iv_b64": "...",
"pek_tag_b64": "...",
"envs": [
{ "slug": "prod", "name": "Production",
"kv": [ { "key_name": "DATABASE_URL", "value_ct": "...", "value_iv": "...", "value_tag": "...", "current_version": 3 } ] }
],
"note": "Use the key fragment from your token to unwrap pek_wrap, then decrypt each kv value with PEK."
}Key rings and keys that never leave the server. Encrypt and decrypt data, sign and verify, and generate envelope data keys. Keys can be rotated to a new version and disabled when no longer needed.
/api/v1/vault/kms/keys/{id}/encryptEncrypt with a key/api/v1/vault/kms/keys/{id}/decryptDecrypt/api/v1/vault/kms/keys/{id}/data-keyEnvelope data key/api/v1/vault/kms/keys/{id}/signSign/api/v1/vault/kms/keys/{id}/rotateNew key versionRun your own certificate authority for internal services. Issue and revoke certificates, check their status, and publish a CRL (PEM or DER). Private keys are sealed and only revealed through an audited action.
/api/v1/vault/cert/cas/{id}/issueIssue a certificate/api/v1/vault/cert/certs/{id}/revokeRevoke/api/v1/vault/cert/cas/{id}/crlCertificate revocation listLet's Encrypt certificates issued through a DNS-01 challenge on domains hosted at Cloudflare, Amazon Route 53 or Google Cloud DNS, with automatic renewal.
Replace long-lived SSH keys with short-lived OpenSSH certificates. Add the CA public key to your servers once, then sign user or host certificates on demand.
# on each server, trust the CA once
echo "TrustedUserCAKeys /etc/ssh/cybernethicc_ca.pub" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl reload sshdRegister sensitive resources and grant access just in time. Someone requests access, the owner approves or denies it, and an approved grant is valid for a bounded window. For SSH resources the grant produces an ephemeral certificate from the SSH CA, so nobody keeps standing credentials.
Finds leaked credentials using provider patterns plus entropy checks. Scan on demand in the Portal, record findings to track them, or install the pre-commit hook script from the Portal. Scanned content is discarded; only a redacted preview of each finding is kept.
Shared vaults with collections, member invites and roles (owner, admin, user).
Upload your identity provider's metadata XML (Okta, Azure AD / Entra ID, Google Workspace and other SAML 2.0 IdPs) in the organisation settings. The Portal then shows the service provider metadata URL, the ACS URL and the login URL to register in your IdP. Turn on require SSO to refuse password login for the organisation.
Enable SCIM for the organisation to get a bearer token, then point your IdP at the SCIM base URL https://portal.cybernethicc.com/api/v1/scim/v2. Users created, updated or deactivated in the IdP follow automatically. Groups are not synced; assign roles in the Portal. The token is per organisation and can be rotated from the Portal.
/api/v1/scim/v2/ServiceProviderConfigCapabilities, read by the IdP/api/v1/scim/v2/UsersList users/api/v1/scim/v2/Users/{id}Read one user/api/v1/scim/v2/UsersProvision a user/api/v1/scim/v2/Users/{id}Replace a user/api/v1/scim/v2/Users/{id}Update or deactivate/api/v1/scim/v2/Users/{id}RemoveAll error responses share the same shape:
{
"error": {
"code": "FORBIDDEN",
"message": "Token has no access to the requested env(s)"
}
}| Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST | Malformed input (e.g. body not JSON, missing required field). |
| 401 | UNAUTHORIZED | Missing or invalid auth, revoked or unknown service token. |
| 403 | FORBIDDEN | Not allowed: env not in the token scope, a feature your plan does not include, or a wrong Secret Send password. |
| 404 | NOT_FOUND | Secret already viewed, expired, or never existed. |
| 429 | TOO_MANY_REQUESTS | Daily Secret Send limit on the Free plan, or too many wrong Secret Send passwords. |
| 500 | INTERNAL_ERROR | Server side. Open a support ticket and quote the response timestamp. |