Dem Abrechnungsbericht nur die benötigten Daten geben

PostgreSQLBeginner
Jetzt üben

Einführung

MarketLedger braucht einen Abrechnungsbericht für seine kleinen Marktanbieter. Der Bericht soll die gestrigen Summen lesen, keine Kunden-E-Mail-Adressen oder Bankreferenzen, und keine Bestellungen schreiben. Seine aktuelle Richtlinie zur Kontoerstellung ist weiter gefasst, als diese Aufgabe es erfordert.

Du schränkst diese Richtlinie ein, beziehst über OpenBao eine echte temporäre PostgreSQL-Anmeldung und speicherst mit der bereitgestellten Abfrage einen vollständigen tabulatorgetrennten Bericht. Du brauchst grundlegende Kenntnisse zu Terminal und Pfaden. SQL-Berechtigungen, Zugangsdaten-Dateien und die relevanten Befehlsoptionen werden vor der Verwendung erklärt; Python-Programmierung oder ein Cloud-Konto sind nicht erforderlich.

Den Shop und seinen benötigten Bericht kennenlernen

In diesem Schritt beginnst du mit dem funktionierenden Geschäftsbetrieb und einem normalen Bericht, bevor du Berechtigungen änderst. Verwende in diesem gesamten Lab Terminal. cd wechselt das Verzeichnis; ein absoluter Pfad funktioniert von überall:

cd /home/labex/project/market-report

PostgreSQL ist die vorbereitete Datenbank. OpenBao ist ein vorbereiteter Dienst zur Verwaltung von Secrets, der die Datenbank bitten kann, eine zeitlich begrenzte neue Anmeldung zu erstellen. Dies sind echte Prozesse im Container dieses Labs. Sie sind keine gehostete Datenbank und keine produktive Geheimnisverwaltung.

Das vorbereitete shop.py ist ein kleiner Client für den funktionierenden Shopdienst. Für seine Ausführung musst du kein Python schreiben. list zeigt die heutigen Bestellungen:

python3 shop.py list

Erwarte anfangs eine leere Liste, []. Gib eine normale Bestellung auf. --order identifiziert die Bestellung, --vendor ihren Anbieter, und --cents gibt den Betrag als ganze Anzahl von Cent an:

python3 shop.py place --order O201 --vendor V101 --cents 600

Erwarte eine gespeicherte, bezahlte Bestellung für das synthetische Handelsdatum 2026-10-29. Wiederholst du den Befehl, lehnt der Dienst die doppelte ID ab; sieh dir mit list die bestehende Bestellung an, statt sie zu löschen oder zu überschreiben.

Die Abrechnung umfasst das vorherige Datum, 2026-10-28. Die neue Bestellung von heute darf die gestrigen Summen nicht verändern. cat gibt eine Textdatei aus; sieh dir den vorbereiteten funktionierenden Beispielbericht an:

cat demo.tsv

Erwarte drei Anbieterzeilen:

vendor_id vendor_name paid_orders total_cents
V101 Birch Pantry 2 4700
V102 Elm Bakery 1 2000
V103 Maple Kitchen 1 2700

Die Trennzeichen sind Tabulatoren, deshalb endet der Dateiname auf .tsv. Vier bezahlte Bestellungen ergeben insgesamt 9400 Cent. Die stornierte Elm-Bestellung ist ausgeschlossen. Das Beispiel wurde mit einer separat vorbereiteten Leseridentität gelesen; es zu kopieren belegt nicht, dass deine neue Datenbankidentität den Bericht ausführen kann.

Eine Sicht (View) ist eine benannte Datenbankabfrage, die ausgewählte Ergebnisse bereitstellt. reporting.daily_settlement verbindet Anbieternamen mit den Summen bezahlter Bestellungen und lässt Kunden-E-Mail-Adressen und Bankreferenzen aus. Die Originaldatensätze bleiben in den privaten Tabellen public.orders und public.vendors. reporting und public sind hier Schemanamen, die Datenbankobjekte gruppieren; das Wort public bedeutet nicht, dass jede Rolle Zugriff haben sollte.

