Gate
한 줄 소개: 의사결정을 증명 가능하게 남기는 거버넌스 서비스. 내부 결재(기안 → 상신 → 승인 → 시행)와 외부 계약 e-sign 을 한 곳에서 처리하고, 시행 시 gate-native CAdES-T(RFC3161 TSA) 봉인을 동기 생성해 결정 자체를 위·변조 불가한 SoR 로 만든다. 원본 문서는 암호화해 같은 곳에 보존한다. (D-gate-5)
서비스 경계(어떤 문서가 gate 에, 무엇이 index/hive 로) = D-gate-index-boundary · /architecture/data.
기술 스택
| 항목 | 값 |
|---|---|
| 언어 | Rust |
| 프레임워크 | axum + maud (서버렌더 HTML) |
| DB | PostgreSQL 16 + sqlx (compile-time embedded migrations) |
| 암호 | e-sign 자체 엔진(crypto.rs/tsa.rs/pades.rs/hsm.rs); PII·해시는 pgcrypto in-SQL (Rust 대칭암호 dep 0) |
| e-sign | CAdES-T (detached CMS RSA-2048+SHA256 + RFC3161 TSA) · PAdES-B-T (typst + pyHanko) |
| 배포 | build-from-SHA blue/green + Caddy proxy (cortex 패턴) |
| repo | github.com/axelabs-ai/gate (canonical /Users/axe/gate) |
포트 (41xx)
| 포트 | 용도 |
|---|---|
| 4100 | PostgreSQL 16 (gate-postgres) |
| 4110 | gate-mcp-blue (active, docker alias gate-mcp) |
| 4111 | gate-mcp-green (passive) |
| 127.0.0.1:4112 | axe-gate-proxy (Caddy blue/green selector, loopback 바인딩) |
- 공개:
axe.axelabs.ai/gate/mcp(MCP) +gate.axelabs.ai(웹 UI, Entra SSO). 내부: Tailscale100.127.210.30:4112·127.0.0.1:4112. - ⚠️ Phase-1 internal —
_HEALTH_SERVICES제외(auto-reconcile /axe health비대상, auto-deploy 서프라이즈 방지). MCP edge(/gate/mcp) cloudflared origin 은 Phase-5 deferred(edge-probe informational·non-fatal); 웹 UI 터널은 live.
인증 — 3단 래더
순서대로 시도, 먼저 통과하는 분기가 actor 를 확정:
- HS256 gate JWT (1순위) —
GATE_JWT_SECRET서명, claims{sub, email, iss:"gate"}. gate OAuth AS 발급분(claude.ai 등이 항상 보내는 형태). 외부세션(knd="ext")은 MCP 거부 → fall-through. - Blueprint RS256 플랫폼 토큰 —
BLUEPRINT_ISSUER=https://axe.axelabs.ai설정 시 ON.axe login통합 SSO — 2026-06-14 issuer flip(D-bp-oidc-issuer-1)으로 동작. gate 는 토큰의scope를 전혀 참조하지 않음 → 서명(RS256) +iss+aud(axe.axelabs.ai) +exp만 검증하므로, frame/hive 와 같은 토큰 한 장이 그대로 통과. - Entra ID 직접 RS256 (기본) — Microsoft JWKS, operator dev /
azcli / claude.ai confidential client.
공통: alg=RS256 고정(alg-confusion 차단), peek-then-fully-verify (frame auth_blueprint.py 미러).
RLS = 두 갈래 OR (가시성): ① participant-RLS gate_is_participant(wf_id) = 기안자 ∪ 결재선 · ② entity_membership gate_member_of_* (D-gate-7) = axec/axev 내부 멤버는 그 법인의 전체 결정기록 read(additive FOR SELECT, 읽기 전용 — 결재 전이는 participant 만). 비참여·비멤버 = 빈 결과(기밀 경계). CLI gate add-member/rm-member/list-members.
MCP 도구 (18)
axe.axelabs.ai/gate/mcp (Bearer JWT). 결재 라이프사이클 → 원본·전문 → 외부 e-sign → 메타 순:
| 도구 | rw | 용도 |
|---|---|---|
draft_document | write | HTML 기안 문서 생성 |
create_workflow | write | 문서 위 결재 워크플로 생성 |
submit_workflow | write | 상신 (draft → in_review, 결재선 생성) |
act_on_step | write | 결재 — 승인 / 반려 / 보류 |
execute_workflow | write | 시행 — 전자서명 봉인 (approved → done) |
withdraw_workflow | write | 기안자 철회 |
set_doa_policy | write | 전결규정(결재선 template) 등록 |
get_workflow | read | 워크플로 전체 타임라인 조회 |
list_inbox | read | 내 결재함 + 내 차례 표시 |
verify_seal | read | CAdES-T 봉인 암호학적 검증 |
attach_evidence | write | 결정기록에 원본 문서 암호화 첨부 |
set_evidence_content | write | 추출한 계약 전문 HTML 저장 (upsert) |
get_evidence | read | 첨부 원본 메타 + 무결성검증 |
list_evidence | read | 워크플로 첨부 원본 메타 목록 |
create_signing_envelope | write | 외부 계약 서명 요청 발송 (sign_url 반환) |
get_envelope_status | read | 외부 서명 envelope 상태 조회 |
whoami | read | 인증 actor + DB actor 확인 |
list_entities | read | 법인 entity 카탈로그 (axec / axev) |
빠른 사용 — CLI (axe gate)
Web ERP 없이 터미널에서 내부 결재 + 외부 계약. 조회는 웹(gate.axelabs.ai)도 가능. 전 라이프사이클 e2e 검증됨.
# 1회 로그인 (브라우저 SSO — 운영자 토큰 발급 불요)
axe self-update # 0.1.10+ (gate 명령 포함)
axe login # Entra / Blueprint 통합 SSO
# 내부 결재 — 기안 → 상신 → 승인 → 시행 → 검증
axe gate inbox # 내 결재함 (참여 중 + 내 차례)
axe gate show <id> # 상세 (상태·결재선·봉인·원본)
axe gate draft --title "용역 계약" --decision-type contract --kind contract \
--entity axev --amount 50000000 --self # 기안+상신 (--line a@x,b@y 로 결재선 지정)
axe gate approve <id> --comment "검토 완료" # 승인 (reject / hold 동일)
axe gate execute <id> [--pdf] # 시행 — CAdES-T 봉인 (--pdf 시 PAdES PDF 동시 생성)
axe gate verify <id> # 봉인 암호검증 (CMS·TSA·무결성)
axe gate withdraw <id> # 기안자 철회
# 외부 계약 e-sign
axe gate sign-send <id> --signer [email protected]:홍길동 --mode sequential # 서명자별 링크 발송 (--signer 반복)
axe gate sign-status <id>
# 조회 / 메타
axe gate entities | whoami | toolse-sign 봉인 + 원본 보존
- 봉인 (
esign_seal, mig 0005): 시행 시 결정 정본 바이트에 detached CAdES-BES CMS(RSA-2048 + SHA256) 서명 → RFC3161 TSA(기본 DigiCert, 한국 prod 은GATE_TSA_URL로 Koscom/CrossCert swap) 타임스탬프 부착 = CAdES-T. append-only(gate_append_only트리거 +REVOKE UPDATE,DELETE).verify_seal//gate/wf/:id/seal가 CMS 서명 + TSA + 3-해시 일치 재검증. 서명 신원 = self-signed X.509 또는 PKCS#11 HSM(load_esign_signer우선순위 PKCS#11 → KEY_PEM → KEY_DIR → dev-ephemeral). - 원본 보존 (
decision_evidence, D-gate-6): 결정기록에 원본 PDF 바이트를pgp_sym_encrypt_bytea(원본, GATE_PII_PASSPHRASE_<entity>)로 암호 첨부.sha256= 원본 평문 해시(봉인된 body 해시와 대조 → ‘봉인 해시 ↔ 실제 바이트’ 고리 닫음). participant-RLS + append-only. read 시 복호화 후 재해시 == 저장 해시 검증(integrity_ok). passphrase 미설정 = fail-closed(평문 보관 거부). - 계약 전문 (
evidence_content, v7): 스캔 날인본(텍스트 레이어 0 →pdftotext빈 결과)을 vision 으로 전사한 HTML 가독 view. body 요약·원본 PDF(법적 정본)와 별개이며 mutable(재추출 upsert). RLS = participant OR entity-member(read) / participant(write).
웹 (gate.axelabs.ai)
Entra SSO 로그인 → 대시보드 /gate/app · 결재함 /gate/inbox · 계약 /gate/contracts · 워크플로 상세 /gate/wf/:id(결재선·봉인·원본 문서 섹션 + 원본 inline 다운로드 /gate/wf/:id/evidence/:eid, 한글 파일명 RFC 5987, no-store). 외부 서명자는 무로그인 /gate/sign/:token(토큰=인가, RLS 우회), 외부 회원은 매직링크 /gate/my 포털(knd=ext 세션, email 스코프 IDOR 차단). @axe/ui 디자인 시스템.
배포
axe ship gate # release-gate + build-from-SHA + blue/green (직접 git push 금지 — pre-push guard)
# 또는: axe deploy gate --apply (deploy hook gate_blue_green, 무중단 alias swap)
# ⚠️ gate 는 mcp-http 만 → 마이그레이션 자동 적용 안 됨. 배포 후 active color 에 수동:
docker exec gate-mcp-<active> gate migrate- env_file =
.env.local(vault dump, D-ops-17).environment:블록은 non-secret/identity 만(BLUEPRINT_ISSUER/JWKS_URL/AUDIENCE,GATE_DB_HOST등 — 비밀 중복 금지). - secrets 4종:
GATE_DB_PASSWORD·GATE_JWT_SECRET·GATE_ESIGN_WEBHOOK_SECRET·GATE_ESIGN_KEY_PEM(escrow/DR). per-entityGATE_PII_PASSPHRASE_<entity>(vaultgate/axe/pii-passphrase-<entity>). 서명 키는/run/esign(blue+green 공유 bind-mount, 단일 봉인 신원).