Skip to main content

Document-Level Security

Document-Level Security (DLS) automatically injects filters into queries based on the authenticated user's role. This ensures users only see documents they are authorized to access without application-level enforcement.

Implementation is in services/storage-engine/src/security/dls.rs.

Policy Model

A DLS policy defines a filter that is applied to all queries matching a specific database, collection, and user role:

{
"id": "policy_001",
"database": "mydb",
"collection": "documents",
"role": "authenticated",
"filter": "{\"owner_id\": {\"$eq\": \"$auth.user_id\"}}",
"enabled": true
}
FieldDescription
databaseTarget database name
collectionTarget collection name
roleUser role this policy applies to
filterJSON filter with $auth.* variable placeholders
enabledWhether the policy is active

Auth Variable Resolution

Filters can reference the authenticated user's properties using $auth.* variables. These are resolved at query time from the JWT claims:

VariableResolved To
$auth.user_idAuthenticated user's ID
$auth.emailAuthenticated user's email
$auth.roleAuthenticated user's role

Example

Policy filter:

{"owner_id": {"$eq": "$auth.user_id"}}

For a user with ID usr_abc123, the resolved filter becomes:

{"owner_id": {"$eq": "usr_abc123"}}

Filter Injection

The DLS middleware reads the AuthContext from the request, looks up matching policies for the target database and collection, resolves $auth.* variables, and injects the merged filter via the X-DLS-Filter header. The CRUD handler merges this with any user-supplied filter using $and.

Multiple Policies

When multiple policies match the same request, they are merged with $and:

{
"$and": [
{"owner_id": {"$eq": "usr_abc123"}},
{"department": {"$eq": "engineering"}}
]
}

Service Role Bypass

Requests authenticated with a service role API key bypass DLS entirely. This allows administrative operations and background jobs to access all documents without restriction.

# Service role  -  no DLS filtering
// Service role connections bypass DLS
mongosh "mongodb://service-user:password@localhost:27017"

// Authenticated user connections have DLS filters applied
mongosh "mongodb://alice:password@localhost:27017"

CRUD Examples

Users See Only Their Documents

Policy:

{
"database": "mydb",
"collection": "notes",
"role": "authenticated",
"filter": "{\"user_id\": {\"$eq\": \"$auth.user_id\"}}"
}

When Alice (user ID usr_alice) queries:

// Alice connects via MongoDB driver
mongosh "mongodb://alice:password@localhost:27017/mydb"
db.notes.find()

The query is executed with filter: {"user_id": {"$eq": "usr_alice"}}.

Team-Based Access

Policy:

{
"database": "mydb",
"collection": "projects",
"role": "authenticated",
"filter": "{\"team_members\": {\"$in\": [\"$auth.email\"]}}"
}

This restricts each user to projects where their email appears in the team_members array.

Inserts and Updates

DLS filters apply to all operations, not just reads. An update targeting documents outside the user's DLS scope will match zero documents.

Source of Truth

  • DLS engine: services/storage-engine/src/security/dls.rs
  • Security module: services/storage-engine/src/security/