Zum Hauptinhalt springen

Schlüssel aus Umgebungsvariablen und Dateien

Neben der Speicherung eines Secrets in der Datenbank kann ein Key-Store-Eintrag seinen Wert zur Laufzeit eines Tasks aus einer Datei auf dem Semaphore-Server oder aus einer Umgebungsvariablen des Semaphore-Server-Prozesses lesen. Das ist nützlich, wenn die Zugangsdaten bereits außerhalb von Semaphore bereitgestellt werden, zum Beispiel:

  • ein SSH-Schlüssel, der als Docker- oder Kubernetes-Secret in den Semaphore-Container eingebunden ist;
  • ein Token, das von einem Agenten (HashiCorp Vault Agent, cert-manager usw.) auf die Festplatte geschrieben und regelmäßig rotiert wird;
  • ein Passwort, das von Ihrem Orchestrator in die Container-Umgebung injiziert wird.

Semaphore kopiert den Wert nicht in seine Datenbank. Jedes Mal, wenn ein Task den Schlüssel benötigt, liest der Server die Datei oder die Variable erneut, sodass eine Rotation der Zugangsdaten auf der Festplatte beim nächsten Task wirksam wird.

info

Die Datei oder Variable wird vom Semaphore-Server gelesen, nicht von einem Runner. Wenn Sie entfernte Runner verwenden, binden Sie die Datei auf dem Server-Host ein; der Server löst das Secret auf und übergibt es an den Runner.

Quelle auswählen

Wenn Sie einen Schlüssel erstellen oder bearbeiten (Key Store → New Key), befinden sich oben im Formular Tabs zur Auswahl der Quelle:

TabWoher der Wert stammtWas einzugeben ist
LocalSemaphore-Datenbank (verschlüsselt)Login, Passwort oder privater Schlüssel im Formular
Storage ProExterner Secret-Speicher wie HashiCorp VaultSpeicher und Secret-Pfad
EnvEine Umgebungsvariable des Semaphore-Server-ProzessesDer Variablenname, zum Beispiel PROD_SSH_KEY
FileEine Datei auf dem Semaphore-ServerDer absolute Pfad zur Datei, zum Beispiel /var/lib/semaphore/secrets/prod.json

Wenn Env oder File ausgewählt ist, werden die Felder für Login, Passwort und privaten Schlüssel ausgeblendet. Die gesamten Zugangsdaten, einschließlich des Logins bei Schlüsseln vom Typ SSH und Anmeldung mit Passwort, müssen in der Datei bzw. Variablen enthalten sein.

1. Verzeichnis freigeben

Aus Sicherheitsgründen liest Semaphore nur Schlüsseldateien, die sich innerhalb seines Secrets-Verzeichnisses befinden. Jeder andere Pfad wird beim Start eines Tasks abgelehnt:

Failed to install inventory: file path must be inside secrets path

Das Standard-Secrets-Verzeichnis ist /tmp/semaphore. Verweisen Sie über dirs.secrets in config.json oder die Umgebungsvariable SEMAPHORE_SECRETS_PATH auf das Verzeichnis, in dem Ihre Schlüsseldateien liegen. Die Vorrangregeln finden Sie unter Secrets-Verzeichnis.

Docker-Compose-Beispiel, das ein Host-Verzeichnis einbindet und freigibt:

services:
semaphore:
image: semaphoreui/semaphore:latest
environment:
SEMAPHORE_SECRETS_PATH: /var/lib/semaphore/secrets
volumes:
- /srv/semaphore/secrets:/var/lib/semaphore/secrets:ro

Gleichwertiges config.json-Fragment:

{
"dirs": {
"secrets": "/var/lib/semaphore/secrets"
}
}

Regeln für den im Tab File eingegebenen Pfad:

  • er muss absolut sein (/var/lib/semaphore/secrets/prod.json, nicht prod.json);
  • er darf keine ..-Segmente enthalten;
  • er muss auf einen Ort innerhalb des Secrets-Verzeichnisses verweisen (Unterverzeichnisse sind zulässig);
  • die Datei muss für den Benutzer lesbar sein, unter dem Semaphore läuft (im offiziellen Docker-Image ist das semaphore, UID 1001).

