Skip to content
Version 1.0.0

Gateway database tables

The schema's tables, their columns, their constraints, their indexes and their triggers.

Internal, subject to change without notice. What this page describes belongs to the operation of a deployment, not to the contract the gateway offers to a third-party program. The vendor makes no commitment about it: these names can change from one version to the next, with no deprecation step. A change then shows up at startup or at upgrade time, as a message naming what is missing.

The part the vendor does commit to is the relay.

The gateway and the admin console read the same database. This page describes its schema as the installation file creates it, plus the registry table that the migration script adds for its own use.

The schema carries almost no machine-readable comments. This page therefore lists the columns, their type, whether they are required and their default value, without explaining what each one is for. Once the schema is annotated, the descriptions will appear here without anyone having to rewrite this page.

A fresh database contains no provider, no model, no endpoint and no account: the operator declares them from the admin console.

A data protection officer looks at these first. The classification is based on the column name, which keeps it true for columns added later without anyone thinking about it.

ColumnNature
users.usernamepersonal data
access_keys.key_hashsecret
access_keys.key_hintsecret
authorization_decisions.subjectpersonal data
identity_sessions.subjectpersonal data
subject_roles.subjectpersonal data
subject_roles.granted_bypersonal data
authorization_policies.installed_bypersonal data
subject_revocations.subjectpersonal data
subject_revocations.revoked_bypersonal data
subject_revocations.lifted_bypersonal data
administration_actions.actorpersonal data
administration_actions.targetpersonal data
agent_acts.subjectpersonal data
agent_acts.targetpersonal data
agent_acts.decided_bypersonal data
agent_session_revocations.revoked_bypersonal data
organization_policies.installed_bypersonal data
organization_policy_journal.actorpersonal data
relay_usage.subjectpersonal data

No API key is stored in clear text: the database keeps a hash and the fragment the console displays so a key can be recognized without being read back.

ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
nameTEXTyesnoneunique
max_cost_euroNUMERIC(10,4)nonone
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
usernameTEXTyesnoneunique, personal data
activeBOOLEANyesTRUE
created_atTIMESTAMPTZyesNOW()
plan_idINTEGERnononereferences plans(id)
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
user_idINTEGERyesnonereferences users(id)
key_hashTEXTyesnoneunique, secret
key_hintTEXTyesnonesecret
nameTEXTyesnone
created_atTIMESTAMPTZyesNOW()
last_used_atTIMESTAMPTZnonone
revoked_atTIMESTAMPTZnonone

Constraints

NameRule
access_keys_name_not_blankCHECK (btrim(name) <> '')

Indexes

NameUniqueColumnsRestricted to
access_keys_by_accountnouser_idno restriction
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
slugTEXTyesnoneunique
nameTEXTyesnone
base_urlTEXTyesnone
api_key_envTEXTnonone
api_key_headerTEXTnonone
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
slugTEXTyesnoneunique
nameTEXTyesnone
provider_idINTEGERyesnonereferences providers(id)
input_token_price_nano_euroBIGINTyes0
output_token_price_nano_euroBIGINTyes0
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
nameTEXTyesnoneunique
model_idINTEGERyesnonereferences models(id)
enabledBOOLEANyesTRUE
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
timestampTIMESTAMPTZyesNOW()
user_idINTEGERnononereferences users(id)
endpoint_idINTEGERnononereferences endpoints(id)
modelTEXTyesnone
latency_msINTEGERyesnone
input_tokensINTEGERnonone
output_tokensINTEGERnonone
request_idUUIDnonone

Indexes

NameUniqueColumnsRestricted to
request_logs_request_id_uniqueyesrequest_idrequest_id IS NOT NULL
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
decided_atTIMESTAMPTZyesclock_timestamp()
subjectTEXTnononepersonal data
identity_sourceTEXTyesnone
resourceTEXTyesnone
decisionTEXTyesnone
reasonTEXTnonone
request_idTEXTnonone

Constraints

NameRule
authorization_decisions_decision_connueCHECK (decision IN ('accordee', 'refusee'))
authorization_decisions_source_connueCHECK (identity_source IN ('annuaire', 'locale', 'inconnue'))
authorization_decisions_accord_nomme_son_sujetCHECK (decision <> 'accordee' OR subject IS NOT NULL)

Indexes

NameUniqueColumnsRestricted to
authorization_decisions_sujet_instantnosubject, decided_at DESCno restriction
ColumnTypeRequiredDefault
idTEXTyesnoneprimary key
subjectTEXTyesnonepersonal data
identity_sourceTEXTyesnone
opened_atTIMESTAMPTZyesclock_timestamp()
expires_atTIMESTAMPTZyesnone
ended_atTIMESTAMPTZnonone
ended_reasonTEXTnonone

Constraints

NameRule
identity_sessions_source_connueCHECK (identity_source IN ('annuaire', 'locale'))
identity_sessions_fin_motiveeCHECK ((ended_at IS NULL) = (ended_reason IS NULL))

Indexes