Du darfst role.sql bearbeiten, die OpenBao-Rolle settlement-report registrieren, Zugangsdaten dieser Rolle beziehen und deine Berichts- und Zugangsdaten-Dateien erstellen. Lass den Shop, ursprüngliche Datenbankdatensätze, die andere Berichtsrolle, die bereitgestellte Abfrage, Umgebungsdatei, Operator-Token und vorbereitete Laufzeitumgebung unverändert. Du brauchst weder ein Datenbankadministratorpasswort noch ein OpenBao-Root-Token.

Bei einem gewöhnlichen Fehler No such file or directory kehre mit dem obigen absoluten cd zurück, prüfe mit ls die tatsächlichen Dateinamen und versuche es erneut. Setze die Umgebung nicht zurück, um einen Tippfehler zu beheben.

Die Kontoerstellungsrichtlinie auf die Abrechnungssicht begrenzen

In diesem Schritt entfernst du Berechtigungen, die der Bericht nicht braucht. Beginne in Terminal unter /home/labex/project/market-report.

Lies die aktuellen Anweisungen zur Kontoerstellung:

cat role.sql

OpenBao ersetzt beim Ausstellen der Zugangsdaten drei Platzhalter: {{name}} wird zu einem neuen Datenbankbenutzernamen, {{password}} zu einem generierten Passwort und {{expiration}} zum Ablaufzeitpunkt des Kontos. Behalte diese Platzhalter bei; ersetze sie nicht durch einen eigenen festen Benutzernamen oder ein Passwort.

CREATE ROLE ... WITH LOGIN erstellt eine PostgreSQL-Anmeldung. VALID UNTIL begrenzt, bis wann sich ihr Passwort für eine neue Verbindung authentifizieren kann. Es beendet nicht jede bereits offene Verbindung. Den ausdrücklichen Widerruf und das natürliche Ablaufen einer Lease untersuchst du im nächsten geführten Lab.

GRANT erteilt eine Berechtigung. USAGE ON SCHEMA reporting erlaubt das Nachschlagen von Objekten in diesem Schema. SELECT ON reporting.daily_settlement erlaubt das Lesen dieser einen Sicht. Die aktuellen zusätzlichen Berechtigungen auf public erlauben das Lesen privater Tabellen und das Ändern von Bestellungen; beides braucht dieser Bericht nicht.

Die letzte Zeile ALTER ROLE ... SET log_statement = 'all' aktiviert native SQL-Protokollierung für jede neu erstellte Berichtsanmeldung. Behalte sie bei: Abfragen dieser Identität sollen zuordenbar bleiben. Verwaltungsanweisungen zur Kontoerstellung, die Passwörter enthalten, werden durch diese Einstellung je Anmeldung nicht protokolliert. Das vorbereitete OpenBao-Auditprotokoll hasht außerdem geheime Werte.

Ersetze die Datei durch die folgenden engeren Anweisungen. cat > role.sql leitet den angegebenen Text in diese Datei um. <<'ROLESQL' beginnt ein Here-Dokument; die Markierung in Anführungszeichen bewahrt den eingeschlossenen Text exakt bis zur Zeile, die nur ROLESQL enthält:

cat > role.sql <<'ROLESQL'
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT USAGE ON SCHEMA reporting TO "{{name}}";
GRANT SELECT ON reporting.daily_settlement TO "{{name}}";
ALTER ROLE "{{name}}" SET log_statement = 'all';
ROLESQL

Lies sie zurück:

cat role.sql

Die Rolle hat eine generierte Anmeldung, eine begrenzte Passwortgültigkeit, die Berechtigung zum Nachschlagen im Schema und Lesezugriff auf eine Sicht. Sie hat weder Zugriff auf Rohtabellen noch Schreibberechtigungen oder Administratorattribute. Eine Sichtberechtigung ist hier nützlich, weil die bereitgestellte Sicht private Daten bewusst auslässt; eine Sicht, die diese privaten Felder offenlegt, würde nicht dieselbe Grenze bieten.

Wartet das Terminal auf weitere Eingabe, weil die Endmarkierung fehlt, tippe ROLESQL allein in eine Zeile. Ist die gespeicherte Datei unvollständig, wiederhole den gesamten Block. Das ändert nur deine Richtliniendatei, noch nicht die laufende Datenbank.

Die Richtlinie mit dem eingeschränkten OpenBao-Operator registrieren

In diesem Schritt registrierst du deine Kontorichtlinie, ohne eine Administratoridentität des Dienstes zur Verwaltung von Secrets zu verwenden. Bleibe in Terminal.

