Expand description
Rule-based access control for the MCP SQLite server.
This module implements the permission system that decides which SQL
operations the server may execute. Permissions are configured at startup
through the --allow and --deny CLI flags, each taking an access control
selector that identifies the operation — and optionally the exact resources
— the rule applies to.
§Selector syntax
Every SQLite authorization action (Read, Insert, CreateTable,
DropIndex, Function, etc.) has a corresponding selector type. A selector
is written as:
Action— matches all operations of that type (every field defaults to the wildcard*).Action(value)— pins the first field to a specific value; remaining fields stay as wildcards.Action(value1.value2)— pins both fields.Action(*.value2)— wildcard first field, pinned second field.
For example, the Read selector has two fields (table_name and
column_name):
| CLI flag | Meaning |
|---|---|
--allow Read | allow all column reads |
--deny Read(Secrets) | deny reads on Secrets |
--allow Read(Secrets.id) | allow reads on Secrets.id |
--deny Read(*.ssn) | deny reads on any ssn column |
§Specificity
Each selector has a specificity equal to the number of its fields that are
pinned to concrete values (i.e. not *). A bare Read has specificity 0,
Read(Students) has specificity 1, and Read(Students.name) has
specificity 2. More specific rules always outrank less specific ones.
§Resolution algorithm
When SQLite asks “is this operation allowed?”, the AuthorizationResolver
evaluates rules as follows:
-
Collect matching rules. For each configured rule whose selector covers the requested operation (globs match anything, values must match exactly), note its specificity.
-
Most specific wins. Rules are evaluated from the highest specificity level to the lowest. The first level that contains at least one matching rule determines the outcome.
-
Deny breaks ties. If both allow and deny rules match at the same specificity level, the result is deny (fail-closed).
-
Default fallback. If no rule matches at any level, the per-action default is used. The default depends on how the resolver was constructed (e.g.
AuthorizationResolver::new_allow_everything).
One sentence summary: the most specific matching rule wins; ties go to deny; no match defers to the default.
§Examples
§Read-only server with one table blocked
--allow Read --deny Read(Secrets)All column reads are allowed except anything touching the Secrets table.
Read(Secrets) has specificity 1 which beats the blanket Read at
specificity 0, so the deny wins for any column in Secrets.
§Read-only with a carve-out
--allow Read --deny Read(Secrets) --allow Read(Secrets.id)All reads are allowed. Reads on Secrets are denied — except for the id
column, which is explicitly re-allowed at specificity 2 (both fields
pinned), beating the specificity-1 deny.
§Conflicting rules at the same specificity
--deny Read(Students) --allow Read(*.name)A read on Students.name matches both rules. Read(Students) has
specificity 1 (table pinned, column glob) and Read(*.name) also has
specificity 1 (table glob, column pinned). Because both match at the same
level, deny wins. To allow Students.name, add a more specific rule:
--allow Read(Students.name) (specificity 2).
§Deny everything, allow specific functions
--deny Function --allow Function(count) --allow Function(sum)All SQL function calls are denied except count and sum, which win at
specificity 1 over the blanket deny at specificity 0.
§Lock down DDL while permitting reads and inserts
--allow Read --allow Insert --allow Select --allow TransactionWith a deny-everything default, only the explicitly allowed actions proceed.
All DDL (CreateTable, DropIndex, etc.) remains denied because no allow
rule exists for those actions.
§Code generation
The define_access_control_selector_types! macro generates the selector
structs, the AccessControlSelector enum, the
AccessControlSelectorSet, and the AuthorizationResolver from a set
of struct declarations. Each struct’s field types are wrapped in
ValueOrGlob so that every field can independently be a concrete value or
a wildcard. The macro also generates Display / FromStr round-tripping,
builder methods, and the specificity-aware resolution logic described above.
Structs§
- Access
Control Selector Set - Holds all configured access control rules, grouped by selector type and indexed by specificity.
- Alter
Table - Selector for
ALTER TABLEstatements, scoped to a database and table. - Analyze
- Selector for
ANALYZEstatements, scoped to a table. - Attach
- Selector for
ATTACH DATABASEstatements, scoped to a filename. - Authorization
Resolver - Resolves incoming SQLite authorization requests against a set of configured allow/deny rules and per-action default permissions.
- Create
Index - Selector for
CREATE INDEXstatements, scoped to a table and index name. - Create
Table - Selector for
CREATE TABLEstatements. - Create
Temp Index - Selector for
CREATE TEMP INDEXstatements, scoped to a table and index name. - Create
Temp Table - Selector for
CREATE TEMP TABLEstatements. - Create
Temp Trigger - Selector for
CREATE TEMP TRIGGERstatements, scoped to a table and trigger name. - Create
Temp View - Selector for
CREATE TEMP VIEWstatements. - Create
Trigger - Selector for
CREATE TRIGGERstatements, scoped to a table and trigger name. - Create
View - Selector for
CREATE VIEWstatements. - Create
Vtable - Selector for
CREATE VIRTUAL TABLEstatements, scoped to a table and module name. - Delete
- Selector for
DELETEstatements, scoped to a table. - Detach
- Selector for
DETACH DATABASEstatements, scoped to a database name. - Drop
Index - Selector for
DROP INDEXstatements, scoped to a table and index name. - Drop
Table - Selector for
DROP TABLEstatements. - Drop
Temp Index - Selector for
DROP TEMP INDEXstatements, scoped to a table and index name. - Drop
Temp Table - Selector for
DROP TEMP TABLEstatements. - Drop
Temp Trigger - Selector for
DROP TEMP TRIGGERstatements, scoped to a table and trigger name. - Drop
Temp View - Selector for
DROP TEMP VIEWstatements. - Drop
Trigger - Selector for
DROP TRIGGERstatements, scoped to a table and trigger name. - Drop
View - Selector for
DROP VIEWstatements. - Drop
Vtable - Selector for
DROP VIRTUAL TABLEstatements, scoped to a table and module name. - Function
- Selector for SQL function invocations within a query.
- Glob
- A wildcard marker that matches any value in a selector field.
- Insert
- Selector for
INSERTstatements, scoped to a table. - Permission
- Pairs a selector with a permission disposition (allow or deny).
- Pragma
- Selector for
PRAGMAstatements, scoped to a pragma name - Read
- Selector for column-level read operations, scoped to a table and column.
- Recursive
- Selector for recursive query authorization checks.
- Reindex
- Selector for
REINDEXstatements, scoped to an index name. - Savepoint
- Selector for
SAVEPOINT,RELEASE, andROLLBACK TOoperations on named savepoints. - Select
- Selector for bare
SELECToperations (the statement-level authorization check, not column-level reads). - Transaction
- Selector for transaction control operations (
BEGIN,COMMIT,ROLLBACK). - Update
- Selector for
UPDATEstatements, scoped to a table and column.
Enums§
- Access
Control Selector - Umbrella enum unifying all access control selector types into a single type for use with the CLI argument parser.
- Access
Control Selector Parse Error - Enumerates the ways parsing an access control selector string can fail.
- Authorization
- The outcome of a policy check against the configured rule set.
- Preset
- Predefined permission presets for common access control configurations.
- Transaction
Operation - The type of transaction or savepoint operation being authorized.
- Value
OrGlob - Either a concrete value of type
Tor a wildcardGlob.