Hi, I am trying to run a schema that I created on ...
# help
s
Hi, I am trying to run a schema that I created on cerbos playground, locally on my machine using docker, but I am unable to enable admin API. I am using this command
docker run --rm --name cerbos -d -v $(pwd)/cerbos-quickstart:/quickstart -p 3592:3592 <http://ghcr.io/cerbos/cerbos:0.42.0|ghcr.io/cerbos/cerbos:0.42.0> server --config=/quickstart/.cerbos.yaml
. But the container starts and stops instantly as if it never started in the first place. I am using docker on windows. The normal quickstart tutorial mentioned here is working just fine, but when I try to enable admin api using the yaml file, the docker container crashes almost instantly and I can't even see the logs. Can someone guide me through this?
p
hi there I've been through this issue, for admin API to work apparently you need to run a database something like this should be fine:
docker-compose.yml
Copy code
services:
  cerbos:
    image: <http://ghcr.io/cerbos/cerbos:0.42.0|ghcr.io/cerbos/cerbos:0.42.0>
    ports:
      - 3592:3592
    volumes:
      - ./cerbos/config:/flash
    command: server --config=/flash/.cerbos.yaml
    depends_on:
      - postgres

  postgres:
    image: 'postgres'
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=root
      - POSTGRES_DB=cerbos
    volumes:
      - ./cerbos/db/init.sql:/docker-entrypoint-initdb.d/db.sql
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:
then
docker-compose -f docker-compose.yml up -d
🙌 1
your cerbos config should look like this
Copy code
storage:
  driver: 'postgres'
  postgres:
    url: '<postgres://root:root@postgres:5432/cerbos?sslmode=disable&search_path=cerbos>'

server:
  apiExplorerEnabled: true
  adminAPI:
    enabled: true
s
this is what my current cerbos config file looks like:
Copy code
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"
  adminAPI:
    enabled: true
    adminCredentials:
      username: cerbos
      passwordHash: JDJ5JDEwJE5HYnk4cTY3VTE1bFV1NlR2bmp3ME9QOXdXQXFROGtBb2lWREdEY2xXbzR6WnoxYWtSNWNDCgo=

storage:
  driver: "disk"
  disk:
    directory: /cerbos-quickstart/policies
    watchForChanges: true
