Home/Credentials/Personal credentials ENУКРРУС API Reference (ReDoc) ↗

Personal credentials

CRUD on your own keys — the owner comes from the token, the secret never comes back.

Personal credentials belong to one user: the server sets owner_type=user and owner_id to the sub of your token on every call. Request bodies never name an owner, and another user's records are invisible to you — their ids answer the same 404 as nonexistent ones.

The lifecycle in six endpoints

Step Endpoint
Create POST /v1/credentials
List / read GET /v1/credentials · GET /v1/credentials/{id}
Rename / rotate PATCH /v1/credentials/{id}
Default switch POST .../make-default
Pause / resume POST .../disable · POST .../enable
Delete DELETE /v1/credentials/{id}

Creation validates the secret against the provider's credential_schema, encrypts it, and stores non-secret configuration alongside. Deprecated providers refuse new records (409); the provider must also admit the user level at all (409 OWNER_TYPE_NOT_ALLOWED_FOR_PROVIDER otherwise).

Roles: user and provider_admin mutate; auditor reads only (403 on writes). All under the shared read/mutation budgets.

Masking: what reads return

Every read returns masked_credentials instead of the secret: long values keep a recognizable head/tail (sk-1***abcd), short and high-risk fields (e.g. client_secret) are masked entirely. The mask is recomputed from plaintext on every write, so after a rotation the mask changes too — a cheap way to confirm the rotation took. Configuration is returned as stored, in the open.

Plaintext exists for the API in exactly two places, neither on this plane: machine resolve and operator reveal.

Rotation is replacement

PATCH with a credentials object replaces the whole secret object — there is no per-field merge. That is deliberate: a rotation is "here is the new key", validated against the schema and re-encrypted with the active key. Optimistic locking is mandatory (version in the body or If-Match); a stale version is 409 CREDENTIAL_VERSION_CONFLICT. PATCH never touches status or is_default — those have dedicated transitions (Defaults and Lifecycle).

Worked example: cookbook scenario 03.

Deletion is soft, but immediate

DELETE removes the record from every list and from resolve at once; the ciphertext survives a recovery window (default 5 days) before physical purge, and repeating the delete is an idempotent 204. There is no undelete endpoint — recovery within the window is an operator action.