Add web UI for SSH CA, Transit, and User engines; full security audit and remediation
Web UI: Added browser-based management for all three remaining engines (SSH CA, Transit, User E2E). Includes gRPC client wiring, handler files, 7 HTML templates, dashboard mount forms, and conditional navigation links. Fixed REST API routes to match design specs (SSH CA cert singular paths, Transit PATCH for update-key-config). Security audit: Conducted full-system audit covering crypto core, all engine implementations, API servers, policy engine, auth, deployment, and documentation. Identified 42 new findings (#39-#80) across all severity levels. Remediation of all 8 High findings: - #68: Replaced 14 JSON-injection-vulnerable error responses with safe json.Encoder via writeJSONError helper - #48: Added two-layer path traversal defense (barrier validatePath rejects ".." segments; engine ValidateName enforces safe name pattern) - #39: Extended RLock through entire crypto operations in barrier Get/Put/Delete/List to eliminate TOCTOU race with Seal - #40: Unified ReWrapKeys and seal_config UPDATE into single SQLite transaction to prevent irrecoverable data loss on crash during MEK rotation - #49: Added resolveTTL to CA engine enforcing issuer MaxTTL ceiling on handleIssue and handleSignCSR - #61: Store raw ECDH private key bytes in userState for effective zeroization on Seal - #62: Fixed user engine policy resource path from mountPath to mountName() so policy rules match correctly - #69: Added newPolicyChecker helper and passed service-level policy evaluation to all 25 typed REST handler engine.Request structs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
// vaultBackend is the interface used by WebServer to communicate with the vault.
|
||||
// It is satisfied by *VaultClient and can be replaced with a mock in tests.
|
||||
type vaultBackend interface {
|
||||
// System
|
||||
Status(ctx context.Context) (string, error)
|
||||
Init(ctx context.Context, password string) error
|
||||
Unseal(ctx context.Context, password string) error
|
||||
@@ -30,6 +31,9 @@ type vaultBackend interface {
|
||||
ValidateToken(ctx context.Context, token string) (*TokenInfo, error)
|
||||
ListMounts(ctx context.Context, token string) ([]MountInfo, error)
|
||||
Mount(ctx context.Context, token, name, engineType string, config map[string]interface{}) error
|
||||
Close() error
|
||||
|
||||
// PKI / CA
|
||||
GetRootCert(ctx context.Context, mount string) ([]byte, error)
|
||||
GetIssuerCert(ctx context.Context, mount, issuer string) ([]byte, error)
|
||||
ImportRoot(ctx context.Context, token, mount, certPEM, keyPEM string) error
|
||||
@@ -41,11 +45,54 @@ type vaultBackend interface {
|
||||
ListCerts(ctx context.Context, token, mount string) ([]CertSummary, error)
|
||||
RevokeCert(ctx context.Context, token, mount, serial string) error
|
||||
DeleteCert(ctx context.Context, token, mount, serial string) error
|
||||
|
||||
// Policy
|
||||
ListPolicies(ctx context.Context, token string) ([]PolicyRule, error)
|
||||
GetPolicy(ctx context.Context, token, id string) (*PolicyRule, error)
|
||||
CreatePolicy(ctx context.Context, token string, rule PolicyRule) (*PolicyRule, error)
|
||||
DeletePolicy(ctx context.Context, token, id string) error
|
||||
Close() error
|
||||
|
||||
// SSH CA
|
||||
GetSSHCAPublicKey(ctx context.Context, mount string) (*SSHCAPublicKey, error)
|
||||
SSHCASignHost(ctx context.Context, token, mount string, req SSHCASignRequest) (*SSHCASignResult, error)
|
||||
SSHCASignUser(ctx context.Context, token, mount string, req SSHCASignRequest) (*SSHCASignResult, error)
|
||||
ListSSHCAProfiles(ctx context.Context, token, mount string) ([]SSHCAProfileSummary, error)
|
||||
GetSSHCAProfile(ctx context.Context, token, mount, name string) (*SSHCAProfile, error)
|
||||
CreateSSHCAProfile(ctx context.Context, token, mount string, req SSHCAProfileRequest) error
|
||||
UpdateSSHCAProfile(ctx context.Context, token, mount, name string, req SSHCAProfileRequest) error
|
||||
DeleteSSHCAProfile(ctx context.Context, token, mount, name string) error
|
||||
ListSSHCACerts(ctx context.Context, token, mount string) ([]SSHCACertSummary, error)
|
||||
GetSSHCACert(ctx context.Context, token, mount, serial string) (*SSHCACertDetail, error)
|
||||
RevokeSSHCACert(ctx context.Context, token, mount, serial string) error
|
||||
DeleteSSHCACert(ctx context.Context, token, mount, serial string) error
|
||||
GetSSHCAKRL(ctx context.Context, mount string) ([]byte, error)
|
||||
|
||||
// Transit
|
||||
ListTransitKeys(ctx context.Context, token, mount string) ([]TransitKeySummary, error)
|
||||
GetTransitKey(ctx context.Context, token, mount, name string) (*TransitKeyDetail, error)
|
||||
CreateTransitKey(ctx context.Context, token, mount, name, keyType string) error
|
||||
DeleteTransitKey(ctx context.Context, token, mount, name string) error
|
||||
RotateTransitKey(ctx context.Context, token, mount, name string) error
|
||||
UpdateTransitKeyConfig(ctx context.Context, token, mount, name string, minDecryptVersion int, allowDeletion bool) error
|
||||
TrimTransitKey(ctx context.Context, token, mount, name string) (int, error)
|
||||
TransitEncrypt(ctx context.Context, token, mount, key, plaintext, transitCtx string) (string, error)
|
||||
TransitDecrypt(ctx context.Context, token, mount, key, ciphertext, transitCtx string) (string, error)
|
||||
TransitRewrap(ctx context.Context, token, mount, key, ciphertext, transitCtx string) (string, error)
|
||||
TransitSign(ctx context.Context, token, mount, key, input string) (string, error)
|
||||
TransitVerify(ctx context.Context, token, mount, key, input, signature string) (bool, error)
|
||||
TransitHMAC(ctx context.Context, token, mount, key, input string) (string, error)
|
||||
GetTransitPublicKey(ctx context.Context, token, mount, name string) (string, error)
|
||||
|
||||
// User (E2E encryption)
|
||||
UserRegister(ctx context.Context, token, mount string) (*UserKeyInfo, error)
|
||||
UserProvision(ctx context.Context, token, mount, username string) (*UserKeyInfo, error)
|
||||
GetUserPublicKey(ctx context.Context, token, mount, username string) (*UserKeyInfo, error)
|
||||
ListUsers(ctx context.Context, token, mount string) ([]string, error)
|
||||
UserEncrypt(ctx context.Context, token, mount, plaintext, metadata string, recipients []string) (string, error)
|
||||
UserDecrypt(ctx context.Context, token, mount, envelope string) (*UserDecryptResult, error)
|
||||
UserReEncrypt(ctx context.Context, token, mount, envelope string) (string, error)
|
||||
UserRotateKey(ctx context.Context, token, mount string) (*UserKeyInfo, error)
|
||||
UserDeleteUser(ctx context.Context, token, mount, username string) error
|
||||
}
|
||||
|
||||
const userCacheTTL = 5 * time.Minute
|
||||
|
||||
Reference in New Issue
Block a user