Showing all phase content; selected phase is highlighted in section badges.

Risk Register

As-of: 2026-05-09. Source: codebase inspection, manifest.yaml deviations, project state.

Likelihood: Low / Medium / High. Impact: Low / Medium / High / Critical. Status: Open / Mitigated / Accepted / Closed.


R-001: Keeper Trial Expiry

FieldValue
RiskKeeper trial expires before integration is validated end-to-end
LikelihoodHigh — trial is a 12-day window from 2026-04-25 provisioning
ImpactCritical — KSM reads stop working, Commander shares become unavailable, staging vault integration is dead
MitigationConvert trial to paid license before expiry. Contact Keeper sales for enterprise pricing and timeline.
StatusOpen
OwnerBen / CTO (budget approval)

R-002: Bot Framework Not Registered

FieldValue
RiskTeams notification flow cannot be exercised end-to-end
LikelihoodHigh — no bot is registered, M365 admin involvement required
ImpactMedium — notifications fall back to in-app (Prisma Notification table). No user-facing impact until Teams delivery is needed.
MitigationRegister bot, wire notification.service.ts to real Adaptive Card delivery. Requires M365 admin approval.
StatusOpen
OwnerBen (engineering) / M365 admin (approval)

R-003: Frontend Test Runner Not Wired

FieldValue
RiskUI regressions ship undetected
LikelihoodMedium — changes to frontend are infrequent right now but will increase in v3
ImpactMedium — no automated safety net for frontend changes
MitigationWire vitest into frontend/package.json scripts. Expand from 2 test files (governance.spec.ts, RequestIssuancePanel.test.tsx) to baseline coverage.
StatusOpen
OwnerBen

R-004: Hand-Linked SQL Between Postgres and Keeper UIDs

FieldValue
RiskBootstrap title-match linkage between Postgres Record.vaultRecordUid and Keeper vault UIDs is fragile; discovery rebuild may produce inconsistent state
LikelihoodMedium — works now but will break if vault records are renamed or re-created
ImpactMedium — incorrect linkage means wrong credential gets shared
MitigationFinalize UID-pinned discovery (option B). Either reconcile existing hand-linked SQL or reset and re-bootstrap. vaultRecordUidPinned flag exists for this purpose.
StatusOpen
OwnerBen

R-005: KSM Application IP Lock

FieldValue
RiskKSM Application was created with IP lock checked. SDK calls from App Service may fail if the IP lock doesn’t match the App Service’s outbound IP (or NAT Gateway IP in production).
LikelihoodHigh — IP lock is checked by default at KSM Application creation
ImpactHigh — KSM reads fail, which means vault record metadata is unavailable
MitigationUncheck IP lock in Keeper Console, or delete and recreate the KSM Application without IP lock. If IP lock is desired, configure it to match App Service outbound IPs and NAT Gateway IP.
StatusOpen
OwnerBen

R-006: HARDEN_GOVERNANCE_v1 Never Tested in True Mode

FieldValue
RiskFlipping HARDEN_GOVERNANCE_v1=true in production without prior staging validation may break issuance flows
LikelihoodMedium — the code paths exist and are unit-tested, but the flag has never been exercised in a running environment
ImpactHigh — if the hardened flow breaks, credential delivery stops
MitigationFlip to true on staging first. Run the full approve-then-issue integration flow. Validate issuance token generation, delivery, verification, and rate-limiting. Only then flip in production.
StatusOpen
OwnerBen

R-007: Production App Service Not Provisioned

FieldValue
RiskNo path to production. app-passkey-prod-1353 exists as a resource but has no deployed code, incomplete Entra config (ENTRA_APP_ID_HERE placeholders in appsettings-prod.json), and no VNet/NAT Gateway.
LikelihoodHigh — this is a known gap, not a probabilistic risk
ImpactMedium — blocks any production use. Not critical while in pilot/staging.
MitigationComplete appsettings-prod.json, register Entra app for production, provision VNet + NAT Gateway, deploy, validate. See Roadmap v3.
StatusOpen
OwnerBen / CTO (infrastructure approval)

