소개
정산 보고서는 실행 중에 데이터베이스 접근이 필요합니다. 작업이 끝나면 저장된 자격 증명으로 새 연결을 열 수 없어야 합니다. 비밀 관리 서비스의 수락 메시지만으로는 그 결과의 증거가 충분하지 않습니다.
이 독립 MarketLedger 환경은 올바른 뷰 권한으로 시작합니다. 보고서를 실행하고 정확한 OpenBao 임대를 해지하며 별도 임대의 자연 만료를 관찰한 뒤 새 로그인을 발급받아 복구합니다. 상점과 독립적인 재고 보고서는 계속 사용할 수 있어야 합니다. 앞 가이드 실습에서 자격 증명 필드와 제한된 보고서 정책을 배웠습니다. 파일이나 세션 상태는 이어지지 않습니다.
작동 중인 상점과 올바른 보고서 정책에서 시작하기
이 단계에서는 어느 임대 시간도 시작하기 전에 정상 업무와 두 보고서 역할을 확인합니다. 계속 Terminal을 사용하세요. 독립 작업 공간으로 들어가세요.
cd /home/labex/project/market-report
cat은 준비된 정상 예시를 출력합니다.
cat demo.tsv
정산 대상은 2026-10-28입니다. Birch의 결제 주문은 두 건에 4700센트, Elm은 한 건에 2000센트, Maple은 한 건에 2700센트입니다. 취소 주문은 제외됩니다. 보고서는 reporting.daily_settlement를 사용하며 비공개 고객 이메일과 은행 참조 정보는 범위 밖입니다.
준비된 상점 클라이언트는 실제 상점 서비스와 통신합니다. 인수는 새 주문, 판매자, 센트 금액을 지정합니다. 다음 합성 거래일 2026-10-29에 정상 주문을 넣으세요.
python3 shop.py place --order O201 --vendor V101 --cents 600
이 나중 주문은 어제 정산에 속하지 않습니다. 명령을 반복하면 서비스는 중복을 거부합니다. 삭제하지 말고 python3 shop.py list로 기존 주문을 보세요.
제공된 env.sh에는 로컬 서비스 주소가 있고 비공개 파일에서 제한된 운영자 토큰을 읽습니다. source는 현재 셸에 변수 할당을 로드하고 export는 자식 명령에서도 사용할 수 있게 합니다. 새 터미널에서는 다시 로드해야 합니다.
source env.sh
운영자 토큰은 OpenBao 요청을 승인하며 데이터베이스 비밀번호가 아닙니다. 이 토큰은 settlement-report와 settlement-short 역할의 자격 증명을 발급받고 정확한 임대를 해지할 수 있습니다. 독립적인 재고 보고서를 관리하거나 데이터베이스 관리자 연결을 읽을 수는 없습니다.
올바른 계정 생성 구문을 읽으세요.
cat role.sql
이 구문은 제공된 비밀번호 만료가 있는 생성된 로그인을 만들고, 스키마 조회와 정산 뷰 읽기를 허용하며, PostgreSQL 자체 SQL 감사를 유지합니다. 이 실습에서는 이 구문과 두 역할 설정을 변경하지 마세요.
일반 보고서 역할의 기본 시간은 10분입니다. 별도로 준비된 settlement-short 역할은 30초 동안 유지되며 같은 뷰 권한을 가집니다. 자격 증명을 요청하기 전에는 어느 시간도 시작되지 않습니다. 초기 설정에서 생성된 자격 증명이 만료되기 전에 서둘러 학습할 필요가 없습니다.
이 역할들의 자격 증명을 발급하고, 제공된 보고서 쿼리를 실행하며, 보고서와 비공개 자격 증명 응답을 저장하고, 발급받은 정확한 보고서 임대를 해지할 수 있습니다. 원본 데이터베이스 레코드, 상점, 독립적인 재고 역할과 임대, 제공된 쿼리, 환경, 운영자 토큰, 준비된 런타임을 보존하세요. 임대 접두사 전체를 해지하지 마세요.
경로 오타가 있으면 위 절대 경로 cd로 돌아가 ls를 실행하고 실제 파일명으로 다시 시도하세요. 같은 복구 방법으로 환경 초기화 없이 해결할 수 있습니다.
새 임시 로그인으로 정산 실행하기
이 단계에서는 작업 접근을 끝내기 전에 실제 보고서를 만듭니다. env.sh가 로드된 Terminal에 머무르세요.
umask 077은 새 파일을 자기 계정만 사용할 수 있게 합니다. bao read -format=json은 실제 동적 자격 증명을 요청하고 JSON을 출력합니다. >는 비밀번호를 화면에 출력하는 대신 파일에 저장합니다. 이 발급으로 10분 임대 시간이 시작됩니다.
umask 077
bao read -format=json database/creds/settlement-report > lease.json
jq는 JSON 필드를 선택합니다. 비밀이 아닌 임대 ID, 기간, 생성된 데이터베이스 사용자명을 읽으세요.
jq '.lease_id, .lease_duration, .data.username' lease.json
임대 ID는 OpenBao에서 이번 발급을, 사용자명은 PostgreSQL 로그인을 식별합니다. 둘 다 운영자 토큰은 아닙니다. 단지 다시 살펴보려는 목적으로 이 응답을 덮어쓰지 마세요. 접근을 끝낼 때 정확한 임대 ID가 필요합니다.
-r 옵션은 JSON 따옴표를 제거합니다. 따옴표로 감싼 명령 치환은 비밀번호를 출력하지 않고 생성된 사용자명과 비밀번호를 데이터베이스 클라이언트 환경에 로드합니다.
export PGUSER="$(jq -r .data.username lease.json)"
export PGPASSWORD="$(jq -r .data.password lease.json)"
psql -X는 개인 psql 시작 파일을 무시하고, -v ON_ERROR_STOP=1은 SQL 오류 시 중지하며, -c는 SQL 명령을 제공합니다. 실제 연결에 어떤 신원을 사용하는지 물으세요.
psql -X -v ON_ERROR_STOP=1 -c 'SELECT current_user;'
새로 생성된 사용자명이 나와야 합니다. -f report.sql은 준비된 쿼리를 읽고 >는 실제 탭 구분 출력을 저장합니다.
psql -X -v ON_ERROR_STOP=1 -f report.sql > settlement.tsv
cat settlement.tsv
정상 예시와 동일한 결제 주문 수와 합계를 가진 판매자 행 세 개가 모두 나와야 합니다. 읽기 전용 결과 검사를 실행하세요.
sudo python3 /opt/labex-report/verify.py result
준비된 검사기는 sudo로 보호된 자체 증거를 읽고 격리된 일반 계정 테스트 환경에서 정책 SQL을 시험합니다. 실제 자격 증명을 발급하거나 보고서를 생성하지 않습니다. 발급된 신원으로 실제 보고서 쿼리를 실행하지 않고 예시만 복사하면 통과하지 못합니다.
천천히 읽다가 보고서 실행 전에 로그인이 만료되면 대체 자격 증명을 한 번만 요청하고 데이터베이스 변수 두 개를 다시 로드한 뒤 신원 및 보고서 명령을 다시 실행하세요. 명시적으로 끝내려는 기존 발급이 있다면 다른 발급을 요청하기 전에 응답을 별도 파일명으로 보존하세요. 보고서 실행에 사용한 모든 대체 발급도 각각의 정확한 임대를 끝내야 합니다. 완료 검사는 가장 최근의 실제 보고서 실행을 사용합니다.
완료된 작업의 정확한 임대 해지하기
이 단계에서는 보고서 작업의 접근을 끝내고 저장된 이전 자격 증명으로 새 연결을 시험합니다. Terminal에 머무르세요.
bao lease revoke는 한 발급의 해지를 요청합니다. 따옴표로 감싼 $(jq -r .lease_id lease.json) 치환은 저장된 전체 임대 ID를 전달합니다. 데이터베이스 사용자명이나 다른 임대가 포함된 접두사 대신 그 정확한 ID를 사용하세요. 읽는 동안 이 10분 발급이 이미 만료되었다면 해지에서 임대를 더 이상 찾을 수 없다고 나올 수 있습니다. 명시적 해지 연습을 위해 이전 응답을 보존하고, 일반 역할의 대체 자격 증명을 새 파일명으로 발급받고, 데이터베이스 변수 두 개를 다시 로드하며 보고서를 다시 실행하세요. 아래 명령과 검사에서 대체 파일명을 사용하세요. 이미 만료된 발급은 여러분이 명시적으로 해지했다는 증거가 아닙니다.
bao lease revoke "$(jq -r .lease_id lease.json)"
CLI에서 해지 작업이 대기열에 들어갔다고 말할 수 있습니다. 이 응답만으로 PostgreSQL이 이전 로그인을 거부했음을 입증하지는 못합니다.
준비된 access.py 검사 도구는 저장된 자격 증명을 읽고 비밀번호로 인증하는 새 TCP 연결을 엽니다. --wait-denied 10은 비밀번호 거부를 최대 10초 기다립니다. 데이터베이스 사용 불가나 SQL 쿼리 거부와 구분하므로 서버를 중지해서는 충족할 수 없습니다.
python3 /opt/labex-report/access.py lease.json --wait-denied 10
PostgreSQL의 password authentication failed 메시지 뒤에 이 저장된 자격 증명으로 새 연결을 열 수 없다는 확인이 나와야 합니다. 검사 도구는 원래 psql 상태 2를 보고합니다. 검사 도구 자체는 예상된 거부를 확인한 뒤에만 성공을 반환합니다.
echo $?는 바로 앞 명령의 종료 상태를 출력합니다. 여기서는 0이 나와야 합니다. psql 연결에 성공한 것이 아니라 검사 도구가 의도한 실패를 성공적으로 확인했다는 뜻입니다.
echo $?
완료된 작업을 확인하세요.
sudo python3 /opt/labex-report/verify.py finished
검사는 자체 기록의 성공한 정확한 임대 해지, 대응하는 해지 완료 이벤트, 그 이후의 새 인증 실패, 실제로 사용할 수 없는 PostgreSQL 로그인을 요구합니다. 또한 완전한 보고서와 독립적인 상점/보고 기능을 그대로 유지합니다. 대신 해지해 주지는 않습니다.
이 연습은 짧게 실행되는 클라이언트 명령으로 만든 새 연결을 시험합니다. 비밀번호 만료가 이미 열린 모든 연결을 강제로 닫지는 않으며, 모든 프로덕션 연결 풀을 비웠다고 주장하지 않습니다.
별도 임대의 자연 만료 관찰하기
이 단계에서는 자연 만료와 직접 수행한 명시적 해지를 구분합니다. 같은 제한된 OpenBao 운영자를 사용하는 Terminal에서 진행하세요.
준비된 settlement-short 역할의 TTL은 30초입니다. 자격 증명을 요청하자마자 허용된 실제 읽기를 한 작업으로 시험하므로, 다음 설명을 읽는 동안 유효 시간이 소모되지 않습니다. &&는 자격 증명 발급이 성공할 때만 검사 도구를 실행합니다.
bao read -format=json database/creds/settlement-short > short-lease.json && python3 /opt/labex-report/access.py short-lease.json
생성된 사용자명, 실제 세 행의 정산 뷰, Native psql exit: 0이 나와야 합니다. 명시적으로 해지한 작업과 사용자명 및 임대 ID가 다릅니다. 읽기 전용 검사 도구는 보고서 파일을 만들거나 보고서 작업을 대신 완료하지 않습니다.
이제 이 임대가 저절로 만료되게 두세요. short-lease.json을 해지하거나 갱신하지 마세요. 다음 검사는 새 연결을 반복해 열며 실제 비밀번호 인증 거부를 최대 40초 기다립니다.
python3 /opt/labex-report/access.py short-lease.json --wait-denied 40
이 명령 전에 30초 넘게 읽었다면 거부가 즉시 나타날 수 있습니다. 앞의 결합 작업으로 자격 증명이 처음에는 작동했음이 이미 증명되었으므로 이 경우도 자연 만료입니다. 그렇지 않으면 만료까지 기다립니다. 앞서와 같은 PostgreSQL 자체 실패와 검사 도구의 확인이 나와야 합니다.
서버를 사용할 수 없다는 연결 오류는 만료의 증거가 아닙니다. 초기 발급이나 직후 읽기가 실패하면 결합 작업을 다시 시도하기 전에 해당 오류를 살펴보세요. 사용하지 않은 유효하지 않은 비밀번호를 작동하던 자격 증명이 만료된 증거로 제시하지 마세요. 최종 검사는 실제 성공한 짧은 역할의 읽기, 자체 만료 이벤트, 이후 인증 거부를 요구합니다.
임대 시간은 초기 설정이 아니라 여러분의 요청으로 시작되었습니다. 우연한 시작 시간 창 안에 입력해야 하는 단계는 없습니다.
새 로그인으로 복구하고 그 접근도 끝내기
이 단계에서는 이전 자격 증명이 작동을 멈춘 뒤 나중 보고서 시도를 완료합니다. Terminal에 머무르세요. 복구란 승인된 서비스를 통해 새 자격 증명을 발급받는 것입니다. 이전 응답을 편집해도 데이터베이스 신원이 갱신되지 않습니다.
이전 증거가 보존되도록 일반 역할의 새 발급을 다른 이름으로 저장하세요.
bao read -format=json database/creds/settlement-report > recovery-lease.json
새 신원을 로드하고 같은 실제 보고서를 실행하세요.
export PGUSER="$(jq -r .data.username recovery-lease.json)"
export PGPASSWORD="$(jq -r .data.password recovery-lease.json)"
psql -X -v ON_ERROR_STOP=1 -f report.sql > settlement.tsv
cat settlement.tsv
완전한 업무 결과는 바뀌지 않습니다. 데이터베이스 사용자명은 새것이며 이전 발급이 끝난 뒤의 정상적인 복구 경로입니다.
이 대체 작업의 정확한 임대도 끝내세요.
bao lease revoke "$(jq -r .lease_id recovery-lease.json)"
python3 /opt/labex-report/access.py recovery-lease.json --wait-denied 10
다른 대체 로그인으로 보고서를 다시 실행한다면 그 정확한 임대도 끝내세요. 완료 검사는 가장 최근 실제 보고서 실행에 사용된 신원을 사용하므로, 이전 계정의 해지가 나중 작업의 종료를 증명하지 않습니다.
준비된 상점 클라이언트는 독립적인 쓰기 신원을 사용합니다. 오늘의 정상 주문이 남아 있는지 확인하세요.
python3 shop.py list
최종 수명주기 검사를 실행하세요.
sudo python3 /opt/labex-report/verify.py lifecycle
읽기 전용 보존 검사를 하기 전에 기존 자체 발급, 쿼리, 해지, 인증 이벤트를 읽습니다. 명시적 해지, 자연 만료, 대체 로그인 복구의 구분된 증거와 시험한 이전 자격 증명으로 새 연결을 열 수 없다는 확인이 나와야 합니다. 원본 보고서 데이터, 상점, 독립적인 재고 자격 증명은 그대로 남아 있어야 합니다.
읽는 동안 대체 로그인이 만료되어 보고서 명령이 실패하면 응답을 보존하고, 새 파일명으로 다른 대체 발급을 요청하며, 데이터베이스 변수를 다시 로드하고 보고서를 다시 실행한 뒤 그 새 정확한 임대를 끝내세요. 같은 배운 명령을 해당 파일명으로 사용하세요. 이전 사용자명의 만료를 연장하거나 역할 접두사 전체를 해지하지 마세요.
요약
실제 보고서를 실행하고 정확한 임대를 끝냈으며 별도 자격 증명의 자연 만료를 관찰했습니다. 새로 발급된 신원으로 복구한 뒤 그 작업의 접근도 끝냈습니다. 대기열에 들어간 요청과 실제 데이터베이스 거부, 중지된 서비스와 비밀번호 거부를 구별했습니다.
결과는 이 준비된 환경에서 비밀번호로 인증하는 새 연결로 의도적으로 범위를 제한합니다. 이미 열려 있는 모든 세션이나 프로덕션 연결 풀이 종료되었다고 주장하지 않습니다. 챌린지에서는 다른 보고 뷰에 대해 권한 정책과 완료된 작업의 수명주기를 결합합니다.