Für Umgebungsvariablen gibt es keine solche Einschränkung; der Server liest einfach die angegebene Variable aus seiner eigenen Umgebung.

2. Wert formatieren

Der Inhalt der Datei (bzw. der Wert der Variablen) hängt vom Schlüsseltyp ab. Ein einzelner Zeilenumbruch am Ende einer Datei wird ignoriert; alles andere wird unverändert übernommen.

SSH-Schlüssel

Semaphore erwartet ein JSON-Dokument, keine rohe PEM- oder OpenSSH-Datei mit dem privaten Schlüssel:

{
"login": "deploy",
"passphrase": "",
"private_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----\n"
}
  • login — der SSH-Benutzername, der als --user an Ansible übergeben wird. Lassen Sie ihn leer, damit das Inventory entscheidet (ansible_user). Bei Git-Repositories wird ein leerer Login standardmäßig zu git.
  • passphrase — Passphrase des privaten Schlüssels oder eine leere Zeichenkette.
  • private_key — der private Schlüssel, wobei Zeilenumbrüche als \n kodiert sind.

Erzeugen Sie den Wrapper aus einem vorhandenen Schlüssel mit jq, das sich um das Escaping kümmert:

jq -n --arg login deploy --rawfile key ~/.ssh/id_ed25519 \
'{login: $login, passphrase: "", private_key: $key}' \
> /srv/semaphore/secrets/prod_ssh.json
chmod 0400 /srv/semaphore/secrets/prod_ssh.json

Erstellen Sie anschließend einen Schlüssel vom Typ SSH, öffnen Sie den Tab File und geben Sie /var/lib/semaphore/secrets/prod_ssh.json ein (den Pfad, wie er innerhalb des Containers sichtbar ist).

warnung

Den Tab File auf einen rohen privaten Schlüssel wie ~/.ssh/id_ed25519 zu verweisen, funktioniert nicht. Die Datei wird als JSON geparst, und der Task schlägt beim Laden des Inventorys fehl.

Anmeldung mit Passwort

Ebenfalls ein JSON-Dokument:

{
"login": "svc-ansible",
"password": "s3cr3t"
}

Lassen Sie login leer, um den Schlüssel als reines Token oder Passwort zu verwenden, zum Beispiel als Ansible-Vault-Passwort.

Beispiel mit Umgebungsvariable

Dasselbe JSON-Format gilt für den Tab Env. In Docker Compose:

services:
semaphore:
image: semaphoreui/semaphore:latest
environment:
PROD_SSH_KEY: '{"login":"deploy","passphrase":"","private_key":"-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----\n"}'

Erstellen Sie einen SSH-Schlüssel, wählen Sie den Tab Env aus und geben Sie PROD_SSH_KEY als Variablennamen ein.

tipp

Umgebungsvariablen sind für jeden Prozess im Container sichtbar und landen häufig in Orchestrator-Metadaten und Logs. Bevorzugen Sie nach Möglichkeit den Tab File mit einem eingebundenen Secret.

Fehlerbehebung

FehlerUrsacheLösung
file path must be absoluteEs wurde ein relativer Pfad eingegebenGeben Sie den vollständigen, mit / beginnenden Pfad ein
file path must not contain traversal segmentsDer Pfad enthält ..Geben Sie den aufgelösten Pfad ein
file path must be inside secrets pathDie Datei liegt außerhalb von dirs.secretsSetzen Sie SEMAPHORE_SECRETS_PATH auf das Verzeichnis der Datei oder verschieben Sie die Datei
no such file or directoryDer Pfad ist falsch oder nicht in den Container eingebundenPrüfen Sie den Volume-Mount und verwenden Sie den Pfad innerhalb des Containers
permission deniedDer Semaphore-Prozess kann die Datei nicht lesenKorrigieren Sie Eigentümer oder Berechtigungen der Datei
invalid character '-' looking for beginning of valueEs wurde ein roher privater Schlüssel statt des JSON-Wrappers angegebenVerpacken Sie den Schlüssel wie oben gezeigt