Skip to Content
플랫폼 아키텍처Vault 세션/정책 (3 layer)

Vault 세션/정책 모델 (3 layer)

AXE Vaultwarden (Timshel fork 기반, D-ops-37 + D-ops-40) 의 session/unlock 정책은 3 layer 누적으로 결정. 각 layer 가 누가 통제하는지 + 변경 비용이 다름.

Layer통제 누가영향 범위변경 비용
1. Server env (Vaultwarden config)운영자 (compose env_file)모든 user, 모든 clientcontainer restart 1회
2. Org Policies (Bitwarden 호환 정책)Org Owner (web UI 또는 API)해당 org member 전원, 모든 client즉시 (next login 적용)
3. Per-client preferences (localStorage)각 user 본인 (각 device/client 마다)본인의 그 client 만본인 30초

3 layer 가 누적 적용 — 각 layer 가 더 paranoia 방향으로 강제하고, 마지막 user 자율 layer 가 ceiling 안에서 편의 조정.

Layer 1 — Server env

Vaultwarden config 의 env var. /Users/axe/.axe/vault/docker-compose.ymlenvironment: 블록.

핵심: SSO_AUTH_ONLY_NOT_SESSION

효과
false (default)SSO 의 refresh token 따라감 — Entra ID 의 token 만료 시점에 자동 logout → re-SSO+MP 강제. user 입력 빈도 ↑
true (AXE 현재 설정, 2026-05-26)SSO 가 인증만, session lifecycle 은 Vaultwarden 자체 30일 idle refresh token 사용. user 가 30일 안 idle 안 하면 무한 갱신

적용 효과 (AXE 4 user):

  • SSO+MP 재입력 = 약 월 1회 (idle 30일 + browser 재시작 시)
  • Touch ID/PIN unlock 은 daily

trade-off:

  • Entra 측 user 비활성/제명이 server session 에 ≤30일 lag
  • offboarding 시 운영자가 수동으로 vault 측에서도 user 비활성 (UI: AXE org → Manage → Members → user → Remove + admin panel 에서 user disable) — AXE 4명 규모 충분 처리 가능
  • customer 규모 ↑ 시 재평가 (별 결정)

다른 관련 env

env효과
SSO_ONLY=falseMP 단독 fallback 유지 (D-ops-26 + D-ops-27)
SIGNUPS_ALLOWED=trueJIT user provisioning (SSO 신규 user 자동 생성)
SSO_SCOPES="openid profile offline_access User.Read"offline_access = refresh token 발급
ORGANIZATION_INVITE_AUTO_ACCEPT=trueinvite Accept 단계 자동 통과

