Secret Management
Secret Management ist derzeit eine Preview-Funktion. Du siehst hier eine frühe Version dieser Funktionalität, die sich in zukünftigen Updates noch ändern kann, während wir die Nutzererfahrung weiter verbessern.
Codesphere bietet ein Secret-Management-System, das mit OpenBao integriert ist, einem Open-Source-Security-Vault. Dies stellt sicher, dass sensible Daten wie API-Schlüssel, Datenbank-Zugangsdaten und Zertifikate mit branchenüblicher Verschlüsselung gespeichert und nur bei Bedarf in deine Services eingespeist werden.
Überblick
Im Gegensatz zu regulären Umgebungsvariablen werden Secrets in einem Vault gespeichert, der mit einer Codesphere-Instanz ausgeliefert wird. Dies bietet mehrere Vorteile:
- Verschlüsselung im Ruhezustand: Alle Werte werden verschlüsselt, bevor sie gespeichert werden.
- Granularer Zugriff: Nur Services, die ein Secret explizit referenzieren, können auf dessen Wert zugreifen.
- Automatische Bereinigung: Secrets sind an den Lebenszyklus des Workspace gebunden.
Derzeit haben nur Admins einer Codesphere-Installation direkten Zugriff auf den Vault.
Secrets referenzieren
Secrets werden im Landscape Config Editor verwaltet. Um ein Secret zu definieren, muss eine bestimmte Templating-Syntax verwendet werden, unabhängig davon, ob die UI oder die YAML-Konfiguration genutzt wird. Der Zugriff auf Secrets wird aktuell nur direkt in den Landscape-Services unterstützt, nicht in den gemeinsamen prepare- oder test-Steps.
Template-Syntax: ${{ vault.secretKeyOfBao }}
- UI-Konfiguration
- YAML-Konfiguration
So fügst du mithilfe des visuellen Editors ein Secret zu einem Service hinzu:
- Öffne den Landscape Config Editor in deinem Workspace.
- Wähle den zu konfigurierenden Service aus und öffne das Fly-in-Sheet Edit Service.
- Navigiere zum Tab Values.
- Füge einen neuen Eintrag mit der Templating-Syntax hinzu:
- Key: Der Name der Umgebungsvariable, die der Service verwenden wird (z. B.
SECRET_KEY). - Value: Das Template, das den Vault-Key referenziert (
${{ vault.secretFoo }}).
- Key: Der Name der Umgebungsvariable, die der Service verwenden wird (z. B.
Konfiguration von Umgebungsvariablen mithilfe von Vault-Templates im Tab „Values“ des Service.
Für die direkte Konfiguration werden Secrets im env-Abschnitt deines ci.yml-Profils definiert. Codesphere parst diese Templates während des Sync-Vorgangs und speist die entsprechenden OpenBao-Einträge in die Service-Umgebung ein.
schemaVersion: v0.2
prepare:
steps: []
test:
steps: []
run:
secret-demo:
steps:
- command: echo $SECRET_KEY
plan: 8
replicas: 1
network:
ports:
- port: 3000
isPublic: false
paths: []
env:
SECRET_KEY: ${{ vault.secretFoo }}
PLAIN_ENV: foo
Erweiterte Environment-Templates
Neben Vault-Secrets unterstützt Codesphere dynamische Templates, um System-IDs oder bestehende Workspace-Umgebungsvariablen zu referenzieren. Diese sind besonders nützlich, um deine Konfiguration portabel zu machen oder Variablen umzumappen.
| Template | Beschreibung |
|---|---|
${{ workspace.id }} | Wird zur ID des Workspace aufgelöst, der die Landscape enthält. |
${{ workspace.devDomain }} | Wird zur Dev Domain des Workspace aufgelöst, der die Landscape enthält. |
${{ team.id }} | Wird zur ID des Teams aufgelöst, dem der Workspace gehört. |
${{ workspace.env['KEY'] }} | Wird zu einer globalen Workspace-Umgebungsvariable aufgelöst. |
Anwendungsfall: Variablen-Remapping
Das Template ${{ workspace.env[...] }} erlaubt es, globale Variablen auf spezifische Service-Anforderungen abzubilden.
Erwartet ein Backend-Service beispielsweise eine Umgebungsvariable namens PG_USER, deine Datenbank-Zugangsdaten sind jedoch global als BACKEND_PG_USER gespeichert, um Namenskonflikte mit anderen Datenbanken zu vermeiden, kannst du sie wie folgt zuordnen:
env:
PG_USER: ${{ workspace.env['BACKEND_PG_USER'] }}
Synchronisierung und Persistenz
Nach der Definition der Secret-Referenzen musst du das Landscape Profile im Execution Manager synchronisieren.
Der Sync-Vorgang
Wenn die ausgewählte ci.yml während einer Landscape-Synchronisierung neue Secret-Referenzen enthält, ist der Nutzer dafür verantwortlich, die tatsächlichen Secret-Werte bereitzustellen. Der Ablauf besteht aus folgenden Schritten:
- User Prompt: Ein Modal erscheint, das dich auffordert, die in deiner Konfiguration definierten Secret-Einträge bereitzustellen.
- Eingabe: Du musst den echten Wert des Secrets mindestens einmal eingeben, um den Eintrag im Vault zu initialisieren.
- Persistenz: Nach dem Absenden werden diese Werte in der OpenBao-Instanz gespeichert.
- Injection: Der Sync wird fortgesetzt, und die Landscape greift auf die Vault-Keys zu, um sie in die jeweiligen Services einzuspeisen.
Das Secret-Eingabe-Modal, das während des Landscape-Sync-Vorgangs ausgelöst wird.
Landscape-Synchronisierungen schlagen fehl, wenn ein im CI-Profil definierter Service nicht auf den referenzierten Secret-Eintrag zugreifen kann. Stelle sicher, dass alle Secrets beim ersten Deployment einer Landscape korrekt eingerichtet sind.
Secrets aktualisieren
Auch wenn derzeit keine dedizierte Benutzeroberfläche (UI) für den Secrets-Vault verfügbar ist, können Secrets während der Landscape-Synchronisierung verwaltet werden. Beim Synchronisieren einer Landscape kannst du wählen, ob du mit bestehenden Secrets deployst oder sie vor dem Fortfahren aktualisierst. Der Ablauf besteht aus folgenden Schritten:
- User Prompt: Ein Modal erscheint, das dich auffordert auszuwählen, wie die Landscape deployt werden soll: mit bestehenden Secrets oder mit geänderten Secrets vor dem Deployment.
- Eingabe: Wähle change secrets before deploying. Gib den neuen echten Secret-Wert ein. Dieser überschreibt nach Klick auf die Bestätigungsschaltfläche den Wert im Vault. Hinweis: Du kannst jede Änderung am Secret rückgängig machen oder während des Bearbeitungsvorgangs den echten Wert einsehen.
- Persistenz: Nach dem Absenden werden diese Werte in der OpenBao-Instanz gespeichert.
- Injection: Der Sync wird fortgesetzt, und die Landscape greift auf die Vault-Keys zu, um sie in die jeweiligen Services einzuspeisen.
Das Secret-Eingabe-Modal, das während des Landscape-Sync-Vorgangs ausgelöst wird.
Shared Vaults
Standardmäßig erhält jeder Workspace eine eigene, isolierte Vault-Partition, und die von ihm referenzierten Secret-Werte müssen beim ersten Landscape-Sync initialisiert werden (siehe Der Sync-Vorgang). Ein Shared Vault entfernt diesen manuellen Schritt für Secrets, die teamweit gemeinsam genutzt werden.
Ein Shared Vault ist eine dedizierte Partition innerhalb des Cluster-Vaults, die auf Team-Ebene statt auf Workspace-Ebene existiert. Einmal erstellt, kann er von einer beliebigen Anzahl von Workspaces innerhalb desselben Teams genutzt werden. Die wichtigsten Vorteile sind:
- Zero-Setup-Zugriff: Workspaces, die einem Shared Vault zugewiesen sind, können dessen Secrets sofort referenzieren – ohne dass jemand während der Workspace-Erstellung oder des Landscape-Syncs Werte eingeben muss.
- Single Source of Truth: Gemeinsame Zugangsdaten (z. B. gemeinsame Datenbankverbindungsdaten) werden einmal gespeichert und überall wiederverwendet, statt in jedem Workspace dupliziert zu werden.
- Zentralisierte Rotation: Die Aktualisierung eines Werts im Shared Vault wird bei der nächsten Bereitstellung an alle Workspaces weitergegeben, die ihn verwenden.
Shared Vaults sind auf Team-Ebene begrenzt. Das Auflisten erfordert Team-Leserechte, während das Erstellen, Löschen oder Ändern Team-Schreibrechte erfordert.
Wie ein Workspace Shared Secrets auflöst
Die Templating-Syntax zum Referenzieren eines Secrets ändert sich nicht – du verwendest weiterhin ${{ vault.secretKey }} in deiner Service-Konfiguration (siehe Secrets referenzieren). Was sich ändert, ist, gegen welchen Vault die Referenz aufgelöst wird:
- Wenn einem Workspace ein Shared Vault zugewiesen ist, werden alle
${{ vault.* }}-Referenzen in seiner Landscape gegen diese gemeinsame Partition aufgelöst. - Wenn kein Shared Vault zugewiesen ist, werden Referenzen gegen die eigene Partition des Workspace aufgelöst (Standardverhalten).
Das bedeutet, dass ein Workspace, der auf einen Shared Vault verweist, eine Landscape deployen kann, die gemeinsame Secrets nutzt, ohne dass vorher eine workspace-spezifische Initialisierung erforderlich ist.
Ein Workspace liest Secrets entweder aus seinem eigenen Vault oder aus dem zugewiesenen Shared Vault – die beiden werden nicht zusammengeführt. Wenn du einen Workspace auf einen Shared Vault umstellst, stelle sicher, dass jeder von der Landscape referenzierte ${{ vault.* }}-Key in diesem Shared Vault existiert, andernfalls schlägt der nächste Sync fehl.
Einem Workspace einen Shared Vault zuweisen
Shared Vaults werden pro Workspace über das Dropdown Secrets Vault ausgewählt. Das Dropdown listet jeden im Team verfügbaren Shared Vault sowie die Standardoption Workspace (default) auf, die den Workspace auf seiner eigenen isolierten Partition belässt.
- Bei der Workspace-Erstellung
- Bei einem bestehenden Workspace
Beim Erstellen eines Workspace erweiterst du Advanced Options im zweiten Schritt des Dialogs und wählst einen Vault aus dem Dropdown Secrets Vault aus. Belässt du die Einstellung bei Workspace (default), bleibt der Workspace isoliert.
Auswahl eines Shared Vault unter Advanced Options im Dialog „Create Workspace“.
Du kannst den Vault eines bestehenden Workspace über den Tab General in den Workspace-Einstellungen ändern. Die Änderung wird beim nächsten Landscape-Sync wirksam.
Ändern des Secrets Vault eines bestehenden Workspace über den Einstellungs-Tab „General“.
Der Secrets Vault-Selektor wird nur angezeigt, wenn Secret Management für deine Installation aktiviert ist.
Secrets über die Public API verwalten
Die Codesphere Public API stellt einen vollständigen Satz an Vault-Endpunkten bereit, mit denen du Workspace-Secrets programmatisch verwalten und automatisch generieren kannst – zum Beispiel in einer CI/CD-Pipeline oder einer internen Developer-Plattform. Authentifizierung und allgemeine API-Nutzung werden in der Public-API-Dokumentation behandelt.
Alle Vault-Endpunkte folgen diesem Basispfad:
/vault/teams/{teamId}/workspaces/{workspaceId}
Secrets speichern
POST /vault/teams/{teamId}/workspaces/{workspaceId}
Schreibt ein oder mehrere Secret-Schlüssel-Wert-Paare in den Vault für einen gegebenen Workspace. Gibt eine Zuordnung von jedem Key zu seinem Revisions-Identifikator zurück, der eine Versionsnummer mit einem Zeitstempel kombiniert.
Request-Body:
{
"DATABASE_PASSWORD": "supersecretpassword",
"API_KEY": "123456789"
}
Response:
{
"DATABASE_PASSWORD": "1__2026-03-05T10:14:48.490756937Z",
"API_KEY": "1__2026-03-05T10:14:48.490756937Z"
}
Secret-Keys auflisten
GET /vault/teams/{teamId}/workspaces/{workspaceId}/keys
Gibt die Liste der für einen Workspace gespeicherten Secret-Keys zurück. Werte werden über diesen Endpunkt nie offengelegt.
Response:
["DATABASE_PASSWORD", "API_KEY"]
Secrets löschen
DELETE /vault/teams/{teamId}/workspaces/{workspaceId}
Entfernt die angegebenen Secrets dauerhaft aus dem Vault.
Request-Body:
["DATABASE_PASSWORD", "API_KEY"]
Secrets automatisch generieren
POST /vault/teams/{teamId}/workspaces/{workspaceId}/generate
Generiert kryptografisch zufällige Secret-Werte und speichert sie direkt im Vault – es muss zu keinem Zeitpunkt ein Klartextwert deine Pipeline verlassen. Die Form jedes generierten Werts wird durch eine Password Policy gesteuert.
Felder der Password Policy:
| Feld | Typ | Beschreibung |
|---|---|---|
length | number | Gesamtlänge des generierten Secrets. |
rules | array | Eine oder mehrere Zeichensatzregeln, die während der Generierung angewendet werden. |
rules[].charset | string | Die Menge der Zeichen, aus denen gewählt wird. |
rules[].minChars | number | Mindestanzahl an Zeichen aus diesem Zeichensatz. |
Request-Body:
{
"DATABASE_PASSWORD": {
"length": 16,
"rules": [
{
"charset": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
"minChars": 16
}
]
},
"API_KEY": {
"length": 32,
"rules": [
{
"charset": "0123456789abcdef",
"minChars": 32
}
]
}
}
Response — die generierten Werte und ihre Revisions-Identifikatoren:
{
"DATABASE_PASSWORD": {
"value": "aB3kR7mX...",
"revision": "1__2026-03-05T10:14:48.490756937Z"
},
"API_KEY": {
"value": "1a2b3c4d...",
"revision": "1__2026-03-05T10:14:48.490756937Z"
}
}
Der Generate-Endpunkt eignet sich ideal für die initiale Workspace-Bereitstellung – du kannst für jede neue Umgebung starke, eindeutige Secrets erzeugen, ohne die Rohwerte je selbst zu handhaben. Referenziere die Vault-Keys in deiner ci.yml mit ${{ vault.secretKey }}, und die Secrets werden zum Zeitpunkt des Deployments eingespeist.
Shared-Vault-Endpunkte
Die Public API stellt außerdem Endpunkte zur Verwaltung von Shared Vaults bereit – teamweite Vaults, die über mehrere Workspaces hinweg wiederverwendet werden können. Damit kannst du einen Shared Vault und dessen Secrets programmatisch bereitstellen, zum Beispiel beim Bootstrapping einer neuen Team-Umgebung.
Shared-Vault-Endpunkte sind auf das Team statt auf einen einzelnen Workspace begrenzt und folgen diesem Basispfad:
/vault/teams/{teamId}/shared
Die Semantik der Secret-Werte – Revisions-Identifikatoren, Verhalten beim Schreiben/Auflisten/Löschen – ist identisch zu den oben beschriebenen Workspace-Endpunkten. Das Auflisten erfordert Team-Leserechte; das Erstellen, Löschen und Ändern erfordert Team-Schreibrechte.
Shared Vaults auflisten
GET /vault/teams/{teamId}/shared
Gibt die Namen aller Shared Vaults zurück, die dem Team gehören.
Response:
["production-secrets", "staging-secrets"]
Einen Shared Vault erstellen
POST /vault/teams/{teamId}/shared
Erstellt einen neuen, leeren Shared Vault für das Team. Secrets werden separat mit dem unten stehenden Store-Endpunkt hinzugefügt.
Request-Body:
{
"name": "production-secrets"
}
Einen Shared Vault löschen
DELETE /vault/teams/{teamId}/shared/{vaultName}
Löscht einen Shared Vault und alle darin gespeicherten Secrets dauerhaft. Jeder Workspace, der diesem Vault noch zugewiesen ist, wird beim nächsten Sync seine Secrets nicht auflösen können.
Secrets in einem Shared Vault speichern
POST /vault/teams/{teamId}/shared/{vaultName}/secrets
Schreibt ein oder mehrere Secret-Schlüssel-Wert-Paare in den benannten Shared Vault. Gibt eine Zuordnung von jedem Key zu seinem Revisions-Identifikator zurück (eine Versionsnummer kombiniert mit einem Zeitstempel).
Request-Body:
{
"DATABASE_PASSWORD": "supersecretpassword",
"API_KEY": "123456789"
}
Response:
{
"DATABASE_PASSWORD": "1__2026-03-05T10:14:48.490756937Z",
"API_KEY": "1__2026-03-05T10:14:48.490756937Z"
}
Secret-Keys in einem Shared Vault auflisten
GET /vault/teams/{teamId}/shared/{vaultName}/keys
Gibt die Liste der im benannten Shared Vault gespeicherten Secret-Keys zurück. Werte werden über diesen Endpunkt nie offengelegt.
Response:
["DATABASE_PASSWORD", "API_KEY"]
Secrets aus einem Shared Vault löschen
DELETE /vault/teams/{teamId}/shared/{vaultName}/secrets
Entfernt ein oder mehrere benannte Secrets aus dem Shared Vault. Das Löschen aller Keys entfernt nicht den Vault selbst – verwende dafür den Endpunkt Einen Shared Vault löschen.
Request-Body:
["DATABASE_PASSWORD", "API_KEY"]
Sicherheit und Zugriffskontrolle
Codesphere erzwingt eine strikte Isolation beim Zugriff auf Secrets:
- Referenzbasierter Zugriff: Ein Service kann ein Secret nur abrufen, wenn dieses explizit in seiner Konfiguration definiert ist.
- Landscape-Isolation: Secrets werden auf Landscape-Ebene verwaltet, sodass unterschiedliche Deployment-Umgebungen voneinander getrennt bleiben.
Lebenszyklus und Bereinigung
Um eine saubere Sicherheitslage aufrechtzuerhalten, verwaltet Codesphere den Lebenszyklus deiner Secrets automatisch. Wenn ein Workspace gelöscht wird:
- Werden alle zugehörigen Secret-Einträge im Vault identifiziert, die zu diesem Workspace und seinen Services gehören.
- Führt das System eine dauerhafte Bereinigung aller zugehörigen Keys durch.
- Bleiben nach dem Entfernen des Workspace keine sensiblen Daten mehr verfügbar.
Shared Vaults folgen einem anderen Lebenszyklus: Da sie dem Team gehören und über mehrere Workspaces hinweg gemeinsam genutzt werden, werden sie beim Löschen eines einzelnen Workspace nicht entfernt. Ein Shared Vault und seine Secrets bleiben bestehen, bis er explizit gelöscht wird – entweder über die Public API oder durch einen Installations-Admin.