Skip to main content

SCIM/OAA Integration Specification

Implementation status:

  • SCIM 2.0 endpoints: [Planned] — designed but not yet implemented in sv0-platform.
  • OAA export endpoints: [Deferred] — export is a read-only projection layer. Implementation deferred until customer need. See ADR-009.
  • Entity model: Updated to 9-type system per ADR-006.

Overview

SecurityV0 adopts industry-proven patterns from SCIM (System for Cross-domain Identity Management) and OAA (Open Authorization API) to enable interoperability with the broader identity security ecosystem.

Strategic rationale:

  • Follow proven patterns — OAA's authorization model is battle-tested across enterprise deployments (Snowflake, Choice Hotels)
  • Minimize client integration effort — clients already using SCIM/OAA patterns integrate with minimal mapping
  • Preserve SecurityV0 differentiators — ownership decay, temporal drift, and evidence packs remain unique capabilities

This specification does NOT define integration with any specific vendor. It defines how SecurityV0 adopts industry patterns where applicable.


OAA Alignment [Deferred]

OAA export is a read-only projection layer. Implementation deferred until customer need. See ADR-009.

What OAA Provides

OAA (Open Authorization API) defines a standardized schema for representing authorization metadata:

OAA ConceptSecurityV0 Internal TypeOAA Export EntityMapping FidelityNotes
Local Useridentitylocal_userHIGHAuthenticating NHIs map directly to OAA users
Resource (automation)automationresource (type: automation)HIGHOAA resources support custom types
Resource (connection)connectionresource (type: connection)HIGHConnection configs are resources in OAA's model
Custom propertycredentialCustom property on local_userMEDIUMOAA has no first-class credential entity
Local User (human)ownerlocal_user (type: human)HIGHHuman owners map to OAA users with human type marker
Local Rolerolelocal_roleHIGHDirect mapping
Custom Permissionpermissioncustom_permissionHIGHOAA supports custom permission definitions
ResourceresourceresourceHIGHDirect mapping
(not exported)execution_evidence(not exported)N/AOAA has no execution evidence concept

What is Lost in OAA Export

Internal ConceptOAA EquivalentLoss
Execution chainsNoneFull loss — OAA has no chain concept
Typed execution edges (CALLS, INVOKES, USES, AUTHENTICATES_AS)Generic can_accessSemantic loss — edge types collapsed
Credential as first-class entityCustom propertyStructural loss — can't query credentials independently
Temporal tracking (first_seen, last_seen, drift)NoneFull loss — OAA is point-in-time
Evidence packsNoneFull loss — OAA has no evidence model

What SecurityV0 Adds Beyond OAA

CapabilityOAASecurityV0
Ownership hierarchyNot modeledOwner entity with decay tracking
Credential lifecycleNot modeledCredential entity (first-class) with rotation status
Execution chainsNot modeledTyped chain: automation → connection → credential → identity
Temporal versioningSnapshots onlyPoint-in-time queries, drift detection
Evidence artifactsNot modeledSealed, immutable evidence packs
Automation classificationResources onlyDedicated automation type with subtypes and execution_mode

OAA Export Specification [Deferred]

OAA export is a read-only projection layer. Implementation deferred until customer need. See ADR-009.

Endpoint: List Applications [Deferred]

GET /api/v1/oaa/applications

Response:

{
"applications": [
{
"id": "app-uuid-1",
"application_type": "entra_id",
"name": "contoso-prod",
"description": "Contoso production Entra ID tenant",
"last_sync_at": "2026-02-06T10:30:00Z",
"entity_counts": {
"identities": 15,
"automations": 87,
"connections": 12,
"roles": 38,
"permissions": 512,
"resources": 89
}
}
],
"total": 1
}

Endpoint: Get Application Payload [Deferred]

GET /api/v1/oaa/applications/{id}

Response (OAA-compatible payload):