Vaultwarden 미지원 (의도):

  • ❌ Maximum Vault Timeout — Bitwarden commercial license, AGPLv3 비호환 (source comment : // MaximumVaultTimeout = 9, // Not supported (Not AGPLv3 Licensed))
  • ❌ Disable Personal Vault Export — 동일 license 사유
  • ❌ Activate Autofill, Automatic App LogIn — Vaultwarden 미구현

→ vault timeout 의 server-side 강제는 영구 영역 외. SSO_AUTH_ONLY_NOT_SESSION=true 가 가용 영역 안 best 대체.

Layer 2 — Org Policies (Bitwarden 호환)

Org Owner 가 /api/organizations/<orgId>/policies/<type> (Bitwarden 정책 docs ) 또는 web UI 로 설정. Vaultwarden 의 supported set  안에서.

현재 AXE org 적용 (2026-05-26, D-ops-40 Progress)

type정책효과
1MasterPasswordmin 12자, complexity 1MP 변경 시점 검증. 기존 MP 영향 0 (paranoia 옵션)
2PasswordGeneratorlength 20, upper+lower+number+specialitem 신규 생성 시 강한 default
3SingleOrgenabledmember 가 다른 org 가입 차단 → 데이터 누설 방지
5PersonalOwnershipenabled신규 item 은 org collection 필수 (D-ops-32 본질 정합)

의도적 미설정 (D-ops-38 + D-ops-26+27):

type정책왜 안 켜나
0TwoFactorAuthenticationEntra SSO 가 이미 MFA 역할 (D-ops-38) — vault 자체 2FA 중복
8ResetPassword운영자 직권 reset 보존 (default), 강제 policy 불필요
14RemoveUnlockWithPinPIN unlock = 일상 편의 핵심, 차단하면 user 경험 악화

Vaultwarden 미지원 (Bitwarden Cloud 에서는 가능):

type정책사유
4RequireSsoVaultwarden 미구현 (의도 — MP 단독 fallback 보존 정책과 정합)
9MaximumVaultTimeoutAGPL 비호환
10DisablePersonalVaultExportAGPL 비호환

API 호출 패턴

# AXE org policy 조회 export BW_SESSION="$(security find-generic-password -s 'axe.vault.session' -w)" AI_USER=0ef2361b-5a69-4c23-973d-e978a4d55512 # ai@ ORG=0c5d8bbd-ad85-42b4-8b8a-2849031981b1 # AXE TOKEN=$(jq -r ".\"user_${AI_USER}_token_accessToken\"" \ "$HOME/Library/Application Support/Bitwarden CLI/data.json") curl -sf -H "Authorization: Bearer $TOKEN" \ "https://axe.axelabs.ai/vault/api/organizations/$ORG/policies" \ | jq '.data | map({type, enabled})' # 정책 변경 (예: MasterPassword 정책 수정) curl -sf -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ "https://axe.axelabs.ai/vault/api/organizations/$ORG/policies/1" \ -d '{"type":1,"enabled":true,"data":{"minComplexity":2,"minLength":14,"requireUpper":false,"requireLower":false,"requireNumbers":false,"requireSpecial":false,"enforceOnLogin":false}}'

token 만료 시 (~1h) bw sync 로 refresh.

Layer 3 — Per-client preferences

vault timeout / PIN / Touch ID / theme = 각 device 의 client localStorage. server 가 못 건드림 (Bitwarden 디자인 — privacy by design, prefs 가 user device 안). 정책 부재 시 각 client 의 첫 사용에서 user 가 선택.

AXE 표준 setup (KDF rotation 완료 후 권장)

4 user 모두 + 모든 새 직원 다음 3 client 설정:

A. Web vault (보조용, https://axe.axelabs.ai/vault )

field권장
Vault timeoutOn browser refresh (web vault 의 최장 옵션 — Never 노출 안 됨)
Vault timeout actionLock (Logout 절대 X — SSO 재진입 비용)

설정 위치: 우상단 본인 이름 → Account settings → Preferences

B. Chrome extension (일상 brower-bound)

field권장
Server URL (self-hosted)https://axe.axelabs.ai/vault
Vault timeoutNever (extension 은 Never 노출됨)
Vault timeout actionLock
Unlock with PIN code✅ + PIN 4~12자 (e.g. axe-2026 word)
Lock with master password on browser restart✅ (paranoia 균형)

C. Native macOS app (daily driver — 가장 편함)

field권장
Server URL (self-hosted)https://axe.axelabs.ai/vault
Vault timeoutNever
Vault timeout actionLock
Unlock with Touch ID✅ (macOS Secure Enclave)
Lock with master password on browser restart

실 효과 (3 layer 누적):

  • daily unlock = Touch ID (수 초)
  • 주 1-2회 = PIN (Chrome ext)
  • 월 1회 (idle 30일 또는 paranoia 재시작) = MP

Vault scope — 무엇을 보호하는가 (trust boundary)

Vault 는 secret 의 저장 + retrieval + access control 만 담당하는 저장소. vault item 을 delete/revoke 했다고 해서 그 secret 이 의미하는 외부 service 의 권한·계정·2FA 가 자동으로 무효화되지 않음. 두 영역을 혼동하면 offboarding/사고 대응 시 access 잔존 위험.

경계 도식

┌─ Vault scope (이 페이지 + Vaultwarden 이 통제) ──────────┐ │ • secret 값의 저장 / 암호화 (Argon2id + KDF) │ │ • org collection 기반 access control (Layer 2) │ │ • SSO + MP unlock lifecycle (Layer 1, 3) │ │ • item delete/revoke → 그 저장 위치 에서 차단 │ └──────────────────────────────────────────────────────────┘ ↓ vault item 은 외부 service 의 "거울" 일 뿐 ┌─ 외부 service scope (vault 가 못 건드림) ─────────────────┐ │ • 해당 service 측 계정 자체 (Microsoft / Google / ...) │ │ • TOTP secret 의 generation (해당 service 가 발급) │ │ • OAuth client_secret / refresh token invalidation │ │ • GitHub PAT, API key 의 server 측 revoke │ │ • customer 측 데이터 자체 (KB / 홈택스 export 등) │ └──────────────────────────────────────────────────────────┘

회수 범위 = vault item delete + 외부 service 측 절차. 둘 다 해야 완전.

회수 대상별 분리표

회수 대상vault 가 처리외부 service 측 절차 필요
service password 저장값✅ item delete/revoke해당 service 의 password reset (admin 또는 본인)
TOTP secret (2FA)✅ item delete해당 service 의 2FA reset → TOTP secret regenerate
OAuth client_secret✅ item deleteAzure / Google / GitHub 측에서 client_secret 재발급 + 옛값 폐기
GitHub PAT✅ item deleteGitHub Settings → Personal access tokens → Revoke (server 측 token row 무효화)
API key (Anthropic / OpenAI / etc)✅ item delete해당 provider 의 console 에서 key revoke
KB / 홈택스 / 회계법인 portal admin 계정❌ vault scope 외 (계정 자체는 vault 가 보관 안 함)해당 portal admin 의 계정 비활성/삭제
Microsoft 365 / Entra ID 계정❌ vault scope 외customer IT 가 Entra ID 에서 user 비활성
customer 측 데이터 (Excel, PDF 등 export 본)❌ vault scope 외customer 자체 DLP / device wipe / 법적 요구

함의

  • offboarding 시: /ops/runbook/employee-offboarding 의 “외부 service 권한 회수” 표를 vault item 제거와 반드시 병행.
  • secret rotation 시: vault item 값을 새로 채우는 것 만으로는 옛값이 외부 service 측에서 살아있음 — /ops/runbook/secret-rotation 의 외부 service rotation step 동반.
  • 사고 대응 시: vault item delete = “이 운영자 머신/AXE org 안에서 더 못 꺼냄”. 그 secret 이 leak 된 정황이면 외부 service 측 revoke 가 본질.

3 layer 누적 그림

┌──────────────────────────────────────────────────────────┐ │ Layer 3: Per-client preferences (user 자율) │ │ • web `On browser refresh` Lock │ │ • extension `Never` + PIN │ │ • native `Never` + Touch ID │ │ ↓ 위 layer 의 ceiling 안에서 user 편의 조정 │ ├──────────────────────────────────────────────────────────┤ │ Layer 2: Org Policies (Owner 통제, member 전원 적용) │ │ • MasterPassword min 12, complexity 1 │ │ • PasswordGenerator length 20 │ │ • SingleOrg │ │ • PersonalOwnership │ │ ↓ 모든 member 자동 │ ├──────────────────────────────────────────────────────────┤ │ Layer 1: Server env (운영자 통제, 전 instance) │ │ • SSO_AUTH_ONLY_NOT_SESSION=true → 30일 session │ │ • SSO_ONLY=false → MP fallback │ │ • SIGNUPS_ALLOWED=true → JIT │ │ ↓ 인스턴스 기본값 │ └──────────────────────────────────────────────────────────┘

새 직원 onboarding 의무 step

  1. KDF rotation (1회) — B-vault-axe.2-sso-mp-incomplete runbook
    • 옛 PBKDF2 → Argon2id 로 vault re-encrypt
    • SSO→MP wrapped variant 정합 (D-ops-40)
  2. Layer 3 setup (1회 per device) — 위 Web/Extension/Native 표 그대로
  3. 끝 — 이후 일상은 Touch ID/PIN 만

운영자가 1번 안내 1회 + 2번 표 공유 1회 = onboarding 끝. layer 1+2 는 server 가 자동.

Customer (Truvia 등) — sovereignty

Layercustomer 자율도
Layer 1 (server env)customer 자체 통제 — customer 의 macmini compose, customer 자율. AXE 가 권장만 (이 페이지 참조 안내)
Layer 2 (org policies)customer org Owner 가 설정 — AXE 가 정책 enforce 불가. 권장 (위 4 정책 동일)
Layer 3 (per-client)customer 직원 본인 — 동일 setup 권장

→ customer 운영자에게 본 페이지 link 만 전달, 권장 follow. /services/vault 의 customer onboarding 단계에 vault setup 포함 (TODO).

함정

함정결과회피
Maximum Vault Timeout 정책 시도 (Bitwarden 패턴)HTTP 400 “Invalid or unsupported policy type”Vaultwarden 미지원 (AGPL). 대신 SSO_AUTH_ONLY_NOT_SESSION=true 사용
SSO_ONLY=true + Entra ID 장애운영자 vault 진입 불가 (lockout)SSO_ONLY=false 유지 (D-ops-26 + D-ops-27) — MP fallback 보존
RemoveUnlockWithPin 정책 enablePIN unlock 불가 → 일상 MP 입력 강제본 정책 enable 금지 (paranoia 와 편의 균형)
옛 KDF (PBKDF2) user 가 SSO→MP unlock 실패client 가 wrapped MP 변환 불가user 별 KDF rotation 의무 (onboarding step 1)
Org policy 변경이 즉시 client 에 반영 안 되는 듯client 가 sync 시점에 fetchbw sync 또는 client 강제 sync (일반적 ≤1분 안 자동)
운영자가 Layer 3 강제 시도 (Chrome managed policy 등)macmini 별 enrollment 필요 — overhead 큼AXE 4명 규모 = docs 안내 + 신뢰. 10+ 직원 시점에 재평가 (B-vault-chrome-mdm-policy-distribution)
Entra user 비활성 후 ≤30일 server session 잔존offboard 직후 vault 접근 가능offboard 시 운영자가 vault admin panel 에서 user disable 같이 실행 (manual checklist)

관련

Last updated on