Lies die vorbereitete Umgebungsdatei, bevor du sie lädst:

cat env.sh

source env.sh führt diese Zuweisungen in der aktuellen Shell dieses Terminals aus. export stellt einen Wert untergeordneten Befehlen zur Verfügung. Die Datei ergänzt das vorbereitete Werkzeug bao in PATH, der Befehlssuchliste der Shell, und setzt die lokalen OpenBao- und PostgreSQL-Adressen. $(cat ...) liest das vorbereitete Operator-Token aus seiner privaten Datei; das Token selbst wird nicht ausgegeben. Diese Einstellungen gehören zu dieser Terminalsitzung. Ein neues Terminal muss sie erneut laden:

source env.sh

Ein OpenBao-Operator-Token autorisiert Anfragen an den Dienst zur Verwaltung von Secrets. Es ist kein PostgreSQL-Benutzername und kein Passwort. Dieses Token darf Zugangsdaten für settlement-report verwalten und beziehen sowie die genauen Leases dieser Rolle widerrufen. Es darf weder die Datenbankverwaltungsverbindung lesen noch den separaten Inventarbericht verwalten.

bao write schreibt Konfiguration an den benannten OpenBao-Pfad. db_name=market wählt die vorbereitete Datenbankverbindung. creation_statements=@role.sql liest deine SQL-Datei als Wert dieses Feldes; @ ist OpenBaos Syntax für Dateieingaben. default_ttl=10m gibt neuen Leases standardmäßig zehn Minuten, und max_ttl=15m begrenzt die konfigurierte Lebensdauer. TTL steht für „time to live“, also Lebensdauer. Verwende diese kurzen Grenzen für den Bericht statt Stunden oder eines unbefristeten Kontos:

bao write database/roles/settlement-report db_name=market creation_statements=@role.sql default_ttl=10m max_ttl=15m

Erwarte eine Bestätigung, dass Daten nach database/roles/settlement-report geschrieben wurden. Das ändert die Erstellungsrichtlinie; eine Datenbankanmeldung wurde noch nicht ausgestellt. Eine Richtlinienänderung betrifft zukünftige Konten. Sie entzieht einer bereits ausgestellten Anmeldung keine Berechtigungen. Beziehe nach jeder registrierten Richtlinienänderung neue Zugangsdaten und erstelle damit deinen Bericht neu. Die Abschlussprüfung verlangt, dass die Berichtsidentität nach deiner letzten Richtlinienregistrierung ausgestellt wurde. Lass keine frühere übermäßig berechtigte Berichtsanmeldung aktiv; die bedingte Wiederherstellung im nächsten Schritt zeigt, wie du ihre genaue Lease beendest, bevor du ihre Zugangsdaten-Datei ersetzt.

Der Richtlinienselbsttest liest die aktuell registrierte Richtlinie und erprobt ihr SQL in einer PostgreSQL-Wegwerf-Testumgebung. Er stellt keine Lease aus, verändert die laufende Datenbank nicht und führt deinen eigentlichen Bericht nicht aus. sudo erlaubt dieser vorbereiteten Prüfung, geschützte Konfiguration einzusehen und ihr isoliertes gewöhnliches Konto auszuführen; deine normalen OpenBao- und Datenbankbefehle verwenden die eingeschränkten Identitäten:

sudo python3 /opt/labex-report/verify.py policy

Meldet er eine zusätzliche Berechtigung oder einen fehlenden Ablaufzeitpunkt, korrigiere role.sql und registriere sie erneut. Behalte Platzhalter und Protokollierungsklausel bei. Gleichwertige Berechtigungsanweisungen, die die genannte Grenze umsetzen, werden akzeptiert; die Prüfung verlangt weder einen bestimmten Editor noch eine bestimmte SQL-Schreibweise.

Eine temporäre Anmeldung beziehen und den echten Bericht ausführen

In diesem Schritt erstellst du mit einer neu ausgestellten Datenbankidentität deine Abrechnungsdatei. Beginne in derselben Terminal-Sitzung mit geladenem env.sh.

