Machine authentication
Your integrations authenticate to bb-sign with an API credential and operate under the same isolation guarantees as a member of the organization. An admin creates the credential in Settings, tab API credentials; the workspace roles assigned to it determine what it can do. This page is normative.
A single identity model
Section titled “A single identity model”A machine authenticates with OAuth2 client credentials against the bbsign realm. bb-sign
processes its token with the same code that processes a person’s token, because Keycloak issues
both the same way:
- A Keycloak service account is a real user record, not a user-less principal.
- The same attribute mapper that adds the
bb_sign_org_idclaim to a person’s token adds it to the machine token, from an attribute on the service-account user. - Every org-scoping decision goes through a single point in the API, which reads that claim regardless of the grant type.
As a result, org isolation is inherited: a machine token is scoped by the same check as a person’s.
Obtain a token
Section titled “Obtain a token”curl -s -X POST https://auth.binarybridges.co/realms/bbsign/protocol/openid-connect/token \ -d grant_type=client_credentials \ -d client_id=<your-client-id> \ -d client_secret=<your-secret>{ "access_token": "eyJ...", "expires_in": 300, "token_type": "Bearer" }Send it as a bearer token on every request:
curl -H "Authorization: Bearer $TOKEN" https://sign-api.binarybridges.co/api/v1/envelopesRequired claims
Section titled “Required claims”| Claim | Value | Purpose |
|---|---|---|
bb_sign_org_id |
The owning org’s UUID | Every org-scoped read and write resolves from this value. If it is missing, the API returns 403 (see Error statuses) |
realm_access.roles |
contains org_api |
The role the organization-scoped endpoints admit |
aud |
contains bb-sign |
If absent, the audience validator rejects the token before authorization is evaluated |
Without the audience mapper, the token fails validation; without the org attribute, it fails authorization. In both cases access is denied. Credentials created from Settings carry all three claims.
Credential scope
Section titled “Credential scope”At organization level a credential holds only label:read and workspace:read: it can list the
label keys and the workspaces it belongs to. What it can do with envelopes depends on the role
it holds in each workspace. When the credential is created, the form asks for a workspace and a
role: “General with Manager is the default.” An admin can later add it to other workspaces from
Settings, tab Workspaces, section Members.
| Permission | viewer | auditor | contributor | manager |
|---|---|---|---|---|
envelope:read | Yes | Yes | Yes | Yes |
archive:read | Yes | Yes | Yes | Yes |
audit:read | No | Yes | Yes | Yes |
document:download | No | Yes | Yes | Yes |
envelope:create | No | No | Yes | Yes |
envelope:update | No | No | Yes | Yes |
document:upload | No | No | Yes | Yes |
label:assign | No | No | Yes | Yes |
envelope:send | No | No | Yes | Yes |
envelope:cancel | No | No | No | Yes |
GET /api/v1/workspacesreturns General and the workspaces the credential holds a role in. Send one’sidasworkspaceIdwhen creating an envelope; if you omit it, the envelope is filed in General.- A credential can belong to at most 50 workspaces.
- A role change applies when the credential’s next token is issued, so within 300 s.
- The org is always taken from the token, never from the request. A machine does not send an
orgIdwhen creating an envelope; if it does, the envelope’s organization does not change.
Permissions reserved for people
Section titled “Permissions reserved for people”A credential never receives these organization permissions, even if an admin tries to grant them. They are escalation guards in the permission catalog:
credential:managewebhook:manageworkspace:manageworkspace:manage-membersworkspace:access-all
Organizations, users, quotas, certificates, labels, the archive, the audit trail, credentials,
webhooks and workspaces are managed in the UI by an org admin. The signing ceremony
(/api/v1/sign/**) is public by design and scoped to one signer by the token in its link;
integrations do not use it.
The two kinds of denial are deliberately distinct:
| Request | Response |
|---|---|
| An operation the credential lacks the organization permission for | 403, no body |
| An envelope or workspace the credential cannot see, or one that does not exist | 404, identical to “does not exist” |
Error statuses
Section titled “Error statuses”| Status | Meaning | Usual cause | Action |
|---|---|---|---|
401 |
No token, expired token, or a token the realm will not validate | Missing Authorization header; token older than 300 s |
Request a new token; check the Bearer prefix |
403 on a workflow endpoint |
Authenticated, but not permitted at organization level | Calling a management operation that exists only in the UI | Confirm the operation exists in the API reference |
403 on GET /api/v1/envelopes specifically |
The token carries org_api but not bb_sign_org_id |
A credential not created from Settings | Revoke it and create a new one in Settings, tab API credentials |
404 on an envelope or workspace |
The credential holds no role in that workspace, or the id is wrong | A workspace never assigned to the credential | Ask an admin to add the credential under Members, or use General |
In the case of the third row, access is denied: a token without the org claim receives no organization’s data.
Token lifetime and revocation
Section titled “Token lifetime and revocation”- A token is valid for 300 s and is not validated by introspection.
- Revoke stops new tokens immediately. The confirmation states that requests using a token already obtained may keep succeeding until that token expires: “revoking does not cut access that is already in flight.” The credential is listed as Revoked — draining until the last token it issued expires, then as Revoked, and stays listed for 90 days. When responding to a leak, treat the credential as active until that time has passed.
- Rotate replaces the secret with no grace period: “The current secret stops working immediately. Any integration using it will fail until you redeploy it with the new secret.”
- An organization can hold at most 10 active credentials.
Create a credential
Section titled “Create a credential”An org admin creates credentials from the UI:
- Open Settings, tab API credentials, and select New credential.
- Give it a label that identifies the system that will use it and, under Access, choose the workspace and the role.
- Copy the Client ID and the Client secret. The secret is shown once: it is stored only in Keycloak and bb-sign keeps no copy.
- Deliver both values to the system that will use them through its secret store, never through source control or chat.
Management from the UI is described in API credentials.