NameUniqueColumnsRestricted to
identity_sessions_sujet_vivantesnosubjectended_at IS NULL
ColumnTypeRequiredDefault
credits_per_eurINTEGERyesnone
ColumnTypeRequiredDefault
idSERIALyesnoneprimary key
subjectTEXTyesnonepersonal data
roleTEXTyesnone
scopeTEXTnonone
poleTEXTnononecomputed
granted_atTIMESTAMPTZyesNOW()
granted_byTEXTyesnonepersonal data

Constraints

NameRule
subject_roles_known_roleCHECK ( role IN ( 'utilisateur-standard', 'administrateur-de-projet', 'administrateur-d-instance', 'auditeur' ) )
subject_roles_scope_iff_projectCHECK ( (role = 'administrateur-de-projet') = (scope IS NOT NULL) )
subject_roles_attribution_uniqueUNIQUE NULLS NOT DISTINCT (subject, role, scope)

Indexes

NameUniqueColumnsRestricted to
subject_roles_by_subjectnosubjectno restriction

Triggers

NameWhenEffect
subject_roles_cumul_interditBEFORE INSERT OR UPDATEFOR EACH ROW EXECUTE FUNCTION refuse_administration_audit_overlap()
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
installed_atTIMESTAMPTZyesclock_timestamp()
installed_byTEXTyesnonepersonal data
documentJSONByesnone
nameTEXTnononecomputed

Constraints

NameRule
authorization_policies_document_est_un_objetCHECK (jsonb_typeof(document) = 'object')
authorization_policies_auteur_non_videCHECK (btrim(installed_by) <> '')
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
subjectTEXTyesnonepersonal data
revoked_atTIMESTAMPTZyesclock_timestamp()
revoked_byTEXTyesnonepersonal data
reasonTEXTyesnone
lifted_atTIMESTAMPTZnonone
lifted_byTEXTnononepersonal data

Constraints

NameRule
subject_revocations_auteur_non_videCHECK (btrim(revoked_by) <> '')
subject_revocations_motif_non_videCHECK (btrim(reason) <> '')
subject_revocations_sujet_non_videCHECK (btrim(subject) <> '')
subject_revocations_levee_endosseeCHECK ((lifted_at IS NULL) = (lifted_by IS NULL))
subject_revocations_leveur_non_videCHECK (lifted_by IS NULL OR btrim(lifted_by) <> '')

Indexes

NameUniqueColumnsRestricted to
subject_revocations_une_seule_en_vigueuryessubjectlifted_at IS NULL
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
performed_atTIMESTAMPTZyesclock_timestamp()
actionTEXTyesnone
actorTEXTyesnonepersonal data
actor_assuranceTEXTyesnone
targetTEXTnononepersonal data
roleTEXTnonone
scopeTEXTnonone
outcomeTEXTyesnone
refusal_reasonTEXTnonone
policy_idBIGINTnonone

Constraints

NameRule
administration_actions_acte_connuCHECK (action IN ( 'attribution-de-role', 'retrait-de-role', 'revocation-de-sujet', 'levee-de-revocation', 'installation-de-politique', 'installation-de-politique-d-organisation', 'revocation-de-session-d-agent' ))
administration_actions_issue_connueCHECK (outcome IN ('effectue', 'sans-effet', 'refuse'))
administration_actions_assurance_connueCHECK (actor_assurance IN ('declaree', 'etablie'))
administration_actions_acteur_non_videCHECK (btrim(actor) <> '')
administration_actions_cible_nommeeCHECK ( action NOT IN ( 'attribution-de-role', 'retrait-de-role', 'revocation-de-sujet', 'levee-de-revocation', 'revocation-de-session-d-agent' ) OR (target IS NOT NULL AND btrim(target) <> '') )
administration_actions_role_ssi_acte_de_roleCHECK ( (action IN ('attribution-de-role', 'retrait-de-role')) = (role IS NOT NULL) )
administration_actions_perimetre_suppose_un_roleCHECK (scope IS NULL OR role IS NOT NULL)
administration_actions_politique_ssi_installationCHECK ( ( policy_id IS NULL OR action IN ( 'installation-de-politique', 'installation-de-politique-d-organisation' ) ) AND ( action NOT IN ( 'installation-de-politique', 'installation-de-politique-d-organisation' ) OR outcome <> 'effectue' OR policy_id IS NOT NULL ) )
administration_actions_refus_motiveCHECK ((outcome = 'refuse') = (refusal_reason IS NOT NULL))

Indexes

NameUniqueColumnsRestricted to
administration_actions_cible_instantnotarget, performed_at DESCno restriction
administration_actions_acteur_instantnoactor, performed_at DESCno restriction
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
announced_atTIMESTAMPTZyesclock_timestamp()
launcherTEXTnonone
guarantee_heldBOOLEANyesnone
reservationsJSONByesnone

Constraints

