Skip to content

Classification tags

A DataClassification puts tags on tables and columns. Other policies then match on a tag instead of on names.

Example

Goal: mask every column that has the tag pii.

The classification tags two columns of customers. This kind needs apiVersion: sluice.bino.bi/v1beta1.

apiVersion: sluice.bino.bi/v1beta1
kind: DataClassification
metadata:
  name: shop-tags
spec:
  rules:
    - resources:
        tables: ["customers"]
        columns: ["email", "phone"]
      tags: ["pii"]
    - resources:
        tables: ["payroll"]
      tags: ["restricted"]

The mask policy names no table and no column. It matches the tag.

apiVersion: sluice.bino.bi/v1alpha1
kind: ColumnMaskPolicy
metadata:
  name: mask-pii
spec:
  match:
    any:
      - resources:
          tags: ["pii"]
  mask:
    type: partial
    args:
      showFirst: 1
      showLast: 0
curl -s http://localhost:8080/v1/query \
  -H "X-Api-Key: sl_demo_alice.supersecret" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT name, email, phone FROM shop.main.customers ORDER BY id"}'
{
  "query_id": "<query-id>",
  "columns": ["name", "email", "phone"],
  "rows": [
    ["Anna", "a***************", "+*************"],
    ["Bernd", "b****************", "+*************"]
  ],
  "row_count": 2,
  "truncated": false
}

The table suppliers also has an email column, but no tag.

curl -s http://localhost:8080/v1/query \
  -H "X-Api-Key: sl_demo_alice.supersecret" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT name, email FROM shop.main.suppliers ORDER BY id"}'
{
  "query_id": "<query-id>",
  "columns": ["name", "email"],
  "rows": [
    ["Paper Ltd", "sales@paper.example"]
  ],
  "row_count": 1,
  "truncated": false
}

What happened: A tag does nothing by itself. When Sluice loads the policies, each tag in a selector becomes the tables of its rules. The mask also took its columns from the pii rule.

Fields

Field Type Default Meaning
rules[].resources object catalogs, schemas, tables and columns, with wildcards. No tags, no actions. Without it, the rule tags every table.
rules[].tags list required Allowed: lower-case letters, digits, ., _, -. First and last character: letter or digit.

You can use resources.tags in access, row filter, mask, reject, rewrite and approval policies. One tag of the list must match. Name fields in the same clause must match too. The order of the files does not matter.

More examples

Goal: only the group auditors reads tables with the tag restricted.

apiVersion: sluice.bino.bi/v1alpha1
kind: SqlAccessPolicy
metadata:
  name: deny-restricted
spec:
  effect: deny
  match:
    any:
      - resources:
          tags: ["restricted"]
  exclude:
    any:
      - subjects:
          groups: ["auditors"]
  message: "restricted data needs the auditors group"
curl -s http://localhost:8080/v1/query \
  -H "X-Api-Key: sl_demo_alice.supersecret" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT name, salary_eur FROM shop.main.payroll"}'
{
  "code": "ACL_DENIED",
  "message": "restricted data needs the auditors group",
  "query_id": "<query-id>",
  "policy": "deny-restricted"
}

What happened: payroll has the tag, and Alice is not in auditors.

Limits

  • A tag that no DataClassification defines stops the load with unknown tag. On a reload, the old policies stay active. sluice policy validate reports it.
  • A rule with only columns matches every table. An effect: allow by such a tag does not load.
  • A RelationshipPolicy with tags stops the server start.

See also