Base de données personnalisée (BYO Database)
Connectez la plateforme Scrydon à un service Postgres managé (RDS, Cloud SQL, Azure Database for PostgreSQL, Supabase, Neon) au lieu du Postgres intégré dans le cluster.
Périmètre : remplacement du Postgres en cluster déployé par
infra.dbpar une instance gérée par le client. Couvre AWS RDS, GCP Cloud SQL, Azure Database for PostgreSQL (Flexible Server), Supabase, Neon, CloudNativePG, le Zalando Postgres Operator, ou tout autre Postgres ≥ 15 avec les extensions requises par les composants activés.Voir aussi : Sauvegarde et restauration (le CronJob de sauvegarde intégré est limité à la base en cluster — les utilisateurs d'une base managée doivent s'appuyer sur le PITR natif du fournisseur).
Pourquoi
Le infra.db intégré est un Postgres mono-pod adossé à un PVC — adapté aux preuves de concept et aux clusters mono-nœud, mais sans récupération point-in-time, réplication synchrone, basculement automatique ni réplication de snapshots régionaux. Les clients en production et la plupart des audits de conformité (SOC 2, ISO 27001 A.8.13, SecNumCloud 3.2, NIST CP-9/CP-10) exigent un service managé ou un cluster dédié opéré par un DBA.
Prérequis
| Exigence | Remarques |
|---|---|
| Postgres 15 ou supérieur | Les migrations Drizzle utilisent des colonnes générées et des opérations jsonb introduites en version 15. |
Extension pgvector disponible | RDS ≥ 15.3 l'inclut ; Azure Flexible Server ≥ 15 requiert azure.extensions=VECTOR ; Cloud SQL 15+ l'active ; Supabase et Neon l'intègrent nativement. |
| Extensions Lakekeeper disponibles | Lorsque infra.lakekeeper.enabled=true (valeur par défaut), le fournisseur doit proposer uuid-ossp, pgcrypto, pg_trgm, btree_gin et btree_gist. |
| Bases de données pré-créées | Une par composant activé. Avec les valeurs par défaut du chart, cela représente sept bases : auth, agentic, analytics, cortex, events, ontology, lakekeeper. Voir Pré-création des bases de données et de l'extension. |
| Un rôle de migration | Nécessite CREATE TABLE, CREATE INDEX, CREATE EXTENSION sur chaque base, plus CREATEROLE — voir Rôle d'isolation des tenants. Sur RDS, cela requiert généralement le rôle équivalent à rds_superuser ; sur Cloud SQL, l'utilisateur postgres par défaut suffit. |
| TLS imposé | Les fournisseurs managés terminent le TLS côté serveur. Utilisez sslmode=require au minimum ; verify-full si vous pouvez monter le bundle CA du fournisseur. |
| Dimensionnement du pool de connexions | Chaque pod d'application Scrydon ouvre l'intégralité de ses limites de pool (databasePool dans la référence Helm) dès qu'il est actif, et son sidecar Dapr en ouvre dapr.postgresStateStore.maxConns (2) par magasin d'état Postgres qu'il utilise. Pendant une mise à niveau, chaque charge de travail exécute un pod de plus : prévoyez réplicas + 1 — avec les valeurs par défaut, ce pic avoisine 200 connexions. Pour les bases managées de petit niveau (< 100 max_connections), abaissez ces limites, ou placez un PgBouncer ou le pooler natif du fournisseur en amont. |
Rôle d'isolation des tenants
Les politiques de Row Level Security de Scrydon s'appliquent à deux rôles
dédiés non superutilisateurs : scrydon_tenant pour le travail propre à une
organisation et scrydon_system pour les jobs qui lisent légitimement entre
tenants. L'application les endosse à chaque transaction avec SET LOCAL ROLE.
Provisionnez-les une fois par cluster, avant de migrer. Les rôles sont globaux au cluster alors que les bases de données ne le sont pas : il s'agit donc d'une étape d'administration ponctuelle, à côté de la création des bases elles-mêmes, et non d'une tâche que les migrations de chaque store devraient répéter six fois. Exécutez :
psql "$ADMIN_DATABASE_URL" \
-v grantees=<your migration user>,<your application user> \
-f scripts/sql/scrydon-cluster-roles.sqlLe script est idempotent : il crée chaque rôle avec les attributs requis, valide
tout rôle existant au lieu de lui faire confiance, accorde exactement les options
d'appartenance dont le runtime a besoin et affiche l'état obtenu pour que vous
puissiez constater que le contrat est respecté. Passez un seul nom à grantees
lorsque votre utilisateur de migration et votre utilisateur applicatif sont le
même rôle ; par défaut, il s'agit de l'utilisateur connecté.
Une fois le script exécuté, l'utilisateur de migration n'a besoin d'aucun
privilège particulier — ni CREATEROLE, ni ADMIN OPTION. Les migrations
vérifient ce contrat ; elles ne l'établissent plus.
N'accordez pas ADMIN OPTION sur ces rôles à l'utilisateur de migration.
Rien dans le produit ne les ré-accorde, et un utilisateur qui la détient
pourrait transmettre scrydon_system — qui lit tous les tenants — à n'importe
quel rôle. Le propre contrôle de couverture RLS de Scrydon le signale comme une
violation du contrat.
Si vous préférez ne pas exécuter le script, les sections ci-dessous donnent les instructions équivalentes et le rôle de chacune.
Ce n'est pas une plomberie facultative. PostgreSQL ignore entièrement la
RLS pour un superutilisateur, et FORCE ROW LEVEL SECURITY ne comble que la
faille du propriétaire de la table. La plupart des déploiements se connectent
avec un équivalent superutilisateur ; sans ce rôle, les politiques seraient donc
inertes tout en apparaissant dans pg_policies — une application des règles que
vous voyez mais que vous n'avez pas.
Deux conséquences pour une base de données que vous fournissez vous-même :
-
L'utilisateur de migration a besoin de
CREATEROLE(ou doit être superutilisateur). Sinon, les migrations s'arrêtent avec :ERROR: Scrydon tenant-isolation migration needs CREATEROLE HINT: Either grant CREATEROLE to the migration user, or pre-create the role once per CLUSTER as an administrator: CREATE ROLE scrydon_tenant NOLOGIN NOSUPERUSER NOBYPASSRLS;Si vous préférez ne pas accorder
CREATEROLEà l'utilisateur de migration, un administrateur peut provisionner le rôle à sa place — mais les deux instructions sont requises :sqlCREATE ROLE scrydon_tenant NOLOGIN NOSUPERUSER NOBYPASSRLS; GRANT scrydon_tenant TO <your migration user>;Créer le rôle seul ne suffit pas : l'utilisateur de migration doit pouvoir exécuter
SET LOCAL ROLE. Une nouvelle appartenance ordinaire dispose de cette capacité par défaut ; l'utilisateur de migration n'a pas besoin d'ADMIN OPTIONet ne doit pas recevoir de pouvoir de délégation simplement pour exécuter Scrydon :ERROR: Scrydon tenant-isolation migration needs SET ROLE access to scrydon_tenant HINT: Have an administrator run: GRANT scrydon_tenant TO <migration user>;PostgreSQL 16 et versions ultérieures peuvent conserver une appartenance préexistante avec
SET FALSE. UnGRANTsimple répété ne modifie pas cette option ; corrigez-la avecGRANT scrydon_tenant TO <migration user> WITH SET TRUE.Les migrations sont idempotentes, mais un nom existant n'est pas accepté aveuglément. Elles s'arrêtent si
scrydon_tenantestLOGIN,SUPERUSERouBYPASSRLS; inspectez et corrigez ce rôle avant de réessayer. Elles n'ignorent l'octroi que lorsque l'utilisateur de migration peut effectivement faireSET ROLE, au lieu de se fier à l'appartenance par le seul nom. -
Les rôles sont globaux au cluster ; les bases de données ne le sont pas. Un seul
scrydon_tenantdessert les six bases applicatives de Scrydon (auth,agentic,analytics,cortex,eventsetontology) : vous ne le créez donc qu'une seule fois par cluster Postgres, et non une fois par base. Lakekeeper dispose de sa propre base et n'utilise pas ce rôle. -
Les politiques s'appliquent à
cortex,events,ontologyetanalytics. Ces quatre bases portent de véritables prédicats de tenant sur chaque table rattachée à une organisation, et l'application exécute chaque requête via le rôle et le GUC décrits ci-dessus. Ce n'est pas encore le cas d'agenticet d'auth: elles ne portent aucune politique RLS, de sorte que sur ces deux bases l'isolation repose toujours sur les propres prédicatsorganization_idde l'application, comme auparavant. Leur conversion est la prochaine étape.Pour une base de données que vous fournissez vous-même, cela compte dans un cas précis : si vous faites pointer le job de migration et l'application vers des utilisateurs de base différents. Le chart utilise un seul
DATABASE_URL_CORTEXpour les deux, et la migration accordescrydon_tenantà quiconque l'exécute — le chemin par défaut ne requiert donc rien de plus. Si vous les séparez, l'utilisateur applicatif doit lui aussi pouvoir endosser le rôle :sqlGRANT scrydon_tenant TO <your application user>; -- PostgreSQL 16+: repair a pre-existing SET FALSE membership with GRANT scrydon_tenant TO <your application user> WITH SET TRUE;Sans cela, chaque requête
cortexéchoue auSET LOCAL ROLE. Avec cela, mais sur une connexion soumise aux politiques (un rôle non superutilisateur à moindre privilège), toute requête que Scrydon émettrait hors de son helper de périmètre tenant renverrait zéro ligne au lieu d'une erreur — un échec silencieux par conception. Tous les chemins de codecortexde Scrydon se trouvent dans ce helper, et un test du dépôt les y maintient ; cette remarque figure ici parce que la propriété mérite d'être connue lorsque vous auditez le rôle que vous nous confiez. -
Un second rôle,
scrydon_system, pour les jobs qui lisent entre tenants. Les purges de rétention, les backfills, le cron des tâches planifiées et le résolveur d'autorisations ne peuvent pas se lier à une seule organisation. Ils endossentscrydon_systemà chaque transaction, et chaque table de tenant porte une politique explicite donnant accès à toutes les lignes pour ce rôle. Les migrations font de même pour leurs propres étapes de données — elles changent de rôle (ou définissent le GUC worker) autour d'un backfill puis le réinitialisent — de sorte que l'utilisateur de migration n'a besoin de rien au-delà de l'appartenanceSET TRUEci-dessous. L'amorçage du cluster ci-dessus provisionne le rôle ; voici les instructions équivalentes, avec une différence par rapport àscrydon_tenantqui compte sur une base à moindre privilège :sqlCREATE ROLE scrydon_system NOLOGIN NOSUPERUSER NOBYPASSRLS; GRANT scrydon_system TO <your migration user> WITH INHERIT FALSE, SET TRUE; -- and, if the application user differs: GRANT scrydon_system TO <your application user> WITH INHERIT FALSE, SET TRUE;INHERIT FALSEn'est pas facultatif sur PostgreSQL 16 et versions ultérieures. Les politiques d'un rôle s'appliquent à chaque membre qui en hérite : unGRANTsimple permettrait donc à une connexion sans périmètre de lire tous les tenants sans jamais exécuterSET ROLE. Une migration corrige une appartenance manquante ou héritée — mais seulement lorsque l'utilisateur qui l'exécute peut accorder des droits, ce qu'un utilisateur de migration à moindre privilège ne peut délibérément pas faire. Si le vôtre détient une appartenance incorrecte, relancez l'amorçage du cluster en tant qu'administrateur plutôt que d'accorderADMIN OPTIONà l'utilisateur de migration.Avant le 2026-09-04, la migration ré-émettait cet octroi à chaque exécution, ce qui exigeait un
ADMIN OPTIONqu'un utilisateur à moindre privilège ne détient pas — une base provisionnée exactement comme documenté ici ne pouvait donc pas migrer. Elle vérifie désormais d'abord et n'accorde que lorsque quelque chose est réellement incorrect. Si vous obtenezneeds SET ROLE access to scrydon_systemsur une base correctement provisionnée, vous utilisez un build antérieur à ce changement.PostgreSQL 15 ne dispose pas d'
INHERITpar octroi ; l'appartenance y est héritée et une connexion sans périmètre lit toutes les lignes, exactement comme l'a toujours fait une connexion superutilisateur — l'isolation des tenants à l'intérieur du helper n'en est pas affectée.
Si votre fournisseur exécute les migrations via un pooler en mode
transaction (port 6543 de Supabase/Neon, ou PgBouncer en mode transaction),
appliquez plutôt les migrations via la connexion directe. Certaines
instructions DDL — dont la création de rôles — sont rejetées sur une connexion
poolée.
Pré-création des bases de données et de l'extension
À exécuter une seule fois, depuis n'importe quel client ayant accès à votre base managée. Le chart par défaut active tous les composants, ce qui correspond à sept bases de données ; supprimez les lignes des services désactivés dans votre fichier de valeurs.
psql "$ADMIN_URL" <<'SQL'
CREATE DATABASE auth;
CREATE DATABASE agentic;
CREATE DATABASE analytics; -- only if analytics.enabled (default true)
CREATE DATABASE cortex; -- only if cortex.enabled (default true)
CREATE DATABASE events; -- only if eventBackbone.enabled (default true)
CREATE DATABASE ontology; -- only if apiOntology.enabled (default true)
CREATE DATABASE lakekeeper; -- only if infra.lakekeeper.enabled (default true)
\c auth
CREATE EXTENSION IF NOT EXISTS vector;
\c agentic
CREATE EXTENSION IF NOT EXISTS vector;
\c cortex
CREATE EXTENSION IF NOT EXISTS vector;
\c lakekeeper
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS btree_gin;
CREATE EXTENSION IF NOT EXISTS btree_gist;
SQLLe chart intégré crée automatiquement les bases et pgvector via un script initdb ; le conteneur init de migration de Lakekeeper crée ses propres extensions. Pour une base managée, pré-créez tous les éléments ci-dessus afin que l'installation échoue avant le déploiement si le fournisseur ou le rôle de migration ne peut pas créer une extension. analytics, events et ontology ne requièrent pas pgvector ; auth, agentic et cortex en ont besoin.
Pourquoi cela doit être fait avant
helm install: le chart exécute chaque migration Drizzle par service dans un Job ordinaire<service>-bootstrap-<revision>, directement contreDATABASE_URL—drizzle-kit migratene crée pas la base elle-même. Lakekeeper exécute également un conteneur initlakekeeper migrate. Une base absente se manifeste peu après l'installation par des Jobs de migration en échec ou un pod Lakekeeper bloqué pendant l'initialisation.
Configuration
Les six bases applicatives prennent en charge deux modes. Choisissez-en un par application — lorsque les deux sont définis pour une application, infra.db.external.existingSecrets.<app> prend la priorité sur infra.db.external.<app>Url. Lakekeeper ne prend actuellement en charge que le mode en ligne : définissez infra.db.external.lakekeeperUrl lorsque infra.db.enabled=false et infra.lakekeeper.enabled=true.
Mode A — Secrets externes (recommandé)
Gardez les DSN des applications hors des fichiers de valeurs et des journaux CI. Pré-créez un Secret par application, chacun dans l'espace de noms cible de l'application, portant un seul DSN sous la clé attendue par l'application. Le chart ajoute chacun en second envFrom sur les déploiements correspondants.
1. Créez un Secret par base applicative activée (six avec les valeurs par défaut du chart) :
NS=scrydon-platform # adjust if you use split namespaces
# auth → key DATABASE_URL → auth DB
kubectl create secret generic scrydon-db-auth -n "$NS" \
--from-literal=DATABASE_URL='postgres://scrydon:REDACTED@pg.example.com:5432/auth?sslmode=require'
# agentic → key DATABASE_URL → agentic DB
kubectl create secret generic scrydon-db-agentic -n "$NS" \
--from-literal=DATABASE_URL='postgres://scrydon:REDACTED@pg.example.com:5432/agentic?sslmode=require'
# analytics → key DATABASE_URL_ANALYTICS → analytics DB
kubectl create secret generic scrydon-db-analytics -n "$NS" \
--from-literal=DATABASE_URL_ANALYTICS='postgres://scrydon:REDACTED@pg.example.com:5432/analytics?sslmode=require'
# cortex → key DATABASE_URL_CORTEX → cortex DB
kubectl create secret generic scrydon-db-cortex -n "$NS" \
--from-literal=DATABASE_URL_CORTEX='postgres://scrydon:REDACTED@pg.example.com:5432/cortex?sslmode=require'
# events → key DATABASE_URL_EVENTS → events DB
kubectl create secret generic scrydon-db-events -n "$NS" \
--from-literal=DATABASE_URL_EVENTS='postgres://scrydon:REDACTED@pg.example.com:5432/events?sslmode=require'
# ontology → key DATABASE_URL_ONTOLOGY → ontology DB
kubectl create secret generic scrydon-db-ontology -n "$NS" \
--from-literal=DATABASE_URL_ONTOLOGY='postgres://scrydon:REDACTED@pg.example.com:5432/ontology?sslmode=require'
# collaboration (only with collaboration.enabled) → key DATABASE_URL_COLLABORATION
# → collaboration DB; set infra.db.external.existingSecrets.collaboration
kubectl create secret generic scrydon-db-collaboration -n "$NS" \
--from-literal=DATABASE_URL_COLLABORATION='postgres://scrydon:REDACTED@pg.example.com:5432/collaboration?sslmode=require'Pourquoi un Secret par application : chaque application lit sa variable d'environnement DSN (
DATABASE_URL,DATABASE_URL_ANALYTICS,DATABASE_URL_CORTEX,DATABASE_URL_EVENTS,DATABASE_URL_ONTOLOGY) viaenvFrom, qui fusionne toutes les clés du Secret référencé dans l'environnement du conteneur. Partager un seul Secret forcerait les applications qui lisentDATABASE_URL(auth, agentic) à voir la même valeur et à pointer vers la même base — ce qui est incorrect. Les Secrets par application maintiennent chaque application liée à sa propre base tout en permettant à toutes les applications de partager un espace de noms.
2. Installez le chart :
# values.customer.yaml
infra:
db:
enabled: false
tls:
enabled: false
backup:
enabled: false
external:
existingSecrets:
auth: scrydon-db-auth
agentic: scrydon-db-agentic
analytics: scrydon-db-analytics
cortex: scrydon-db-cortex
events: scrydon-db-events
ontology: scrydon-db-ontology
lakekeeperUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/lakekeeper"helm upgrade --install scrydon oci://scrydonops.azurecr.io/scrydon/charts/scrydon \
--version <version> \
--namespace scrydon-platform \
-f values.customer.yamlLakekeeper constitue l'exception au Mode A : son DSN doit actuellement être fourni avec lakekeeperUrl. Le chart ajoute sslMode et écrit le même DSN dans les variables de lecture et d'écriture de Lakekeeper au sein du Secret secrets-lakekeeper géré par le chart, avec sa clé de chiffrement. La valeur apparaît donc dans les fichiers de valeurs et dans helm get values.
Si vous gérez les secrets applicatifs via External Secrets Operator, Sealed Secrets ou SOPS, assurez-vous que le Secret résultant possède la bonne clé (DATABASE_URL, DATABASE_URL_ANALYTICS, DATABASE_URL_CORTEX, DATABASE_URL_EVENTS ou DATABASE_URL_ONTOLOGY) dans le bon espace de noms — le chart ne vérifie jamais comment le Secret a été créé.
La base agentic stocke également l'état de sécurité d'exécution Dapr partagé par Agentic et API Platform. Si namespaces.agentic et namespaces.platform diffèrent, créez le Secret de base Agentic portant le même nom et le même DATABASE_URL dans les deux espaces de noms. Les composants Dapr sont propres à leur espace de noms ; le chart en génère un dans chacun et limite chaque copie à l'application qui la possède.
Vous pouvez également mixer les modes par application (par exemple existingSecrets.auth pour auth, agenticUrl pour agentic) — le Mode A prend la priorité par application lorsque les deux sont définis. Lakekeeper requiert toujours lakekeeperUrl.
Mode B — DSN en ligne
Plus simple — un seul bloc de valeurs, sans Secret pré-créé. Les DSN se retrouvent dans le Secret secrets-<app> géré par le chart à l'intérieur du cluster. Convient pour les environnements de staging ; à éviter en production (les DSN se retrouvent dans les fichiers de valeurs, les journaux CI et la sortie de helm get values).
# values.customer.yaml
infra:
db:
enabled: false
tls:
enabled: false
backup:
enabled: false
external:
authUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/auth"
agenticUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/agentic"
analyticsUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/analytics"
cortexUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/cortex"
eventsUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/events"
ontologyUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/ontology"
lakekeeperUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/lakekeeper"
# Only with collaboration.enabled:
collaborationUrl: "postgres://scrydon:REDACTED@pg.example.com:5432/collaboration"
sslMode: require # appended as ?sslmode=require to each DSNFuseau horaire de la session
Le paramètre TimeZone du serveur n'a aucune importance. Chaque connexion qu'ouvrent les services Scrydon et leurs jobs de migration pour écrire des données définit TimeZone=UTC à l'ouverture, et ce réglage prime sur les valeurs par défaut du serveur, de la base et du rôle (postgresql.conf, ALTER DATABASE … SET timezone, ALTER ROLE … SET timezone). Vous n'avez pas à modifier le fuseau horaire de votre instance managée.
Si un pooler de connexions se trouve entre Scrydon et Postgres, il doit transmettre au serveur le paramètre de démarrage TimeZone. PgBouncer le fait par défaut ; un pooler configuré pour supprimer ou restreindre les paramètres de démarrage doit être autorisé à laisser passer TimeZone.
Les connexions que vous ouvrez vous-même (console SQL, outil de reporting, script de migration) ne sont pas concernées. Elles utilisent le fuseau horaire défini par votre serveur ou votre client.
Ce qui doit rester dans le cluster
| Composant | Raison |
|---|---|
Clé maître crypto Dapr (dapr-crypto-key Secret) | Chiffre les valeurs de secrets écrites par la couche secrets de Scrydon avant qu'elles n'atteignent Postgres. En cas de perte, les secrets chiffrés dans une base managée restaurée sont irrécupérables. Sauvegardez cette clé hors cluster — voir Sauvegarde et restauration. |
| StarRocks (si activé) | Moteur OLAP pour Analytics — dispose de ses propres outils de sauvegarde ; voir la documentation StarRocks. |
| Stockage objet / PVC des uploads | pvc-uploads est indépendant de infra.db et n'est pas affecté par BYO Postgres. |
Secrets Kubernetes contenant les valeurs spécifiques aux applications (AUTH_SECRET, jetons API, jetons app-api Dapr) | Gérés par le chart comme aujourd'hui — le Mode A remplace uniquement la ligne DATABASE_URL. |
Secret Lakekeeper (secrets-lakekeeper) | Contient les DSN de lecture/écriture dérivés de lakekeeperUrl et la clé de chiffrement du catalogue. Sauvegardez la clé de chiffrement avant de restaurer les métadonnées Lakekeeper. |
Migrations
Lors de la première installation, chaque service activé migre dans un Job ordinaire : auth-bootstrap, events-bootstrap, agentic-bootstrap, analytics-bootstrap, cortex-bootstrap et api-ontology-bootstrap. Lors d'une mise à jour, ces mêmes propriétaires s'exécutent comme hooks pre-upgrade nommés <service>-migration. Chaque Job lit son DSN dans le même Secret que le runtime, et s'applique donc à votre base managée.
Avec collaboration.enabled, collaboration-migration applique la base
collaboration après les autres. Contrairement à elles, il ne crée ni
n'accorde aucun rôle : exécutez d'abord scripts/sql/scrydon-cluster-roles.sql
en tant qu'administrateur, avec votre utilisateur de migration et celui d'API
Platform comme grantees, sinon le Job s'arrête sur Missing scrydon_tenant.
Fournissez son DSN via infra.db.external.collaborationUrl ou
infra.db.external.existingSecrets.collaboration, jamais via auth.secrets :
le chart le refuse, car le DATABASE_URL_COLLABORATION rendu pour API Platform
le remplacerait silencieusement.
Mise à jour avec
auth.secrets.DATABASE_URL_COLLABORATIONdéfini : le chart ne se rend plus avec cette clé. Avanthelm upgrade, retirez-la deauth.secretset déplacez le DSN versinfra.db.external.collaborationUrl, ou placez-le dans un Secret sous la cléDATABASE_URL_COLLABORATIONet nommez ce Secret dansinfra.db.external.existingSecrets.collaboration. Sur le PostgreSQL intégré, retirez simplement la clé : le chart fournit lui-même le DSN.
Lorsque Lakekeeper est activé, son conteneur init lakekeeper-migrate applique les migrations du catalogue via lakekeeperUrl avant le démarrage du serveur de catalogue.
Le conteneur init wait-for-db qui teste le ping du FQDN du service en cluster est ignoré lorsque infra.db.enabled=false — la disponibilité de la base externe relève de la responsabilité du fournisseur.
Chaque helm upgrade relance les hooks de migration avant le redémarrage des pods, et un hook sans rien à appliquer ne fait rien. Relancer les migrations après un changement de valeurs revient donc à une simple mise à jour ; aucun Job n'est à supprimer au préalable :
helm upgrade scrydon oci://scrydonops.azurecr.io/scrydon/charts/scrydon \
--version <version> \
--namespace scrydon-platform \
-f values.customer.yamlVérification
# Apps should be Ready with Dapr sidecars injected (2/2). The chart defaults
# every service to scrydon-platform; add your namespaces.* targets if you split.
kubectl get pods -n scrydon-platform
# No in-cluster Postgres should exist
kubectl get deploy db -n scrydon-platform
# Expected: Error from server (NotFound)
# Migration Jobs should have run successfully
kubectl get jobs -n scrydon-platform
# <service>-bootstrap-<rev> on install (<service>-migration-<rev> on upgrade)
# for auth, events, agentic and, when enabled, analytics, cortex and
# api-ontology — Complete
# Lakekeeper's migration init container should have exited successfully
kubectl logs deploy/lakekeeper -n scrydon-platform -c lakekeeper-migrate
# A running app pod should have DATABASE_URL pointing at the managed host
kubectl exec deploy/api-platform -n scrydon-platform -c api-platform -- \
sh -c 'echo "$DATABASE_URL" | sed -E "s#//[^@]+@#//REDACTED@#"'Notes par fournisseur
AWS RDS / Aurora
- Groupe de paramètres : définissez
rds.force_ssl=1. - Extension :
pgvectordisponible depuis Postgres 15.3 sur RDS et Aurora. Installez viaCREATE EXTENSION vector;depuis un rôle appartenant àrds_superuser. - Rôle : créez un rôle avec les moindres privilèges (
CREATE ROLE scrydon LOGIN PASSWORD '…' CREATEDB;) et accordez-lui la propriété par base. - Auth IAM : non supportée par le chart actuellement — utilisez l'authentification par mot de passe.
GCP Cloud SQL
- L'indicateur
cloudsql.iam_authentication=onest optionnel ; le chart utilise l'authentification par mot de passe. pgvectoractivé par défaut sur Postgres 15+ Enterprise Plus ; sur les niveaux standard, exécutezCREATE EXTENSION vector;une fois.- IP privée : exécutez le cluster dans le même VPC que votre instance Cloud SQL, ou utilisez un sidecar Cloud SQL Auth Proxy.
Azure Database for PostgreSQL (Flexible Server)
- Paramètre serveur : ajoutez
VECTORàazure.extensionsavant le premierCREATE EXTENSION. - Réseau : la zone DNS privée avec peering VNet est recommandée ; sinon, ouvrez des règles de pare-feu pour l'IP de sortie AKS.
- Vérification du certificat : utilisez
sslmode=verify-full. Les certificats serveur d'Azure remontent à DigiCert Global Root G2 et Microsoft RSA Root CA 2017, que le runtime Scrydon approuve déjà ; aucun bundle CA n'est à monter. - N'ajoutez pas
sslrootcert=à un DSN. Le runner de migrations et plusieurs services transmettent au serveur les paramètres DSN qu'ils ne reconnaissent pas, et le serveur refuse alors la connexion avecunrecognized configuration parameter "sslrootcert".
Supabase / Neon
pgvectoractivé par défaut.- Format de la chaîne de connexion (poolée, mode transaction) :
postgres://postgres.<project>:<pass>@aws-0-<region>.pooler.supabase.com:6543/postgres. Vérifiez que vos migrations s'exécutent via la connexion poolée ; certains DDL peuvent nécessiter la connexion directe (5432). - La suspension automatique de Neon gèle les branches inactives — configurez un keepalive ou utilisez un niveau payant pour les plateformes qui s'arrêtent entre les exécutions de workflows.
Restauration sur Postgres managé
Pour restaurer les archives pg_dump --format=custom produites par le CronJob de sauvegarde intégré (voir Sauvegarde et restauration), provisionnez d'abord les rôles d'isolation des tenants sur le serveur managé. Chaque politique de sécurité au niveau des lignes des
dumps est accordée à scrydon_tenant ou scrydon_system, et pg_restore ignore
une politique dont le rôle n'existe pas. Utilisez pour cela
scrydon-cluster-roles.sql, pas le fichier globals-<horodatage>.sql.gz de la
sauvegarde : il recrée aussi le superutilisateur postgres du serveur intégré,
ce qu'un service managé n'autorise pas. Restaurez ensuite chaque base :
# decompress if you used gzip
gunzip -k /backups/auth-20260416T020000Z.sql.gz
# restore into the managed DB (run from any client with network access)
pg_restore -d "$DATABASE_URL" --no-owner --no-privileges \
/backups/auth-20260416T020000Z.sql--no-owner --no-privileges est important — les noms de rôles sur la base managée diffèrent généralement du Postgres intégré (postgres vs scrydon / rds_superuser / cloudsqlsuperuser).
Après la restauration, redémarrez les pods d'application pour qu'ils établissent de nouvelles connexions :
kubectl rollout restart deployment -n scrydon-platformDépannage
CREATE EXTENSION vector échoue — le fournisseur managé ne dispose pas de pgvector pour votre version / niveau Postgres actuel. Mettez à niveau l'instance ; aucune solution de contournement n'existe.
Pods en CrashLoopBackOff avec ECONNREFUSED ou SSL required — hôte/port DSN incorrect, TLS obligatoire mais sslmode absent, ou la politique réseau bloque la sortie vers la base. Consultez kubectl logs pour le pod, vérifiez la valeur DSN avec la commande kubectl exec sous Vérification.
Les migrations restent bloquées — le conteneur init wait-for-db est ignoré, le Job passe donc directement à la migration. S'il reste bloqué, le DSN est incorrect ou le rôle n'a pas les privilèges CREATE. Inspectez kubectl logs job/auth-bootstrap-<rev> à l'installation ou kubectl logs job/auth-migration-<rev> à la mise à niveau.
Lakekeeper reste en état Init — vérifiez lakekeeperUrl, l'accès réseau, la base lakekeeper et les cinq extensions Lakekeeper. Inspectez kubectl logs deploy/lakekeeper -c lakekeeper-migrate.
Table d'état du workflow Dapr introuvable — le composant Dapr Workflows crée son schéma automatiquement au premier démarrage. Si vous remplacez la base intégrée par une base managée existante déjà utilisée ailleurs, assurez-vous que les valeurs tablePrefix (dapr_workflow_state, analytics_dapr_workflow_state) ne sont pas en conflit.
Correspondance de conformité
- ISO 27001:2022 A.8.13 (sauvegarde des informations) — la sauvegarde native du fournisseur managé satisfait cette exigence ; désactivez
infra.db.backup.enabled. - ISO 27001:2022 A.8.24 (TLS en transit) —
sslmode=requireminimum,verify-fullrecommandé. - NIST CP-9 / CP-10 (sauvegarde et restauration) — couverture PITR managée ; documentez le RPO/RTO du fournisseur dans votre PCA.
- SecNumCloud 3.2 (continuité) — exige une réplication régionale ou multi-AZ que le Postgres en cluster intégré ne peut pas offrir. BYO Postgres managé est la voie supportée.