Tenancy & access
Everything in OSPulse belongs to a tenant. Repositories, scans, policies, alerts, tokens, settings, audit records — none of them exist outside one. Understanding the tenant boundary is the fastest way to reason about who can see what, what a token can do, and what happens to your data at the end.
The tenant is the isolation boundary
A tenant is the organisation-level container and the unit of isolation. There is no cross-tenant read path: a query issued in one tenant cannot return another tenant's rows, and this is enforced at the data layer rather than left to individual endpoints to remember.
That single fact explains a lot of the API's shape:
- Nothing takes a tenant identifier. You never pass one, because your credential
already determines it. Tenant-level endpoints are addressed as
/api/v1/tenants/current/...for exactly this reason. - Identifiers are only meaningful inside a tenant. A repository ID from one tenant
returns
404in another — not403, because from that tenant's perspective the object genuinely does not exist. - Settings are tenant-wide by default. Scoring weights, retention, benchmark profile and feature flags apply to everything in the tenant, not per repository.
Within a tenant, repositories can be organised further — by workspace, team, business criticality and lifecycle status — and those attributes are what policies, alert rules and reporting scope against. They are organisational structure, not security boundaries. The security boundary is the tenant.
One tenant or several?
Use separate tenants when you need genuine data isolation — a subsidiary with its own compliance obligations, or a customer estate you manage on their behalf. Use workspaces and teams inside one tenant when you want structure but shared policy, shared scoring and a single view of risk. Splitting tenants to model an org chart costs you the aggregate picture that made the product useful.
Users and roles
Human access is per user, and each user's capability inside the tenant is determined by the role they hold. The model separates three things deliberately:
- Authentication — proving who you are. Handled by password or by your identity provider through SSO.
- Membership — belonging to a tenant. Granted by invitation or provisioned automatically through SCIM.
- Authorisation — what you may do once inside. Determined by role.
Roles range from full administrative control over tenant configuration, through day-to-day operational roles that can trigger scans and triage findings, down to read-only roles intended for auditors and reporting consumers — people who legitimately need to see the risk picture and pull evidence out of it, but must not be able to change policy, grant exceptions or alter settings.
That read-only tier matters more than it first appears. Compliance reviewers, internal audit and customer-security teams all need access to the same evidence your engineers see. Giving them a role that cannot mutate anything is what lets you say yes without widening your blast radius.
Removing a user is explicit:
curl -X DELETE https://api.ospulse.app/api/v1/users/{userId} \
-H "Authorization: Bearer $OSPULSE_TOKEN"The exact roles available to you are listed in the tenant's user administration screen and depend on your plan. Configure the identity side of this in SSO & SCIM.
API tokens act within a tenant
A token is not a separate identity class with its own permission universe. It is a credential that acts inside one tenant with a bounded scope. Create one with:
curl -X POST https://api.ospulse.app/api/v1/api-tokens \
-H "Authorization: Bearer $OSPULSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-policy-gate",
"roleScopeJson": "{\"roles\":[\"read\"]}",
"expiresAtUtc": "2027-01-31T00:00:00Z"
}'Three properties are required, and each is required for a reason:
namestringRequiredA human-readable label. This is what appears in the token list and in audit records, so
it should identify the consumer — ci-policy-gate, warehouse-sync — not the person
who happened to create it.
roleScopeJsonstringRequiredThe role scope the token carries. A token should hold the narrowest scope that lets its consumer do its job: a CI gate needs to read dependencies and evaluate policy, not to delete repositories or reconfigure SSO.
expiresAtUtcdate-timeRequiredAn expiry. Mandatory rather than optional, because an unbounded credential is a credential nobody will ever rotate. A token that expires forces a rotation event you can plan, instead of a leak you discover.
List tokens with GET /api/v1/api-tokens and revoke immediately with
DELETE /api/v1/api-tokens/{apiTokenId}. The token value itself is shown once at creation
and is not recoverable — see Authentication.
One token per consumer
Sharing a single token across CI, a reporting job and a local script means you cannot revoke one without breaking the others, and the audit log cannot tell you which of them made a call. Issue a token per consumer and the incident response writes itself.
SSO and SCIM
For any organisation past a handful of people, identity should not live in OSPulse.
SSO delegates authentication to your identity provider, so account lifecycle, MFA policy and session control stay where they already are. Read the current configuration:
curl https://api.ospulse.app/api/v1/auth/sso \
-H "Authorization: Bearer $OSPULSE_TOKEN"Configure it with POST /api/v1/auth/sso/configure.
SCIM closes the gap SSO leaves. SSO controls whether someone can sign in; it does not by itself tell OSPulse that a leaver's account should cease to exist, or that someone moving teams should change role. SCIM provisioning makes your identity provider the source of truth for membership: users are created, updated and deactivated in OSPulse as a consequence of changes in the directory.
OSPulse exposes a standard SCIM 2.0 service at /scim/v2/, including
ServiceProviderConfig, ResourceTypes and Schemas for discovery, full user lifecycle
under /scim/v2/Users, and group listing at /scim/v2/Groups.
The deprovisioning gap is the one that bites
Joiners are self-correcting — someone complains within a day if access is missing. Leavers are silent. SCIM is worth configuring almost entirely for the offboarding half.
Tenant settings
Four categories of tenant-wide configuration change how OSPulse behaves for everything inside the boundary.
Scoring weights
Health scoring combines several components, and the weighting between them is a judgement about what your organisation actually cares about.
curl https://api.ospulse.app/api/v1/tenants/current/scoring-weights \
-H "Authorization: Bearer $OSPULSE_TOKEN"Adjust with PATCH /api/v1/tenants/current/scoring-weights. Because weights are
tenant-wide, changing them re-frames every score in the tenant at once — which is the
point, but means it is not a change to make casually. Health snapshots record the weights
in force when they were captured, so historical scores remain interpretable after a
change.
Benchmark profile
GET and PATCH /api/v1/tenants/current/benchmark-profile describe your organisation —
size band, sector and similar — so comparative analytics compare you against a meaningful
peer set rather than the whole population. Benchmarking is opt-in
(PUT /api/v1/analytics/benchmark/opt-in); an inaccurate profile produces a comparison
that is precisely wrong.
Retention
GET and PATCH /api/v1/settings/retention govern how long historical data is kept —
scan history, logs, audit records. Retention is a genuine trade-off rather than a
"higher is better" setting: longer retention gives you deeper trend analysis and a fuller
evidence trail, at the cost of holding more data than some data-protection positions want
you to. Set it from your obligations, not from instinct.
Feature flags
GET /api/v1/feature-flags lists the capability flags in effect for the tenant, and
PATCH /api/v1/feature-flags/{key} toggles those you control. Flags let a tenant adopt
new behaviour on its own schedule rather than having it arrive with a deployment.
Usage and entitlements
Your plan defines entitlements — how many repositories, how much scanning, which capabilities. Current consumption against those limits is a single call:
curl https://api.ospulse.app/api/v1/tenants/current/usage \
-H "Authorization: Bearer $OSPULSE_TOKEN"The response separates counters (what you have used) from quotas (what you are entitled to), which is what makes it useful to alert on. Watching the ratio lets you discover you are approaching a limit while there is still time to do something about it, rather than when an import starts failing.
Billing-side detail — the subscription itself, plan catalogue and invoices — lives under
/api/v1/billing/. Plan limits vary; see pricing.
Getting your data out
Two mechanisms, for two different needs.
Full tenant export produces a complete archive of your tenant's data, asynchronously:
curl -X POST https://api.ospulse.app/api/v1/tenants/current/data-export \
-H "Authorization: Bearer $OSPULSE_TOKEN"It returns 202 Accepted and processes in the background. This is the right tool for
migration, for a data-subject or regulatory request, and for the "can we get our data
back?" question that should be answered before you adopt any platform, not after.
Continuous export to your own analytics estate is a different problem, solved by
warehouse export destinations under /api/v1/analytics/export/ — see
Warehouse export. Use tenant export for a point-in-time
copy and warehouse export for an ongoing feed.
SBOM generation (POST /api/v1/sbom/export) is narrower still: a standards-formatted
inventory for a specific consumer. See SBOM generation.
Deleting a tenant
Tenant deletion is the one genuinely irreversible operation in the API.
curl -X DELETE https://api.ospulse.app/api/v1/tenants/current \
-H "Authorization: Bearer $OSPULSE_TOKEN"This destroys the tenant and everything in it
Deletion removes repositories, scan history, findings, policies, exceptions, audit records and settings for the entire tenant. It is not a soft delete you can walk back, and support cannot restore a deleted tenant. Run a full data export first, confirm you have the archive, and confirm the credential you are using belongs to the tenant you intend to delete — the endpoint has no tenant identifier to check against, because it always acts on your own.
The endpoint requires appropriate administrative permission and may return 202 where
deletion is processed asynchronously, or 204 where it completes immediately.
Audit logging
Every consequential action in a tenant is recorded: who did it, what changed, when, and from which actor type — a user, an API token, or the system itself.
curl https://api.ospulse.app/api/v1/audit-log \
-H "Authorization: Bearer $OSPULSE_TOKEN"For evidence bundles and external review, GET /api/v1/audit-log/export produces the same
records in an exportable form.
The audit log is what makes the rest of this page verifiable rather than merely stated. It is where you demonstrate that a policy exception was granted deliberately and by whom, that a departed engineer's token was revoked on the day they left, and that nobody quietly lowered a scoring weight before a compliance review. Treat it as the primary evidence surface it is: export it on a schedule, and give your auditors a read-only role rather than screenshots.
