Channels
Access IdentityScribe through LDAP, REST, GraphQL, or MCP. All channels use the same query engine, so they behave consistently.
What are channels?
Section titled “What are channels?”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.
Channel comparison
Section titled “Channel comparison”| Channel | Protocol | Use case | Status |
|---|---|---|---|
| LDAP | LDAP v3 | Enterprise integrations, legacy systems, LDAP-native tools | Stable |
| REST | HTTP/JSON | Web applications, BFF patterns, automation | Stable |
| GraphQL | HTTP/GraphQL | Flexible queries, frontend-driven data fetching | Stable |
| MCP | HTTP/SSE + JSON-RPC | AI coding assistants (Cursor, Claude, VS Code) | Experimental |
| gRPC | HTTP/2 + Protobuf | High-throughput service-to-service | Roadmap |
Common concepts
Section titled “Common concepts”Authentication
Section titled “Authentication”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
Section titled “Authorization”Authorization is handled at the directory level, not per-channel. Permissions are evaluated during query execution based on the authenticated principal.
Pagination
Section titled “Pagination”Channels support pagination appropriate to their protocol:
| Channel | Pagination Style | Parameters |
|---|---|---|
| LDAP | Simple Paged Results, VLV | LDAP controls |
| REST | Relay-style cursor pagination | first/after, last/before, limit |
| GraphQL | Relay Connection spec | first/after, last/before |
| MCP | Cursor pagination | limit/after |
Error handling
Section titled “Error handling”All channels share the unified failure model documented in Failures. Errors are mapped to protocol-appropriate responses:
| Channel | Error Format |
|---|---|
| LDAP | ResultCode + diagnostic message |
| REST | HTTP status + JSON body + error headers |
| GraphQL | errors array with extensions |
| MCP | JSON-RPC error with code + message |
| gRPC | Status code + google.rpc.Status details |
See Failures for the complete error contract, retry guidance, and troubleshooting.
Entry identifiers
Section titled “Entry identifiers”Every entry can be referenced using any of these formats:
| Format | Example | When to use |
|---|---|---|
| GlobalId | dXNlcjo5aXg | Fastest lookup (use the id from results) |
| UUID | 550e8400-e29b-41d4-a716-446655440000 | Integration with external systems |
| UOID | 12345 | Legacy numeric references |
| DN | cn=john,ou=users,dc=example,dc=com | LDAP compatibility |
All channels accept all formats. GlobalId is recommended for performance since the entry type is encoded in the ID.
Operational attributes
Section titled “Operational attributes”Every entry response includes metadata:
| Attribute | Description |
|---|---|
id | GlobalId for efficient lookups |
dn | Distinguished Name (LDAP path) |
entryType | Type name (User, Group, etc.) |
uuid | RFC 4122 UUID |
etag | Change tracking token |
createTimestamp | When created |
modifyTimestamp | When last modified |
verifiedTimestamp | When last verified against source |
Temporal references
Section titled “Temporal references”Time-based parameters support flexible formats for expressing timestamps and durations. These work consistently across all channels.
Supported formats
Section titled “Supported formats”| Format | Example | Description |
|---|---|---|
| ISO-8601 timestamp | 2024-12-24T10:30:00Z | Full timestamp with timezone |
| Partial date | 2024, 2024-12, 2024-12-24 | Expanded to midnight UTC |
| Partial date-time | 2024-12-24T10, 2024-12-24T10:30 | Expanded with missing components |
| ISO duration | P7D, PT1H, P1M | 7 days, 1 hour, 1 month ago |
| HOCON duration | 7d, 1h, 30m, 2w | Human-friendly durations |
now keyword | now | Current time |
| Relative expression | now-1h, now+30m, now-7d | Relative to current time |
| Day keywords | yesterday, today, tomorrow | Midnight UTC of the day |
| Period keywords | this week, last month, this year | Start of period (midnight UTC) |
| Relative periods | last 3 days, last 2 hours | N units ago from now |
| LDAP generalized time | 20241224103000Z | Legacy LDAP format |
Where used
Section titled “Where used”Temporal lookup (at parameter):
Point-in-time queries to view entry state at a specific moment.
# View entry state as it was 1 hour agocurl "/api/users/123?at=now-1h"
# View entry state on a specific datecurl "/api/users/123?at=2024-01-15"Changes API (range, since, until):
Query entry change history within a time window.
# Changes in the last 24 hourscurl "/api/users/123/changes?since=now-1d"
# Changes between two datescurl "/api/users/123/changes?since=2024-01-01&until=2024-02-01"
# Last 7 days of changescurl "/api/users/123/changes?range=7d"Filter expressions: Use temporal references in filter comparisons on timestamp attributes.
# Users modified in the last hourcurl "/api/users?filter=modifyTimestamp ge now-1h"
# Users created this weekcurl "/api/users?filter=createTimestamp ge now-7d"
# Users not verified in over 30 dayscurl "/api/users?filter=verifiedTimestamp lt now-30d"All three timestamp attributes (createTimestamp, modifyTimestamp, verifiedTimestamp) support temporal references in filter expressions.
Observability
Section titled “Observability”All channels emit metrics and traces through the unified observability stack:
Core metrics
Section titled “Core metrics”| Metric | Description |
|---|---|
scribe.channel.requests.total | Request count by channel, operation, result |
scribe.channel.request.duration.seconds | Request latency histogram |
scribe.channel.inflight | Currently processing requests |
Trace spans
Section titled “Trace spans”Channel requests create root spans named {Channel}.{Operation} (e.g., LDAP.Search, REST.GET), with nested spans for each query pipeline stage.
Channel discovery
Section titled “Channel discovery”The /observe/channels endpoint exposes enabled channels and their runtime binding information:
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.
API discovery (RFC 9727)
Section titled “API discovery (RFC 9727)”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:
curl -s http://localhost:8080/.well-known/api-catalogReturns 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.
Configuration
Section titled “Configuration”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.
Related documentation
Section titled “Related documentation”- LDAP Channel Guide — Configuration and usage for the LDAP channel
- REST Channel Guide — Configuration and usage for the REST channel
- GraphQL Channel Guide — Configuration and usage for the GraphQL channel
- MCP Channel Guide — AI coding assistant integration via Model Context Protocol
- Failures — Error codes, retry guidance, and troubleshooting
- Observability — Metrics, traces, and operational playbooks
- Configuration Guide — General configuration reference