Eine Zugangsdatenantwort enthält drei verschiedene Dinge: eine Lease-ID, die diese Ausstellung in OpenBao identifiziert, einen generierten PostgreSQL-Benutzernamen und dessen Passwort. Das Operator-Token aus dem vorherigen Schritt hat die Ausstellung autorisiert; es gehört nicht zu diesen Datenbankzugangsdaten.

Halte Zugangsdaten-Dateien privat. umask 077 macht neu erstellte Dateien nur für dein Konto les- und schreibbar; vorhandene Dateien verändert es nicht:

umask 077

bao read fordert Zugangsdaten für die Rolle an. -format=json wählt strukturierte JSON-Ausgabe. > speichert diese Ausgabe in lease.json und ersetzt eine vorhandene Datei dieses Namens. Dieser Befehl erstellt wirklich eine neue PostgreSQL-Anmeldung und startet ihre Lease-Uhr; führe ihn nicht wiederholt aus, nur um dieselbe Lease anzusehen:

bao read -format=json database/creds/settlement-report > lease.json

jq wählt Felder aus JSON aus. -r gibt Zeichenfolgenwerte ohne JSON-Anführungszeichen aus. Lies die nicht geheime Identität, Lease-ID und Lease-Dauer; gib das Passwort nicht aus:

jq '.lease_id, .lease_duration, .data.username' lease.json

Erwarte eine Lease-ID database/creds/settlement-report/..., eine Dauer von 600 Sekunden und einen generierten Benutzernamen. Ihre zufälligen Endungen unterscheiden sich jedes Mal.

Der PostgreSQL-Client psql liest PGUSER und PGPASSWORD aus der Umgebung. Die Ersetzungen $(...) in Anführungszeichen setzen sie aus dieser Ausstellung. Diese Werte bleiben in dieser Terminalsitzung und ihren untergeordneten Befehlen:

export PGUSER="$(jq -r .data.username lease.json)"
export PGPASSWORD="$(jq -r .data.password lease.json)"

psql -X ignoriert persönliche psql-Startanpassungen, -v ON_ERROR_STOP=1 stoppt bei SQL-Fehlern, und -c übergibt einen SQL-Befehl. SELECT current_user fragt PostgreSQL, welche Identität diese Verbindung tatsächlich verwendet:

psql -X -v ON_ERROR_STOP=1 -c 'SELECT current_user;'

Erwarte denselben generierten Benutzernamen wie in lease.json, nicht den Shop-Schreiber, den Beispiel-Leser oder den Datenbankadministrator.

Das vorbereitete report.sql wählt die vier öffentlichen Berichtsspalten aus, sortiert Zeilen nach Anbieter-ID und kopiert sie mit Kopfzeile als tabulatorgetrennte Daten auf die Standardausgabe. Lass die Abfrage unverändert. -f liest SQL aus dieser Datei, während > nur dessen Berichtsausgabe speichert:

psql -X -v ON_ERROR_STOP=1 -f report.sql > settlement.tsv

Lies dein tatsächliches Ergebnis:

cat settlement.tsv

Seine drei Anbieterzeilen müssen dem vorherigen Geschäftsbeispiel entsprechen: Birch 2 / 4700, Elm 1 / 2000, Maple 1 / 2700. Keine Kunden-E-Mail und keine Bankreferenz darf erscheinen. Die Summe bleibt 9400 Cent, weil die heutige Bestellung O201 außerhalb der gestrigen Abrechnung liegt.

Scheitert eine spätere Verbindung mit password authentication failed, ist die zehnminütige Lease möglicherweise während des Lesens abgelaufen. Das ist ein Zugangsdatenfehler, keine abgelehnte Tabellenabfrage. Wiederhole den Befehl zur Zugangsdaten-Ausstellung einmal, lade sowohl PGUSER als auch PGPASSWORD aus der neuen Datei erneut und führe die Identitäts- und Berichtsbefehle erneut aus. Ein neuer Benutzername ist zu erwarten. Bearbeite weder den gespeicherten Benutzernamen noch verlängere den Ablaufzeitpunkt manuell.