R-008: Commander CLI as Single Point of Failure for Shares

FieldValue
RiskAll share creation flows through python3 -m keepercommander subprocess. If Keeper changes the Commander CLI behavior, output format, or authentication model, share creation breaks.
LikelihoodLow — Keeper Commander is a stable product, but CLI tools do change between major versions
ImpactHigh — share creation is the core value proposition; if it breaks, credentials can’t be issued
MitigationPin Commander version. Error classification (classifyCommanderError) handles known failure modes. parseShareUrl regex extracts URLs from stdout. Consider wrapping Commander in a versioned Docker container for isolation.
StatusAccepted
OwnerBen

R-009: Key Vault Dependency

FieldValue
RiskIf Azure Key Vault access fails, the application fails to start (DATABASE_URL, KSM_CONFIG are KV references)
LikelihoodLow — Azure KV has 99.99% SLA
ImpactCritical — complete application outage
MitigationKV is a fundamental Azure platform dependency. Acceptable risk. Monitor KV health via Application Insights. Consider caching resolved secrets with a TTL if cold-start latency becomes an issue.
StatusAccepted
OwnerBen

R-010: v4 SMS Adds SIM-Swap and Interception Risk

FieldValue
RiskSMS-based OTP is vulnerable to SIM swap attacks and SS7 interception. An attacker who controls the phone number can intercept the OTP and complete credential retrieval.
LikelihoodLow for targeted attacks on enterprise users; Medium if high-value credentials are at stake
ImpactHigh — complete bypass of the second factor
MitigationSMS alone is insufficient. v4 hardening should add device-bound MFA on top (FIDO2, app-based TOTP, or push notification). SMS serves as a usability layer, not the security boundary.
StatusOpen (v4 conceptual)
OwnerCTO (security architecture decision)

R-011: Entra Client Secret in Provisioning Transcript

FieldValue
RiskEntra client secret appeared in the provisioning chat transcript (noted in manifest.yaml deviation client-secret-in-transcript)
LikelihoodLow — transcript access is limited
ImpactMedium — if the secret is compromised, an attacker could impersonate the application to Entra
MitigationRotate the client secret before production deployment. Acceptable for staging.
StatusOpen
OwnerBen

R-012: Incomplete Prisma Migration Chain

FieldValue
RiskPrisma migrations assume a pre-existing base schema. Staging was bootstrapped with db push (not migrate deploy). A new environment can’t be stood up from the migration chain alone.
LikelihoodHigh — will be hit when deploying to production
ImpactMedium — workaround exists (db push), but it’s not suitable for production (no migration history, no rollback)
MitigationCreate a baseline migration that captures the current schema state. All future changes go through prisma migrate dev / prisma migrate deploy.
StatusOpen
OwnerBen

R-013: Default Postgres Database Name

FieldValue
RiskStaging uses the default postgres database instead of a dedicated passkey database (noted in manifest.yaml deviation default-postgres-db)
LikelihoodMedium — acceptable for staging, problematic for production (shared namespace, backup/restore ambiguity)
ImpactLow — no functional impact, but violates best practices for production deployments
MitigationCreate dedicated passkey database before production deployment.
StatusOpen
OwnerBen

R-014: getFolderPermissions() Stubbed in Real Implementation

FieldValue
RiskRealVaultReadService.getFolderPermissions() throws “not supported by KSM SDK.” Interface method exists but has zero callers in production code. If a future feature depends on it, it will fail silently in real mode.
LikelihoodLow — no current callers
ImpactLow — no functional impact unless a new feature calls it
MitigationDocument the limitation. If folder-level ACL resolution is needed from the real vault, it must come through Commander or the Keeper REST API (not KSM).
StatusAccepted
OwnerBen