Data model
Scribe stores identity data as entries. Each entry has a type, identifiers, attributes, and a history of changes. See Architecture for how these fit into the sync and query pipeline. Click any element below to jump to its reference section.
How entries, identifiers, attributes, and events relate
Entry identifiers
Section titled “Entry identifiers”Every entry can be referenced by four formats. All channels accept all formats.
| Format | Example | When to use |
|---|---|---|
| GlobalId | dXNlcjo5aXg | Fastest lookup — use the id from query results |
| UUID | 550e8400-e29b-41d4-a716-446655440000 | External system integration |
| UOID | 12345 | Legacy numeric references |
| DN | cn=john,ou=users,dc=example,dc=com | LDAP compatibility |
GlobalId is the recommended default. It’s URL-safe (no escaping needed), stable (assigned once, never changes), and fast (the entry type is encoded in the ID, so lookups skip type resolution). The canonical attribute name is entryID, with id as a convenience alias. Treat it as an opaque string.
Attributes
Section titled “Attributes”Entries carry three categories of attributes: user data synced from the source directory, operational metadata managed by Scribe, and virtual attributes computed at query time.
Operational attributes
Section titled “Operational attributes”Every entry carries metadata alongside user-defined data. Request them with the + directive (REST: ?fields=+, LDAP: add + to the attribute list) or by name.
| Canonical | Aliases | Purpose |
|---|---|---|
entryID | id | URL-safe global identifier |
entryUOID | uoid | Internal numeric database row ID |
entryDN | dn | Distinguished Name (full LDAP path) |
entryUUID | uuid, objectGUID, nsuniqueid, guid, ibm-entryuuid, dominoUNID | RFC 4122 UUID with product-specific aliases |
entryType | type | Entry type name (User, Group, etc.) |
entryRDN | rdn, relativeDN | Path relative to the entry type’s base DN |
entryName | — | First RDN value (the “simple name”) |
eTag | etag, entryCSN, revision | Change tracking token |
createTimestamp | createdAt, whenCreated | Creation time |
modifyTimestamp | updatedAt, whenChanged | Last modification time |
verifiedTimestamp | verifiedAt, lastVerifiedAt | Last verification against source |
Responses always use canonical names, even when you request an alias. Both forms work in filters and projections.
Entry naming
Section titled “Entry naming”Two attributes give shorter alternatives to the full DN:
entryName— the name portion. Forcn=John Doe,ou=users,dc=example,dc=com, entryName isJohn Doe. Uses an indexed SQL function for fast lookups.entryRDN— the path relative to the type’s configured base. For the same entry under baseou=users,dc=example,dc=com, entryRDN iscn=John Doe.
Both support case-insensitive filtering, sorting, and projection across all channels.
Virtual attributes
Section titled “Virtual attributes”Some attributes are computed at query time rather than stored. The classic example is memberOf, which finds all groups containing a user without storing membership on the user entry.
Virtual attributes are configured per transcribe. See Transcribes configuration for the full syntax.
Entry types
Section titled “Entry types”An entry type groups directory entries of the same kind — users, groups, devices. Each type maps to a transcribe that defines what to sync (base DN, filter, scope, attributes, indexes).
See Architecture > Transcribes for how entry types work in the sync pipeline.
Change events
Section titled “Change events”Every change Scribe detects produces an immutable event:
Every change recorded, any point in time queryable
| Type | Carries |
|---|---|
| add | Full attribute set of the new entry |
| modify | Diff — which attribute changed, how, and to what value |
| move | Old and new DN |
| delete | Entry identifier |
Events are append-only. Each has a unique position (commit + index) and a timestamp. The entries table is a materialized view derived from these events — nothing is ever updated or deleted in the event log. This is what makes point-in-time queries and full audit history possible.
See Architecture > Events for how change detection works.
Change data formats
Section titled “Change data formats”MODIFY events provide three representations of the change. All use delta semantics (what changed, not the full state):
| Format | Description | When to use |
|---|---|---|
diff | Attribute-level operations: SET, ADD, REMOVE | Internal processing, full detail |
patch | JSON Patch style with /attribute/- for array additions | JSON Patch-compatible consumers |
merge | JSON Merge Patch style with changed values only | Simple consumers that just want the new values |
data { ... on ModifyData { diff { attribute operation value } patch { operation path value } merge { attribute values } }}All three formats are available in the GraphQL and REST channels.
Temporal references
Section titled “Temporal references”Time-based parameters (at, since, until, range) accept flexible formats: ISO timestamps, durations, relative expressions (now-1h), and natural language (yesterday, last 3 days). See Filters > Temporal references for the complete format table.