Skip to content

Configuration reload

Sluice loads the policy directory again without a restart. A running query finishes with the old policies.

Example

Goal: allow a second table while the server runs.

policies:
  # serve.sh copies policies.d to this directory, so the steps can change files.
  directory: "./data/policies"
  reload: true

No policy allows customers yet:

curl -s http://localhost:8080/v1/query \
  -H "X-Api-Key: sl_demo_analyst.supersecret" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT id, name FROM shop.main.customers ORDER BY id"}'
{
  "code": "ACL_DENIED",
  "message": "no SqlAccessPolicy matched (default-deny)",
  "query_id": "<query-id>"
}

Copy this file into the policy directory:

apiVersion: sluice.bino.bi/v1alpha1
kind: SqlAccessPolicy
metadata:
  name: allow-customers
  priority: 100
spec:
  effect: allow
  match:
    any:
      - subjects:
          groups: ["analytics"]
        resources:
          catalogs: ["shop"]
          schemas: ["main"]
          tables: ["customers"]
cp changes/allow-customers.yaml data/policies/

The same query now returns rows:

curl -s http://localhost:8080/v1/query \
  -H "X-Api-Key: sl_demo_analyst.supersecret" \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT id, name FROM shop.main.customers ORDER BY id"}'
{
  "query_id": "<query-id>",
  "columns": ["id", "name"],
  "rows": [
    [1, "Alice"],
    [2, "Bob"]
  ],
  "row_count": 2,
  "truncated": false
}

What happened: Sluice saw the new file and reloaded the directory 250 ms later.

Triggers

Trigger Use
A file changes Automatic. policies.reload: false turns it off.
SIGHUP systemctl reload sluice or kill -HUP.
POST /admin/reload From a script. See Admin API.

The last two always work and reload at once.

curl -s -X POST http://localhost:9091/admin/reload \
  -H "Authorization: Bearer demo-admin-token-change-me"
{
  "ok": true,
  "digest": "<digest>"
}

What a reload applies

  • Every policy, also the OPA modules.
  • Subject bindings: API keys, JWT issuers, HMAC secrets, rate limits and budgets.
  • Secrets of policy objects. Sluice reads each reference again.
  • Table columns. Reload after a column changes at a data source.

These need a restart: the server config and every DataSource change.

An invalid file

One invalid file stops the whole reload, and the old policies stay active. Here a file has a wrong effect:

curl -s -X POST http://localhost:9091/admin/reload \
  -H "Authorization: Bearer demo-admin-token-change-me"
{
  "code": "ERR_CONFIG_INVALID",
  "message": "server configuration invalid"
}

After a file change, the log shows the cause. So does sluice policy validate:

sluice policy validate data/policies
data/policies/broken.yaml: SqlAccessPolicy/broken: spec.effect: must be "allow" or "deny"
1 validation error(s)
[exit status 3]

ERR_CONFIG_INVALID means Sluice cannot load a file: broken YAML, an unknown kind, a wrong field value. ERR_POLICY_INVALID means a policy or a Rego module does not compile. Here a policy has an unknown tag:

curl -s -X POST http://localhost:9091/admin/reload \
  -H "Authorization: Bearer demo-admin-token-change-me"
{
  "code": "ERR_POLICY_INVALID",
  "message": "policy document invalid"
}

Confirm a reload

GET /admin/healthz counts the reloads in config_version. The log shows config watch: reload applied.

curl -s http://localhost:9091/admin/healthz \
  -H "Authorization: Bearer demo-admin-token-change-me"
{
  "status": "ok",
  "version": "<version>",
  "config_digest": "<digest>",
  "config_version": 2
}

Limits

  • Sluice watches the policy directory for .yaml and .yml files, and policies.opa.moduleDir for .rego files. Hidden files do not count.
  • It misses directories created after the start.
  • A duplicate JWT issuer, or an hmacSecretRef that cannot be resolved, does not stop the reload. Sluice warns and keeps the old JWT bindings. An API key whose hashRef cannot be resolved stops working until the next reload.
  • An ApprovalPolicy needs approval.publicBaseUrl from the start. Without it, matching queries fail with ERR_INTERNAL.

See also