Atom

Data Model

Current schema overview for Atom's main database tables.

Atom stores security state in Postgres. All primary keys are UUIDs. Most objects have tenant_id so the same Atom instance can serve many domains or customers.

Data Model Diagram

What this means: entities prove identity with credentials. Roles and direct policies connect subjects to permission blocks. Permission blocks say where actions apply. Assignment guardrails prevent unsafe access state from being created. Audit logs record what happened.

Core Tables

TableSimple purpose
tenantsTop boundary for a domain, customer, or workspace.
entitiesPrincipals such as humans, devices, services, workloads, and applications.
credentialsPassword hashes, API key hashes, and issued certificate records for entities.
sessionsRevocable login sessions referenced by JWTs.
resourcesProtected objects such as channels, rules, reports, alarms, or application resources.
principal_groupsWho-containers for entities that receive the same roles.
object_groupsWhere-containers for entities, resources, and child object groups.
rolesFriendly names for sets of permission blocks.
actionsOperation names such as read, publish, manage, and authz.check.
action_applicabilityDefines which actions are valid for which protected object kinds/types.
action_assignment_rulesDefines which entity kinds may be assigned which actions on protected object kinds/types.
permission_blocksThe access rule: scope, effect, optional conditions, and object boundary.
permission_block_actionsLinks actions to a permission block.
role_permission_blocksLinks permission blocks to roles.
role_assignmentsGives a role to an entity or principal group.
direct_policiesGives one permission block directly to an entity or principal group.
audit_logsImmutable history of security-relevant events.
certificate_crl_stateCached CRL state for the active mounted certificate issuer.

Entity And Credential State

Entities are the universal subject type. A user, device, service, workload, and application are all entities with different kind values.

Credentials belong to entities:

  • password credentials store an argon2 hash;
  • API key credentials store an argon2 hash and a lookup identifier;
  • certificate credentials store issued certificate metadata and no private key.

Plaintext passwords, API key secrets, and generated leaf private keys are never stored.

Authorization State

The authorization model is split deliberately:

  • actions name the operation;
  • action_applicability says where the operation is valid, but does not grant access;
  • action_assignment_rules say whether access may be assigned to an entity kind;
  • permission_blocks define the actual rule;
  • roles bundle permission blocks;
  • role_assignments give roles to subjects;
  • direct_policies give one permission block directly to a subject.

This keeps scope and actions in one place: the permission block.

The canonical protected object kinds are entity, resource, group, tenant, role, policy, credential, audit_log, and signing_key. Sub-kinds are stored with a kind prefix, such as entity:device and resource:channel, so authorization checks, audit logs, and explain output use the same values.

Certificate State

Atom does not store CA certificates or CA private keys in Postgres in file issuer mode. CA files are mounted into the container and loaded during startup.

Postgres stores only issued certificate lifecycle state:

  • issued certificate rows in credentials;
  • revocation data in certificate credential metadata;
  • cached CRL bytes and CRL number in certificate_crl_state.

On this page