DAAM
Alpha

Policies

Policies define what tables a developer can access and what operations they can perform. DAAM uses a default-deny model — tables not mentioned in any policy are inaccessible. Policies belong to databases and are assigned to users and groups. The control plane is the source of truth; agents enforce policies locally.

Overview

Policies are database-centric. Each policy belongs to a specific database and defines two things:

  • Table grants — which tables the user can access and what operations (SELECT, INSERT, UPDATE, DELETE) are allowed on each.
  • Masking rules — which columns have their values masked on read, and what masking preset is applied (e.g. email, phone, redact).

Users and groups are then assigned to policies. A single policy can be assigned to any number of users and groups. A user or group can be assigned to multiple policies on the same database — the grants and masking rules from all applicable policies are merged into a single effective policy.

If a user has no policy assignments on a database, they have no access to it at all. There is no implicit read access — every permission must be explicitly granted.

Creating a Policy

Admins create policies from the database detail page in the console:

  1. Navigate to the database you want to create a policy for.
  2. Click Create Policy.
  3. Enter a policy name (e.g. "read-only", "analyst", "full-access"). Names must be unique within the database.
  4. Add table grants — select tables and choose which operations to allow.
  5. Add masking rules — select columns and choose a masking preset.
  6. Save the policy.

A newly created policy has no assignments. It serves as a template ready to be assigned to users or groups.

The table and column dropdowns in the policy editor are populated from the agent's schema introspection. The agent automatically discovers your database's tables and columns and reports them to the control plane.

Interactive preview
Schema data available (reported2026-03-12 08:15:00 UTC). Table and column dropdowns are populated from the database schema.

analyst · prod-users (us-east-1)

Version 3 · Updated2026-03-10 14:32:00 UTC

Table Grants

Table (schema.table)Selected TableSELECTINSERTUPDATEDELETE
Quick:

Row Filters

Restrict which rows users can access by injecting WHERE conditions. Supports dynamic filtering via user attribute variables.

public.users

ColumnOperatorValue

public.orders

ColumnOperatorValue

public.payments

ColumnOperatorValue

No row filters configured.

Masking Rules

Standard masking transforms query output — developers see masked values but can reference the column freely in SQL.

Strict masking additionally blocks the column from being used in WHERE, GROUP BY, JOIN, HAVING, and other query clauses. This prevents inference attacks where a developer could deduce masked values through query predicates.

Strict-masked columns can only appear in SELECT output, ORDER BY, and RETURNING clauses.

Pattern (schema.table.column)TypeStrict

Test Query

Validates against the grants and masking rules above, including unsaved changes. Save the policy to apply changes to agents.

Checking...

Assignments (3)

TypeNameAssigned
User[email protected]2026-02-20 11:00:00 UTC
User[email protected]2026-02-22 15:30:00 UTC
GroupData Team2026-03-01 09:00:00 UTC

The preview above includes row filters on the users and orders tables. Row filters restrict which rows a user can see based on column conditions and user variables. For details on operators, user variables, and how filters combine across policies, see the Row Filters documentation

Table Grants

Each table grant specifies a schema, table, and one or more permissions. The preview above shows a live policy editor with sample data — try the preset buttons to see how permissions change across all tables.

PermissionDescription
SELECTRead rows from the table
INSERTCreate new rows
UPDATEModify existing rows
DELETERemove rows

DDL operations (CREATE, ALTER, DROP), TRUNCATE, and superuser access are never granted. These operations are blocked regardless of policy configuration.

Permission Presets

The policy editor offers presets for common permission patterns:

PresetGrants
Read OnlySELECT
Append OnlySELECT, INSERT
Read/WriteSELECT, INSERT, UPDATE, DELETE

Presets are a UI convenience — they expand to individual table grants. You can customize the permissions on any table after applying a preset.

Masking Rules

Masking rules define how sensitive column values are transformed when read via SELECT. Masking only affects read results — writes to masked columns are unaffected. Each rule specifies a column match pattern and a masking preset.

Available Presets

PresetExample Output
emailj***@e***.com
phone***-***-1234
ssn***-**-6789
credit_card****-****-****-1111
nameA*** J***
redact[REDACTED]
nullNULL

Match Patterns

Masking rules use three-part match patterns: schema.table.column. You can use wildcards to apply rules broadly:

  • public.users.email — masks the email column on public.users
  • public.users.* — masks all columns on public.users
  • *.*.email — masks any column named email across all schemas and tables

