Skip to content

Channels

Access IdentityScribe through LDAP, REST, GraphQL, or MCP. All channels use the same query engine, so they behave consistently.

Channels are the front door to IdentityScribe:

  • LDAP — Standard directory protocol for enterprise integrations
  • REST — HTTP/JSON API for modern web applications
  • GraphQL — Flexible query API for frontend-driven data fetching
  • MCP — Model Context Protocol for AI coding assistants
  • gRPC — High-performance binary protocol (roadmap)

All channels share the same directory pipeline (normalize → plan → compile → execute). Behavior and observability are identical across protocols.

ChannelProtocolUse caseStatus
LDAPLDAP v3Enterprise integrations, legacy systems, LDAP-native toolsStable
RESTHTTP/JSONWeb applications, BFF patterns, automationStable
GraphQLHTTP/GraphQLFlexible queries, frontend-driven data fetchingStable
MCPHTTP/SSE + JSON-RPCAI coding assistants (Cursor, Claude, VS Code)Experimental
gRPCHTTP/2 + ProtobufHigh-throughput service-to-serviceRoadmap

LDAP bind authentication is available today. Unified JWT bearer token authentication is on the roadmap — when available, the same token will work across all channels.

Authorization is handled at the directory level, not per-channel. Permissions are evaluated during query execution based on the authenticated principal.

Channels support pagination appropriate to their protocol:

ChannelPagination StyleParameters
LDAPSimple Paged Results, VLVLDAP controls
RESTRelay-style cursor paginationfirst/after, last/before, limit
GraphQLRelay Connection specfirst/after, last/before
MCPCursor paginationlimit/after

All channels share the unified failure model documented in Failures. Errors are mapped to protocol-appropriate responses:

ChannelError Format
LDAPResultCode + diagnostic message
RESTHTTP status + JSON body + error headers
GraphQLerrors array with extensions
MCPJSON-RPC error with code + message
gRPCStatus code + google.rpc.Status details

See Failures for the complete error contract, retry guidance, and troubleshooting.

Every entry can be referenced using any of these formats:

FormatExampleWhen to use
GlobalIddXNlcjo5aXgFastest lookup (use the id from results)
UUID550e8400-e29b-41d4-a716-446655440000Integration with external systems
UOID12345Legacy numeric references
DNcn=john,ou=users,dc=example,dc=comLDAP compatibility

All channels accept all formats. GlobalId is recommended for performance since the entry type is encoded in the ID.

Every entry response includes metadata:

AttributeDescription
idGlobalId for efficient lookups
dnDistinguished Name (LDAP path)
entryTypeType name (User, Group, etc.)
uuidRFC 4122 UUID
etagChange tracking token
createTimestampWhen created
modifyTimestampWhen last modified
verifiedTimestampWhen last verified against source

Time-based parameters support flexible formats for expressing timestamps and durations. These work consistently across all channels.

FormatExampleDescription
ISO-8601 timestamp2024-12-24T10:30:00ZFull timestamp with timezone
Partial date2024, 2024-12, 2024-12-24Expanded to midnight UTC
Partial date-time2024-12-24T10, 2024-12-24T10:30Expanded with missing components
ISO durationP7D, PT1H, P1M7 days, 1 hour, 1 month ago
HOCON duration7d, 1h, 30m, 2wHuman-friendly durations
now keywordnowCurrent time
Relative expressionnow-1h, now+30m, now-7dRelative to current time
Day keywordsyesterday, today, tomorrowMidnight UTC of the day
Period keywordsthis week, last month, this yearStart of period (midnight UTC)
Relative periodslast 3 days, last 2 hoursN units ago from now
LDAP generalized time20241224103000ZLegacy LDAP format

Temporal lookup (at parameter): Point-in-time queries to view entry state at a specific moment.

Terminal window
# View entry state as it was 1 hour ago
curl "/api/users/123?at=now-1h"
# View entry state on a specific date
curl "/api/users/123?at=2024-01-15"

Changes API (range, since, until): Query entry change history within a time window.

Terminal window
# Changes in the last 24 hours
curl "/api/users/123/changes?since=now-1d"
# Changes between two dates
curl "/api/users/123/changes?since=2024-01-01&until=2024-02-01"
# Last 7 days of changes
curl "/api/users/123/changes?range=7d"

Filter expressions: Use temporal references in filter comparisons on timestamp attributes.

Terminal window
# Users modified in the last hour
curl "/api/users?filter=modifyTimestamp ge now-1h"
# Users created this week
curl "/api/users?filter=createTimestamp ge now-7d"
# Users not verified in over 30 days
curl "/api/users?filter=verifiedTimestamp lt now-30d"

All three timestamp attributes (createTimestamp, modifyTimestamp, verifiedTimestamp) support temporal references in filter expressions.

All channels emit metrics and traces through the unified observability stack:

MetricDescription
scribe.channel.requests.totalRequest count by channel, operation, result
scribe.channel.request.duration.secondsRequest latency histogram
scribe.channel.inflightCurrently processing requests

Channel requests create root spans named {Channel}.{Operation} (e.g., LDAP.Search, REST.GET), with nested spans for each query pipeline stage.

The /observe/channels endpoint exposes enabled channels and their runtime binding information:

Terminal window
curl -s http://localhost:8080/observe/channels | jq '.channels'

Returns channel status, connection URLs, and actual bound ports (useful for ephemeral port 0). See Monitoring Guide for details.

The /.well-known/api-catalog endpoint provides machine-readable API discovery per RFC 9727. Clients can discover all available HTTP API channels and their schema URLs from a single endpoint:

Terminal window
curl -s http://localhost:8080/.well-known/api-catalog

Returns a Linkset document with service-desc (schema URLs) and service-doc (documentation/playground URLs) for each enabled channel:

{
"linkset": [
{
"anchor": "/api",
"service-desc": [
{"href": "/api.json", "type": "application/json"},
{"href": "/api.yaml", "type": "application/yaml"}
],
"service-doc": [
{"href": "/api", "type": "text/html"},
{"href": "/docs/channels/rest", "type": "text/html"}
]
},
{
"anchor": "/graphql",
"service-desc": [
{"href": "/graphql.json", "type": "application/json"},
{"href": "/graphql.sdl", "type": "application/graphql"}
],
"service-doc": [
{"href": "/graphql", "type": "text/html"},
{"href": "/docs/channels/graphql", "type": "text/html"}
]
}
]
}

See RFC 9727 for the full specification.

See Observability for metrics, traces, and operational playbooks.

Channels are configured in the channels namespace. HTTP-based channels (REST, GraphQL) use the unified HTTP server with named sockets.

# HTTP server configuration (shared by REST, GraphQL, monitoring)
http {
port = 8080
host = auto # localhost in dev, 0.0.0.0 in production
}
channels {
# LDAP uses dedicated listeners
ldap {
listen = [
{ port = 10389 }
{ port = 10636, ssl { ... } }
]
}
# REST channel (serves at /api on the default HTTP socket)
rest {
enabled = true
# socket = "@default" # Optional: use named socket for separation
ui.enabled = true
}
}

See HTTP Server Configuration for socket binding, TLS, and named socket separation. See individual channel guides for detailed configuration options.