I'll try your approach, thanks!
👍 1
Hi, when I run
docker-compose -f docker-compose.yml up -d
, I see this in the logs for the posgress container:
Copy code
2025-04-01 16:01:05 
2025-04-01 16:01:05 PostgreSQL Database directory appears to contain a database; Skipping initialization
2025-04-01 16:01:05 
2025-04-01 16:01:05 2025-04-01 21:01:05.998 UTC [1] LOG:  starting PostgreSQL 17.4 (Debian 17.4-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2025-04-01 16:01:05 2025-04-01 21:01:05.999 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-04-01 16:01:05 2025-04-01 21:01:05.999 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2025-04-01 16:01:06 2025-04-01 21:01:06.018 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-04-01 16:01:06 2025-04-01 21:01:06.041 UTC [29] LOG:  database system was shut down at 2025-04-01 21:00:57 UTC
2025-04-01 16:01:06 2025-04-01 21:01:06.052 UTC [1] LOG:  database system is ready to accept connections
2025-04-01 16:01:06 2025-04-01 21:01:06.407 UTC [33] ERROR:  relation "policy" does not exist at character 15
2025-04-01 16:01:06 2025-04-01 21:01:06.407 UTC [33] STATEMENT:  SELECT 1 FROM "policy"
2025-04-01 16:01:06 2025-04-01 21:01:06.408 UTC [33] ERROR:  relation "policy_dependency" does not exist at character 15
2025-04-01 16:01:06 2025-04-01 21:01:06.408 UTC [33] STATEMENT:  SELECT 1 FROM "policy_dependency"
2025-04-01 16:01:06 2025-04-01 21:01:06.409 UTC [33] ERROR:  relation "policy_ancestor" does not exist at character 15
2025-04-01 16:01:06 2025-04-01 21:01:06.409 UTC [33] STATEMENT:  SELECT 1 FROM "policy_ancestor"
2025-04-01 16:01:06 2025-04-01 21:01:06.409 UTC [33] ERROR:  relation "policy_revision" does not exist at character 15
2025-04-01 16:01:06 2025-04-01 21:01:06.409 UTC [33] STATEMENT:  SELECT 1 FROM "policy_revision"
2025-04-01 16:01:06 2025-04-01 21:01:06.410 UTC [33] ERROR:  relation "attr_schema_defs" does not exist at character 15
2025-04-01 16:01:06 2025-04-01 21:01:06.410 UTC [33] STATEMENT:  SELECT 1 FROM "attr_schema_defs"
and because of this i think the cerbos container exits instantly and I see the following error in its logs.
Copy code
2025-04-01 16:01:06 {"log.level":"info","@timestamp":"2025-04-01T21:01:06.382Z","log.logger":"cerbos.server","message":"maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined"}
2025-04-01 16:01:06 {"log.level":"info","@timestamp":"2025-04-01T21:01:06.382Z","log.logger":"cerbos.server","message":"Loading configuration from /flash/.cerbos.yaml"}
2025-04-01 16:01:06 {"log.level":"warn","@timestamp":"2025-04-01T21:01:06.387Z","log.logger":"cerbos.otel","message":"Disabling OTLP traces because neither OTEL_EXPORTER_OTLP_ENDPOINT nor OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is defined"}
2025-04-01 16:01:06 {"log.level":"info","@timestamp":"2025-04-01T21:01:06.388Z","log.logger":"cerbos.postgres","message":"Initializing Postgres storage","host":"postgres","database":"cerbos"}
2025-04-01 16:01:06 {"log.level":"info","@timestamp":"2025-04-01T21:01:06.406Z","log.logger":"cerbos.db","message":"Checking database schema. Set skipSchemaCheck to true to disable."}
2025-04-01 16:01:06 {"log.level":"info","@timestamp":"2025-04-01T21:01:06.410Z","log.logger":"cerbos.server","message":"maxprocs: No GOMAXPROCS change to reset"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.408Z","log.logger":"cerbos.postgres","message":"Query","sql":"SELECT 1 FROM \"policy\"","args":[],"err":"ERROR: relation \"policy\" does not exist (SQLSTATE 42P01)","time":824367,"pid":33}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.408Z","log.logger":"cerbos.db","message":"Check failed for the table","table":"policy","error":"ERROR: relation \"policy\" does not exist (SQLSTATE 42P01)"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.408Z","log.logger":"cerbos.postgres","message":"Query","args":[],"err":"ERROR: relation \"policy_dependency\" does not exist (SQLSTATE 42P01)","time":642862,"pid":33,"sql":"SELECT 1 FROM \"policy_dependency\""}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.408Z","log.logger":"cerbos.db","message":"Check failed for the table","table":"policy_dependency","error":"ERROR: relation \"policy_dependency\" does not exist (SQLSTATE 42P01)"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.409Z","log.logger":"cerbos.postgres","message":"Query","err":"ERROR: relation \"policy_ancestor\" does not exist (SQLSTATE 42P01)","time":403913,"pid":33,"sql":"SELECT 1 FROM \"policy_ancestor\"","args":[]}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.409Z","log.logger":"cerbos.db","message":"Check failed for the table","table":"policy_ancestor","error":"ERROR: relation \"policy_ancestor\" does not exist (SQLSTATE 42P01)"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.409Z","log.logger":"cerbos.postgres","message":"Query","sql":"SELECT 1 FROM \"policy_revision\"","args":[],"err":"ERROR: relation \"policy_revision\" does not exist (SQLSTATE 42P01)","time":302796,"pid":33}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.409Z","log.logger":"cerbos.db","message":"Check failed for the table","table":"policy_revision","error":"ERROR: relation \"policy_revision\" does not exist (SQLSTATE 42P01)"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.410Z","log.logger":"cerbos.postgres","message":"Query","args":[],"err":"ERROR: relation \"attr_schema_defs\" does not exist (SQLSTATE 42P01)","time":302039,"pid":33,"sql":"SELECT 1 FROM \"attr_schema_defs\""}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.410Z","log.logger":"cerbos.db","message":"Check failed for the table","table":"attr_schema_defs","error":"ERROR: relation \"attr_schema_defs\" does not exist (SQLSTATE 42P01)"}
2025-04-01 16:01:06 {"log.level":"error","@timestamp":"2025-04-01T21:01:06.410Z","log.logger":"cerbos.server","message":"Failed to start server","error":"failed to create store: schema check failed. Ensure that the schema is correctly defined as documented at <https://docs.cerbos.dev/cerbos/latest/configuration/storage.html#postgres-schema>: schema check failed: policy, policy_dependency, policy_ancestor, policy_revision, attr_schema_defs"}
2025-04-01 16:01:06 cerbos: error: failed to create store: schema check failed. Ensure that the schema is correctly defined as documented at <https://docs.cerbos.dev/cerbos/latest/configuration/storage.html#postgres-schema>: schema check failed: policy, policy_dependency, policy_ancestor, policy_revision, attr_schema_defs
p
oh, sorry, forgot one bit you must run a few commands on the DB prior to Cerbos usage
Copy code
CREATE SCHEMA IF NOT EXISTS cerbos;

SET search_path TO cerbos;

CREATE TABLE IF NOT EXISTS policy (
    id bigint NOT NULL PRIMARY KEY,
    kind VARCHAR(128) NOT NULL,
    name VARCHAR(1024) NOT NULL,
    version VARCHAR(128) NOT NULL,
    scope VARCHAR(512),
    description TEXT,
    disabled BOOLEAN default false,
    definition BYTEA
);