{
"application_type": "entra_id",
"name": "contoso-prod",
"description": "Contoso production Entra ID tenant",

"local_users": [
{
"id": "sp-uuid-1",
"name": "sp-hr-onboarding",
"email": null,
"is_active": true,
"created_at": "2025-03-10T00:00:00Z",
"last_login_at": "2026-02-06T10:15:00Z",
"user_type": "service_principal",
"identities": [
{
"identity_type": "azure_ad",
"identity_value": "sp-uuid-1"
}
],
"custom_properties": {
"sv0_identity_subtype": "service_principal",
"sv0_execution_mode": "autonomous"
}
}
],

"local_groups": [],

"local_roles": [
{
"id": "role-uuid-1",
"name": "Application.ReadWrite.All",
"permissions": ["perm-uuid-1", "perm-uuid-2"],
"custom_properties": {
"sv0_is_privileged": true
}
}
],

"permissions": [
{
"id": "perm-uuid-1",
"name": "Application.ReadWrite.All",
"permission_type": ["MetadataWrite"],
"apply_to_sub_resources": true,
"resource_types": ["application"],
"custom_properties": {
"sv0_canonical_type": "MetadataWrite",
"sv0_is_privileged": true,
"sv0_is_delegatable": false,
"sv0_raw_permission": "Application.ReadWrite.All"
}
}
],

"resources": [
{
"id": "resource-uuid-1",
"name": "All Applications",
"resource_type": "application",
"sub_resources": []
}
],

"identity_to_permissions": [
{
"identity": {
"id": "sp-uuid-1",
"identity_type": "local_user"
},
"apply_to_application": false,
"permission": "perm-uuid-1",
"resource": "resource-uuid-1"
}
],

"custom_properties": {
"sv0_tenant_id": "tenant-uuid-1",
"sv0_connector_id": "entra-connector-1",
"sv0_last_sync_at": "2026-02-06T10:30:00Z"
}
}

OAA Permission Type Mapping [Deferred]

OAA uses permission_type arrays. SecurityV0 maps canonical types:

SecurityV0 Canonical TypeOAA permission_type
DataReadDataRead
DataWriteDataWrite
DataCreateDataCreate
DataDeleteDataDelete
MetadataReadMetadataRead
MetadataWriteMetadataWrite
MetadataCreateMetadataCreate
MetadataDeleteMetadataDelete
NonDataNonData
UncategorizedUncategorized

SCIM 2.0 Specification [Planned]

SecurityV0 exposes a read-only SCIM 2.0 API for identity discovery by IGA and PAM tools.

Service Provider Configuration

GET /scim/v2/ServiceProviderConfig

Response:

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
"documentationUri": "https://docs.securityv0.io/scim",
"patch": {
"supported": false
},
"bulk": {
"supported": false
},
"filter": {
"supported": true,
"maxResults": 1000
},
"changePassword": {
"supported": false
},
"sort": {
"supported": true
},
"etag": {
"supported": true
},
"authenticationSchemes": [
{
"type": "oauthbearertoken",
"name": "OAuth Bearer Token",
"description": "Authentication via OAuth 2.0 Bearer Token"
}
]
}

Schema Discovery

GET /scim/v2/Schemas

Returns SecurityV0's SCIM schemas including:

  • urn:ietf:params:scim:schemas:core:2.0:User (standard)
  • urn:ietf:params:scim:schemas:core:2.0:Group (standard)
  • urn:securityv0:scim:schemas:extension:nhi:1.0 (SecurityV0 NHI extension)

Resource Types

GET /scim/v2/ResourceTypes

Response:

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"],
"Resources": [
{
"id": "User",
"name": "User",
"endpoint": "/Users",
"schema": "urn:ietf:params:scim:schemas:core:2.0:User",
"schemaExtensions": [
{
"schema": "urn:securityv0:scim:schemas:extension:nhi:1.0",
"required": false
}
]
},
{
"id": "Group",
"name": "Group",
"endpoint": "/Groups",
"schema": "urn:ietf:params:scim:schemas:core:2.0:Group"
}
]
}

List Users (Identities)

GET /scim/v2/Users
GET /scim/v2/Users?filter=userType eq "service_principal"
GET /scim/v2/Users?filter=active eq true and userType eq "oauth_app"

Only entities of type identity are exposed via SCIM /Users. Entities of type automation, connection, and credential are not SCIM users and are not returned by this endpoint.