Eine andere Wiederherstellung gilt, wenn du die Richtlinie nach der Ausstellung von Zugangsdaten geändert hast. Das frühere Konto behält seine ursprünglichen Berechtigungen. Führe vor dem Ersetzen seines lease.json den Befehl bao lease revoke "$(jq -r .lease_id lease.json)" aus. Die Ersetzung in Anführungszeichen übergibt genau diese gespeicherte Lease-ID; sie ist weder ein Datenbankbenutzername noch ein Lease-Präfix. Widerrufe niemals den Inventarbericht oder ein gesamtes Lease-Präfix. Fordere nach dem Beenden der früheren Ausstellung neue Zugangsdaten an, lade beide Datenbankvariablen erneut und erstelle den Bericht mit den obigen Befehlen neu. So bleibt keine ältere übermäßig berechtigte Anmeldung neben der neuen eingeschränkten Anmeldung nutzbar.

Bestätigen, dass private Daten und Schreibzugriffe unzugänglich bleiben

In diesem Schritt testest du die Kontogrenze und bewahrst dabei den Shop und seine ursprünglichen Daten. Verwende dasselbe Terminal mit deiner ausgestellten PostgreSQL-Identität.

Der folgende Lesezugriff soll fehlschlagen. SELECT * fordert alle Spalten an; die Richtlinie muss dieses Konto stoppen, bevor es rohe Bestelldaten lesen kann:

psql -X -v ON_ERROR_STOP=1 -c 'SELECT * FROM public.orders;'

Erwarte einen PostgreSQL-Fehler permission denied für das private Schema oder die Tabelle. $? ist der Rückgabestatus des unmittelbar vorherigen Befehls; echo gibt ihn aus. Lies ihn sofort:

echo $?

Erwarte 1, eine abgelehnte SQL-Abfrage. Ein Verbindungsfehler mit Status 2 belegt diese Berechtigungsgrenze nicht; verwende bei abgelaufener Lease die Wiederherstellung durch Neuausstellung und erneutes Laden aus dem vorherigen Schritt.

Versuche nun einen für die Daten harmlosen Schreibzugriff: UPDATE ... WHERE false trifft auf keine Zeile zu und könnte deshalb auch bei einem irrtümlich überberechtigten Konto keine Bestellungen verändern. Er muss trotzdem wegen unzureichender Berechtigung abgelehnt werden:

psql -X -v ON_ERROR_STOP=1 -c 'UPDATE public.orders SET amount_cents = 0 WHERE false;'
echo $?

Erwarte erneut einen Berechtigungsfehler und Status 1. Das Konto kann die vorgesehene Sicht lesen, aber weder rohe private Daten lesen noch Bestellungen schreiben.

Der vorbereitete Shopclient verwendet die separate Schreibidentität des Shopdienstes statt deiner Berichtszugangsdaten. Bestätige, dass die von dir aufgegebene Bestellung weiterhin verfügbar ist:

python3 shop.py list

Führe die schreibgeschützte Abschlussprüfung aus. Sie liest zuerst vorhandene native OpenBao-Ausstellungs- und PostgreSQL-Abfragenachweise und prüft dann deinen tatsächlichen Bericht und die erhaltenen Geschäftsdaten. Sie erstellt keine fehlende Anmeldung und erzeugt den Bericht nicht für dich:

sudo python3 /opt/labex-report/verify.py result

Du hast jetzt eine vollständige Abrechnung, die mit einer echten dynamisch ausgestellten, eingeschränkten Datenbankidentität erstellt wurde. Das nächste unabhängige Lab beginnt mit der richtigen Berechtigungsrichtlinie und konzentriert sich auf das Beenden des Zugriffs und das Beobachten fehlgeschlagener neuer Verbindungen.

Zusammenfassung

Du hast eine eingeschränkte Richtlinie zur Kontoerstellung registriert, über einen eingeschränkten OpenBao-Operator eine neue PostgreSQL-Anmeldung bezogen und mit dieser Identität eine echte Abrechnung gespeichert. Ihre Sicht stellt die erforderlichen Geschäftssummen bereit, während private Tabellen, Schreibzugriffe und Administratorrechte außerhalb des Berichtsumfangs bleiben.

Operator-Token, Lease-ID und Datenbankzugangsdaten haben unterschiedliche Aufgaben. Diese Übung ist weiterhin auf vertrauenswürdige vorbereitete Verwaltungskomponenten angewiesen; temporäre Konten beseitigen dieses anfängliche Vertrauen nicht. Das nächste Lab untersucht den gezielten Lease-Widerruf, natürliches Ablaufen und die Wiederherstellung durch eine neue Ausstellung.