CREATE TABLE IF NOT EXISTS policy_dependency (
    policy_id BIGINT,
    dependency_id BIGINT,
    PRIMARY KEY (policy_id, dependency_id),
    FOREIGN KEY (policy_id) REFERENCES cerbos.policy(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS policy_ancestor (
    policy_id BIGINT,
    ancestor_id BIGINT,
    PRIMARY KEY (policy_id, ancestor_id),
    FOREIGN KEY (policy_id) REFERENCES cerbos.policy(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS policy_revision (
    revision_id SERIAL PRIMARY KEY,
    action VARCHAR(64),
    id BIGINT,
    kind VARCHAR(128),
    name VARCHAR(1024),
    version VARCHAR(128),
    scope VARCHAR(512),
    description TEXT,
    disabled BOOLEAN,
    definition BYTEA,
    update_timestamp TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS attr_schema_defs (
    id VARCHAR(255) PRIMARY KEY,
    definition JSON
);

CREATE OR REPLACE FUNCTION process_policy_audit() RETURNS TRIGGER AS $policy_audit$
    BEGIN
        IF (TG_OP = 'DELETE') THEN
            INSERT INTO policy_revision(action, id, kind, name, version, scope, description, disabled, definition)
            VALUES('DELETE', OLD.id, OLD.kind, OLD.name, OLD.version, OLD.scope, OLD.description, OLD.disabled, OLD.definition);
        ELSIF (TG_OP = 'UPDATE') THEN
            INSERT INTO policy_revision(action, id, kind, name, version, scope, description, disabled, definition)
            VALUES('UPDATE', NEW.id, NEW.kind, NEW.name, NEW.version, NEW.scope, NEW.description, NEW.disabled, NEW.definition);
        ELSIF (TG_OP = 'INSERT') THEN
            INSERT INTO policy_revision(action, id, kind, name, version, scope, description, disabled, definition)
            VALUES('INSERT', NEW.id, NEW.kind, NEW.name, NEW.version, NEW.scope, NEW.description, NEW.disabled, NEW.definition);
        END IF;
        RETURN NULL;
    END;
$policy_audit$ LANGUAGE plpgsql;

CREATE TRIGGER policy_audit
AFTER INSERT OR UPDATE OR DELETE ON policy
FOR EACH ROW EXECUTE PROCEDURE process_policy_audit();

CREATE USER cerbos_user WITH PASSWORD 'changeme';
GRANT CONNECT ON DATABASE postgres TO cerbos_user;
GRANT USAGE ON SCHEMA cerbos TO cerbos_user;
GRANT SELECT,INSERT,UPDATE,DELETE ON cerbos.policy, cerbos.policy_dependency, cerbos.policy_ancestor, cerbos.attr_schema_defs TO cerbos_user;
GRANT SELECT,INSERT ON cerbos.policy_revision TO cerbos_user;
GRANT USAGE,SELECT ON cerbos.policy_revision_revision_id_seq TO cerbos_user;
i stored this file on
./cerbos/db/init.sql
🙌 2
a
Hi, you should be able to enable the admin API even without the database. Some of the operations won't be available (you can't add or update policies, for example) but it shouldn't cause the PDP to crash. If you remove the
--rm
from the command (which tells Docker to delete the container as soon as it stops) you should be able to get the logs from the stopped container. My guess is that there's something wrong in your config file.
s
Hi, I was able to run it successfully using the init.sql file shared above. Thank you so much! 😃
1
Hi, now I am trying to test the policies that I created on cerbos playground locally. I couldn't figure out how I can add that to the updated config file. Here is my current config file.
Copy code
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"
  adminAPI:
    enabled: true
    adminCredentials:
      username: cerbos
      passwordHash: JDJ5JDEwJE5HYnk4cTY3VTE1bFV1NlR2bmp3ME9QOXdXQXFROGtBb2lWREdEY2xXbzR6WnoxYWtSNWNDCgo=

storage:
  driver: 'postgres'
  postgres:
    url: '<postgres://root:root@postgres:5432/cerbos?sslmode=disable&search_path=cerbos>'
Since I wasn't able to configure this, I tried a different approach of using JS sdk and trying the
addOrUpdatePolicies()
function. It works fine for resource policies. This could be a stupid question, but I don't understand how I am supposed to add the
principals.yaml
and
resources.yaml
. These are my
principals.yaml
and
resources.yaml
file:
Copy code
principals:
  admin#1:
    id: admin#1
    roles:
      - admin
    attr: {}
  fieldworker#2:
    id: fieldworker#2
    roles:
      - fieldworker
    attr: {}
  manager#3:
    id: manager#3
    roles:
      - manager
    attr: {}
Copy code
resources:
  BillingTransactionReport#1:
    id: BillingTransactionReport#1
    kind: BillingTransactionReport
    attr: {}
  ClaimBalanceReport#2:
    id: ClaimBalanceReport#2
    kind: ClaimBalanceReport
    attr: {}
  BillingOutstandingBalanceReport#3:
    id: BillingOutstandingBalanceReport#3
    kind: BillingOutstandingBalanceReport
    attr: {}
The individual resource policy files are successfully being read and added as policies, but I am not how I should handle these files.
a
Those files are test data; you don't need to add them to the PDP server because they're not used at runtime to make decisions. They're for running tests against your policies at compile time as described here: https://docs.cerbos.dev/cerbos/latest/policies/compile
👀 1