리스펙스 바우치 사용하기

출판사가 최종 파일을 인쇄소에 넘길 때 책임 기록을 남깁니다.

네이티브와 새 작업 디렉터리를 준비하세요. 명령은 Windows의 Git Bash 같은 POSIX 셸에서 실행합니다. 이 실습에서는 발급자와 수신자 역할을 한곳에서 수행합니다. 실제 수신자는 발급자의 공개키와 정확한 실행 파일 식별자와 규칙 소스를 독립적으로 검토합니다.

규칙과 입력 준비하기

전체 프로그램을 print-handoff.lspx로 저장하세요. 앱이 최종 파일을 검사하고 네 가지 통과 여부를 정해진 순서로 전달합니다.

LISPEX
(define 인쇄-규격-통과?
  (and (car input)
       (car (cdr input))
       (car (cdr (cdr input)))
       (car (cdr (cdr (cdr input))))))

(if 인쇄-규격-통과?
    (decision-approve)
    (decision-deny))

input.checked.json을 다음 내용 그대로 저장하세요. 두 파일 모두 BOM 없는 UTF-8과 LF 줄바꿈, 마지막 줄바꿈 하나를 사용합니다. 입력의 공백 두 칸 들여쓰기도 유지합니다.

JSON
{
  "input": "csk.checked-input/v1",
  "value": [
    true,
    true,
    true,
    true,
    "edition-final"
  ]
}

앞의 네 값은 순서대로 판형과 여백, 글꼴 포함, 쪽수가 검사를 통과했다는 뜻입니다. 다섯 번째 값은 양쪽이 합의한 최종 파일 판을 식별합니다. 앱이 그 판을 실제 제작 파일에 연결하고 보관합니다. 규칙은 불리언 네 개를 읽고 서명은 입력 다섯 값 전체를 묶습니다. 이 예제의 답은 approve입니다. csk.checked-profile/v1은 여기서 사용하는 언어 프로파일입니다.

서명 키 준비하기

실습용 Ed25519 키 쌍을 로컬에서 만들고 공개키를 검사합니다.

SH
lispex key generate --out-dir issuer-key
lispex key inspect --public-key issuer-key/public.spki.der

두 명령은 종료 코드 0으로 끝납니다. 생성 명령은 "status": "generated"가 있는 JSON을 출력합니다. issuer-key/private.pkcs8.der와 issuer-key/public.spki.der도 만듭니다. 검사 명령은 "status": "valid"가 있는 JSON을 출력합니다. 발급자는 개인키로 서명합니다. 수신자는 정책에 넣을 공개키를 고르며, 개인키는 발급자가 보관합니다.

선택한 파일의 식별자를 출력합니다. /absolute/path/to/lispex를 네이티브 실행 파일의 절대 경로로 바꾸세요. Windows에서는 D:/tools/lispex.exe 같은 경로를 사용할 수 있습니다.

SH
lispex vouch key-id --public-key issuer-key/public.spki.der
lispex vouch engine-id --executable /absolute/path/to/lispex
lispex vouch source-id --source print-handoff.lspx
lispex vouch input-id --input input.checked.json

각 명령은 식별자 하나를 출력하고 종료 코드 0으로 끝납니다. key-id는 생성한 키에 따라 달라집니다. engine-id는 sha256:로 시작하며 정확한 실행 파일을 식별합니다. 이 값을 검토한 뒤 정책에 사용하세요. 위 소스와 입력을 사용하면 마지막 두 명령은 다음 값을 출력합니다.

62c5df19ad4786acfab0e57101bed3c2c2a6fd57ce66d75f82f951e751c38669
9e1f420be1fc34992b76a0b1d88ea20e72243f6f4ca5a80210298e1693d006cf

1. 수신자 정책 만들기

ENGINE_ID의 자리표시자를 검토한 engine-id 출력 전체로 바꾸세요. sha256:도 포함합니다. 공개키와 소스도 직접 검토한 파일을 지정하세요.

SH
ENGINE_ID="sha256:<reviewed-native-engine-digest>"
lispex vouch policy create \
  --public-key issuer-key/public.spki.der \
  --engine-sha256 "$ENGINE_ID" \
  --source print-handoff.lspx \
  --out policy.json

lispex vouch policy check --trust-policy policy.json

생성 명령은 policy.json을 씁니다. 두 명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. 정책은 허용할 키와 엔진과 언어 프로파일과 소스 식별자를 하나로 정해진 바이트 형식으로 저장합니다. 이 단계는 신뢰 설정을 준비합니다. 다음에는 발급자가 실행 기록에 서명합니다.

2. 서명된 기록 발급하기

ISSUER_KEY_URI에는 pkcs8-file:// 뒤에 개인키의 절대 경로를 붙이세요. Linux나 macOS 경로는 pkcs8-file:///로 시작합니다. Windows에서는 pkcs8-file://D:/vouch-example/issuer-key/private.pkcs8.der 같은 값을 사용합니다. 아래 경로를 바꾼 뒤 실행하세요.

SH
ISSUER_KEY_URI="pkcs8-file:///absolute/path/to/issuer-key/private.pkcs8.der"
lispex vouch issue \
  --source print-handoff.lspx \
  --input input.checked.json \
  --profile csk.checked-profile/v1 \
  --key-handle "$ISSUER_KEY_URI" \
  --out-dir issued \
  --emit-bundle