NameRule
agent_execution_announcements_reserves_ssi_non_tenueCHECK (guarantee_held = (jsonb_array_length(reservations) = 0))
agent_execution_announcements_reserves_en_tableauCHECK (jsonb_typeof(reservations) = 'array')
agent_execution_announcements_sans_lanceur_sans_garantieCHECK (launcher IS NOT NULL OR guarantee_held = FALSE)

Indexes

NameUniqueColumnsRestricted to
agent_execution_announcements_instantnoannounced_at DESCno restriction
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
received_atTIMESTAMPTZyesclock_timestamp()
sessionTEXTyesnone
workstationTEXTnonone
subjectTEXTnononepersonal data
subject_assuranceTEXTyes'declaree'
surfaceTEXTyesnone
agentTEXTyesnone
atTIMESTAMPTZyesnone
rankINTEGERyesnone
kindTEXTyesnone
toolTEXTnonone
targetTEXTnononepersonal data
decisionTEXTnonone
decided_byTEXTnononepersonal data
outcomeTEXTnonone
reasonTEXTnonone
duration_msINTEGERnonone
modeTEXTnonone
rule_countINTEGERnonone
toolsJSONBnonone

Constraints

NameRule
agent_acts_assurance_connueCHECK (subject_assurance IN ('declaree', 'etablie'))
agent_acts_surface_connueCHECK (surface IN ('cli', 'ide'))
agent_acts_rang_positifCHECK (rank >= 1)
agent_acts_genre_connuCHECK (kind IN ('tool-call', 'session-frame'))
agent_acts_decision_connueCHECK (decision IS NULL OR decision IN ('allowed', 'refused'))
agent_acts_decideur_connuCHECK (decided_by IS NULL OR decided_by IN ('human', 'automation'))
agent_acts_issue_connueCHECK (outcome IS NULL OR outcome IN ('succeeded', 'failed', 'not-executed'))
agent_acts_motif_borneCHECK (reason IS NULL OR char_length(reason) <= 300)
agent_acts_outils_en_tableauCHECK (tools IS NULL OR jsonb_typeof(tools) = 'array')
agent_acts_appel_completCHECK (kind <> 'tool-call' OR (tool IS NOT NULL AND decision IS NOT NULL AND decided_by IS NOT NULL AND outcome IS NOT NULL))
agent_acts_cadre_completCHECK (kind <> 'session-frame' OR mode IS NOT NULL)
agent_acts_un_rang_par_sessionUNIQUE (session, rank)

Indexes

NameUniqueColumnsRestricted to
agent_acts_session_rangnosession, rankno restriction
agent_acts_instantnoreceived_at DESCno restriction
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
sessionTEXTyesnone
revoked_atTIMESTAMPTZyesclock_timestamp()
revoked_byTEXTyesnonepersonal data
revoked_by_assuranceTEXTyesnone
reasonTEXTyesnone

Constraints

NameRule
agent_session_revocations_session_non_videCHECK (btrim(session) <> '')
agent_session_revocations_auteur_non_videCHECK (btrim(revoked_by) <> '')
agent_session_revocations_assurance_connueCHECK (revoked_by_assurance IN ('declaree', 'etablie'))
agent_session_revocations_motif_non_videCHECK (btrim(reason) <> '')
agent_session_revocations_une_par_sessionUNIQUE (session)
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
slugTEXTyesnoneunique
nameTEXTyesnone
created_atTIMESTAMPTZyesnow()
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
organization_idBIGINTyesnonereferences organizations(id)
revisionTEXTyesnone
documentJSONByesnone
validity_secondsINTEGERyesnone
installed_atTIMESTAMPTZyesnow()
installed_byTEXTyesnonepersonal data

Constraints

NameRule
“UNIQUE (organization_id, revision)

Indexes

NameUniqueColumnsRestricted to
organization_policies_in_forcenoorganization_id, id DESCno restriction
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
organization_idBIGINTnononereferences organizations(id)
atTIMESTAMPTZyesnow()
actorTEXTyesnonepersonal data
actor_assuranceTEXTyesnone
outcomeTEXTyesnone
revisionTEXTnonone
refusal_reasonTEXTnonone
documentJSONBnonone
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
announced_atTIMESTAMPTZyesclock_timestamp()
served_organizationTEXTyesnone
ColumnTypeRequiredDefault
idBIGSERIALyesnoneprimary key
recorded_atTIMESTAMPTZyesclock_timestamp()
subjectTEXTyesnonepersonal data
identity_sourceTEXTyesnone
modelTEXTyesnone
input_tokensINTEGERnonone
output_tokensINTEGERnonone
latency_msINTEGERnonone
request_idTEXTnonone

Indexes

NameUniqueColumnsRestricted to
relay_usage_sujet_instantnosubject, recorded_at DESCno restriction

Created by gateway-db/migrate.sh, not by the installation file.

ColumnTypeRequiredDefault
versionTEXTyesnoneprimary key
applied_atTIMESTAMPTZyesNOW()

The migrations themselves, the order in which they apply, backup and restore are not described here. What is described is the state of the schema, not the path a database takes to reach it.