Response:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 142,
"itemsPerPage": 100,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:securityv0:scim:schemas:extension:nhi:1.0"
],
"id": "sp-uuid-1",
"userName": "sp-hr-onboarding",
"displayName": "HR Onboarding Service Principal",
"userType": "service_principal",
"active": true,
"meta": {
"resourceType": "User",
"created": "2025-03-10T00:00:00Z",
"lastModified": "2026-02-06T10:30:00Z",
"version": "W/\"abc123\""
},
"urn:securityv0:scim:schemas:extension:nhi:1.0": {
"identitySubtype": "service_principal",
"executionMode": "autonomous",
"applicationId": "app-uuid-1",
"applicationName": "contoso-prod",
"lastActivityAt": "2026-02-06T10:15:00Z",
"ownershipStatus": "orphaned",
"findingCount": 2
}
}
],
"urn:ietf:params:scim:api:messages:2.0:cursorPagination": {
"nextCursor": "cursor-abc123",
"previousCursor": null
}
}

Get Single User

GET /scim/v2/Users/{id}

List Groups (Teams/Owners)

GET /scim/v2/Groups

Maps SecurityV0 Owner entities (team type) to SCIM Groups.

Write Operations

All write operations return HTTP 501 Not Implemented:

POST /scim/v2/Users → 501
PUT /scim/v2/Users/{id} → 501
PATCH /scim/v2/Users/{id} → 501
DELETE /scim/v2/Users/{id} → 501

Rationale: SecurityV0 is read-only toward source systems. It discovers and catalogs identities but does not provision or deprovision them.


NHI Extension Schema [Planned]

SecurityV0 defines a SCIM extension for NHI (Non-Human Identity) attributes:

Schema URI: urn:securityv0:scim:schemas:extension:nhi:1.0

AttributeTypeDescription
identitySubtypestringSubtype of the identity entity. Values: service_principal, oauth_app, machine_account, integration_user
executionModestringExecution mode of the identity. Values: autonomous, operator_assisted, human_triggered, unknown
applicationIdstringReference to containing Application
applicationNamestringHuman-readable application name
lastActivityAtdateTimeLast execution timestamp
ownershipStatusstringowned, degraded, orphaned
findingCountintegerNumber of active findings
credentialStatusstringactive, expired, expiring_soon
canonicalPermissionsstring[]List of canonical permission types held

Non-identity entity types (automation, connection, credential) are not exposed via SCIM /Users. These entities are not SCIM users. When SCIM resource discovery is needed, a future /ResourceTypes extension or separate resource endpoint would be required.


Pagination

SCIM Cursor Pagination (RFC 9865)

SecurityV0 implements cursor-based pagination for SCIM endpoints:

GET /scim/v2/Users?count=100

Response includes:

{
"totalResults": 5000,
"itemsPerPage": 100,
"Resources": [...],
"urn:ietf:params:scim:api:messages:2.0:cursorPagination": {
"nextCursor": "cursor-abc123",
"previousCursor": null
}
}

Next page:

GET /scim/v2/Users?cursor=cursor-abc123&count=100

OAA Pagination [Deferred]

OAA export uses offset-based pagination:

GET /api/v1/oaa/applications?offset=0&limit=100

Authentication

Both SCIM and OAA endpoints require authentication:

  • OAuth 2.0 Bearer Token (recommended)
  • API Key (via X-API-Key header)

All requests must be tenant-scoped. The authenticated principal determines which Applications and Identities are visible.


Error Responses

SCIM Errors

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "401",
"scimType": "unauthorized",
"detail": "Invalid or expired token"
}

OAA Errors [Deferred]

{
"error": "not_found",
"message": "Application not found",
"application_id": "app-uuid-unknown"
}

Integration Examples

SailPoint IdentityNow

Configure SCIM source connector:

  1. Base URL: https://api.securityv0.io/scim/v2
  2. Auth: OAuth 2.0 Bearer Token
  3. Filter: userType eq "service_principal"

Saviynt EIC

Configure SCIM connector for NHI discovery:

  1. Endpoint: https://api.securityv0.io/scim/v2/Users
  2. Import non-human identities into Saviynt's identity warehouse
  3. Correlate with application accounts via applicationId

OAA Consumer (Generic) [Deferred]

For tools that consume OAA-format payloads:

  1. Fetch application list: GET /api/v1/oaa/applications
  2. For each application, fetch full payload: GET /api/v1/oaa/applications/{id}
  3. Import identities, permissions, resources into authorization graph

References