명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. 네이티브는 리스펙스 인터프리터와 Meaning 인터프리터로 소스를 실행하고 두 전체 실행 기록에 서명합니다. 리스펙스 인터프리터는 소스를 읽고 핵심 형식인 CoreExpr로 정규화한 뒤 평가합니다. Meaning은 그 소스에서 만든 중간 표현을 평가합니다.

명령은 issued/ 아래에 다음 파일을 만듭니다. 발급할 때마다 새 출력 디렉터리를 고르세요.

파일내용
issue-report.json"status": "issued-native"와 "primary_error": null이 있는 발급 결과
payload.json소스와 입력과 프로파일과 엔진과 결과를 포함한 전체 실행 정보
envelope.dsse.jsonDSSE 형식의 서명된 기록 묶음
vouch-input-bundle.json봉투와 소스와 입력 바이트를 담은 전송 묶음

전송 묶음에는 바이트 한도가 있습니다. 다음에는 수신자 정책에 따라 서명을 검사합니다.

3. 전송 묶음 인증하기

SH
lispex vouch verify \
  --bundle issued/vouch-input-bundle.json \
  --trust-policy policy.json \
  --profile csk.checked-profile/v1 \
  --report-out authenticated.json

명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. authenticated.json의 authentication_status는 "authenticated"이고 primary_error는 null입니다. 정책이 허용한 키가 정책에 맞는 내용에 서명했음을 확인한 것입니다.

보고서의 comparison_status: "agree"는 서명된 실행 기록을 설명합니다. 현재 실행은 5단계에서 확인합니다. 먼저 자신이 고른 소스와 입력을 결속하세요.

4. 자신의 요청 결속하기

직접 고른 소스와 입력을 전송 묶음과 별도로 전달합니다.

SH
lispex vouch verify \
  --bundle issued/vouch-input-bundle.json \
  --trust-policy policy.json \
  --source print-handoff.lspx \
  --input input.checked.json \
  --profile csk.checked-profile/v1 \
  --report-out bound.json

명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. 두 파일의 정확한 바이트가 서명된 내용과 일치하면 bound.json에 authentication_status: "authenticated"를 씁니다. 보고서 형식은 3단계와 같습니다. 이번 명령에서 따로 제공한 소스와 입력으로 요청 결속을 확인합니다.

검사를 마친 리스펙스 이미지는 --source 대신 --source-image로 제공할 수 있습니다. --input은 계속 직접 지정하세요. 네이티브 재실행과 게이트에는 소스와 입력 경로가 모두 필요합니다. 한쪽만 주면 파일을 읽기 전에 거부합니다.

5. 현재 실행 확인하기

SH
lispex vouch verify \
  --bundle issued/vouch-input-bundle.json \
  --trust-policy policy.json \
  --source print-handoff.lspx \
  --input input.checked.json \
  --profile csk.checked-profile/v1 \
  --reexecute \
  --report-out current.json

명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. current.json에 다음 결과를 씁니다.

필드값
authentication.status"authenticated"
reexecution.status"execution-agreed"
comparison.current_vs_signed"agree"

네이티브가 현재 tree와 Meaning의 전체 실행 기록을 서명된 기록과 비교했습니다. 다음에는 애플리케이션에 필요한 결정을 요구합니다.

6. 필요한 결정 요구하기

SH
lispex vouch gate \
  --bundle issued/vouch-input-bundle.json \
  --trust-policy policy.json \
  --source print-handoff.lspx \
  --input input.checked.json \
  --profile csk.checked-profile/v1 \
  --require-decision approve \
  --report-out gate.json

명령은 종료 코드 0으로 끝나며 표준 출력은 비어 있습니다. gate.json을 만듭니다. 그 안의 gate 객체는 다음과 같습니다.

JSON
{
  "basis": "csk.current-native-agreement/v0",
  "observed_decision": "approve",
  "reason": null,
  "required_decision": "approve",
  "status": "granted"
}

게이트는 이번 호출 안에서 인증하고 요청을 결속하고 규칙을 재실행한 뒤 요구한 결정과 비교합니다. 로컬 통과 결과는 네이티브 프로세스 안에서 생성됩니다. 보고서는 결과를 살펴보고 로그를 남길 수 있도록 그 결과를 기록합니다.

거부 결과를 보려면 위 명령을 --require-decision deny와 --report-out denied.json으로 바꿔 실행하세요. 종료 코드는 10이며 표준 출력은 비어 있습니다. 보고서에는 gate.status: "denied"와 gate.reason: "required-decision-mismatch"가 기록됩니다. 관측한 결정은 여전히 "approve"입니다. 거부 뒤에는 보고서를 확인하고 애플리케이션의 다음 행동을 결정하세요.

호출 애플리케이션은 호출자 신원과 요청 유효 시점과 만료와 폐기를 확인합니다. 요청 재사용과 업무 승인과 트랜잭션 상태도 확인합니다. 인쇄 작업 승인 같은 외부 행동은 애플리케이션이 제어합니다.

컴파일 실행 추가하거나 애플리케이션 연결하기

컴파일 예제는 tree와 Meaning 검사에 리스펙스 VM 일치를 더합니다. 네이티브는 요청 인증 뒤 이름의 참조를 정한 중간 표현인 Core IR과 바이트코드를 다시 만듭니다.

로컬 게이트 결과를 애플리케이션에 연결하려면 판단 뒤 앱이 할 일을 보세요. 출력 파일을 읽는 방법은 실행 기록과 보고서에 있습니다.