pgmorbacMulti-OrBAC for PostgreSQL
    DocumentationDownloadSource
    Use cases
    • How do I...?
    Getting Started
    • Introduction
    • Quick start
    • How pgmorbac compares
    • Upgrade
    Concepts
    • Organizations
    • Roles
    • Activities
    • Views
    • Contexts
    • Rules & Modalities
    • Global Rules
    • System Principals
    • Constraints
    • Row-Level Security
    • Decision Cache
    Resolution
    • is_allowed
    Recipes
    • Org Hierarchies
    • Multi-Tenant Isolation
    • Wildcard Admin
    • Delegation
    • Service Accounts
    • Deny Rules
    • Separation of Duty
    • Derived Roles
    • Cross-Org Access
    • Obligations & Recommendations
    • Temporal Access
    Integration
    • Fastify
    • PostgREST & RLS Context
    • SQL Only
    Reference
    • Function Reference
    Recipes

    Service Accounts

    System principals versus ordinary service users.

    Situation. Two non-human accounts at Valmont. lab-importer files lab results every night and must never be blocked by a policy mistake. The patient-portal backend reads prescriptions on behalf of patients and should be governed like any other account.

    They need different treatment.

    The rule of thumb

    System principalOrdinary service user
    Registered in system_principalsyesno
    Prohibitions applyneveryes
    Config editable at runtimeno (trigger-locked)yes
    Use forinfrastructure jobs that must not be lockableanything acting for users

    Registering a principal is a deployment-time decision, made in SQL by the database owner. Make it only when being blocked would break the platform.

    The system principal

    INSERT INTO morbac.system_principals (user_id, description)
    VALUES ('aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa', 'Nightly lab-results importer')
    ON CONFLICT (user_id) DO NOTHING;

    It still needs a permission; being a principal only removes prohibitions:

    INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality)
    VALUES ('aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa', 'create', 'lab-results',
            (SELECT id FROM morbac.contexts WHERE name = 'always'), 'permission')
    ON CONFLICT DO NOTHING;

    Proof that a prohibition cannot touch it:

    INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality, priority)
    VALUES (NULL, 'create', 'lab-results',
            (SELECT id FROM morbac.contexts WHERE name = 'always'), 'prohibition', 500)
    ON CONFLICT DO NOTHING;   -- bans everybody
     
    SELECT morbac.is_allowed('aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
        (SELECT id FROM morbac.orgs WHERE name = 'Clinique Valmont Nord'),
        'create', 'lab-results');                            -- true, still runs
     
    SELECT morbac.is_allowed('11111111-1111-4111-8111-111111111111',
        (SELECT id FROM morbac.orgs WHERE name = 'Clinique Valmont Nord'),
        'create', 'lab-results');                            -- false, banned

    Clean up the demo ban:

    DELETE FROM morbac.global_rules
    WHERE user_id IS NULL AND view = 'lab-results' AND modality = 'prohibition';

    The ordinary service user

    patient-portal gets a normal role and normal rules, so it can be suspended, scoped and audited like a human account:

    INSERT INTO morbac.roles (org_id, name)
    SELECT id, 'portal-service' FROM morbac.orgs WHERE name = 'Clinique Valmont Nord'
    ON CONFLICT (org_id, name) DO NOTHING;
     
    INSERT INTO morbac.user_roles (user_id, role_id, org_id)
    SELECT 'bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb', r.id, r.org_id
    FROM morbac.roles r JOIN morbac.orgs o ON o.id = r.org_id
    WHERE o.name = 'Clinique Valmont Nord' AND r.name = 'portal-service'
    ON CONFLICT DO NOTHING;

    What the trigger lock prevents

    Once registered, attempts to assign roles to the principal, delegate to or from it, write user rules for it, or target it with a global prohibition all raise an exception. Removing the lock means removing the row from system_principals, which only the database owner can do.

    PreviousDelegationNext Deny Rules
    pgmorbac - Multi-OrBAC permission engine for PostgreSQL
    DocumentationDownloadGitea