Masking and grants are orthogonal. A user with SELECT on a table sees masked values for any masked columns. A user without SELECT cannot query the table at all. Writes to masked columns are allowed — masking only transforms read results.

Assigning Users and Groups

After creating a policy, assign users or groups to it. Assigned users receive the policy's grants and masking rules on the database.

Direct User Assignment

On the policy detail page, type at least 2 characters into the search box to search org members by email. Select a user from the results and save the assignment. The user's effective policy is recomputed and pushed to the agent immediately.

Group Assignment

You can also assign groups to policies. All members of the group (including members of nested child groups) automatically receive the policy's grants. This is the recommended approach for teams — when someone joins or leaves a group, their database access updates automatically.

The search box supports both user emails and group names. Only users and groups belonging to the current organization appear in results.

A user assigned to the same policy both directly and via a group does not receive double grants. The policy's grants and masking rules are included once in the effective policy regardless of how many assignment paths exist.

Effective Policy Resolution

A user's effective policy on a database is the merged result of all policies they can reach through direct assignments and group memberships. The agent never sees individual policies — it receives a single flat effective policy per user.

How Resolution Works

Your effective access is the combination of all policies assigned to you — directly and through groups. Grants from all applicable policies are merged: if any policy grants a permission, you have it. When multiple policies define masking for the same column, the strictest rule wins.

Grant Merging (Union)

All table grants from all applicable policies are combined. If any policy grants a permission on a table, the effective policy includes that grant. For example:

SourceTableGrants
"read-only" (direct)public.ordersSELECT
"read-write" (via group)public.ordersSELECT, INSERT
"read-write" (via group)public.productsSELECT

Effective result: public.orders gets SELECT and INSERT (union), public.products gets SELECT.

Masking Merging (Most Restrictive Wins)

When multiple policies define masking rules for the same column, the most restrictive preset wins. For example, if one policy shows a column unmasked and another redacts it, the column is redacted. The null and redact presets are considered the most restrictive since they reveal the least information.

If a masking rule exists in one policy but not another, the rule is included in the effective policy. The absence of a masking rule in one policy does not cancel a rule from another.

Example: one policy masks public.customers.email with the "email" preset and another masks it with "redact". The effective policy uses "redact" because it is more restrictive (rank 2 vs rank 4).

Live Enforcement

Policy changes take effect immediately. When you edit a policy, assign a user, or change group memberships, the control plane automatically:

  1. Recomputes the effective policy for all affected users on the database.
  2. If the effective policy changed, pushes the updated version to the agent.
  3. The agent applies permission changes to active database sessions in real time.

If a user loses all access (e.g. their only policy is deleted or they are removed from a group), the agent terminates their active connections.

What Triggers Recomputation

EventRecomputed For
Policy created, updated, or deletedEvery user assigned to that policy (directly or via group)
User assigned to or unassigned from a policyThat user on the policy's database
Group assigned to or unassigned from a policyEvery member of that group on the policy's database
User added to or removed from a groupThat user on every database where the group has a policy
Access request approved, activated, expired, or revokedThe requester on the target database

The effective policy version changes only when the resolved grants or masking rules actually differ, even if a source policy was edited without changing the effective outcome.

Schema Introspection

The policy editor's table and column dropdowns are populated from the agent's automatic schema discovery. When an agent connects to its upstream database, it introspects the schema and reports the available tables and columns to the control plane.

This means the policy editor always reflects your actual database schema. If you add a new table to your database, the agent detects it and makes it available for policy configuration without any manual steps.

You can trigger a schema refresh from the database detail page in the console if you need the agent to re-introspect immediately.

Deleting a Policy

When you delete a policy, all its assignments, table grants, and masking rules are removed. The control plane then:

  1. Recomputes the effective policy for all users who were assigned (directly or via groups).
  2. For users who still have access through other policies: pushes the updated effective policy.
  3. For users who no longer have any access: sends a policy removal to the agent, which terminates their active connections.

Deleting a policy is immediate and cannot be undone. If you want to temporarily disable access, consider removing user assignments instead of deleting the policy.

Validation

Policies are validated on save. Policy names must be unique within the database, at least one table grant is required, and masking rule patterns must follow the schema.table.column format. The console displays validation errors inline when saving.