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:
@@ -124,6 +124,120 @@ func (m *mockVault) CreatePolicy(ctx context.Context, token string, rule PolicyR
|
||||
|
||||
func (m *mockVault) DeletePolicy(ctx context.Context, token, id string) error { return nil }
|
||||
|
||||
// SSH CA stubs
|
||||
func (m *mockVault) GetSSHCAPublicKey(ctx context.Context, mount string) (*SSHCAPublicKey, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) SSHCASignHost(ctx context.Context, token, mount string, req SSHCASignRequest) (*SSHCASignResult, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) SSHCASignUser(ctx context.Context, token, mount string, req SSHCASignRequest) (*SSHCASignResult, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) ListSSHCAProfiles(ctx context.Context, token, mount string) ([]SSHCAProfileSummary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockVault) GetSSHCAProfile(ctx context.Context, token, mount, name string) (*SSHCAProfile, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) CreateSSHCAProfile(ctx context.Context, token, mount string, req SSHCAProfileRequest) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) UpdateSSHCAProfile(ctx context.Context, token, mount, name string, req SSHCAProfileRequest) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) DeleteSSHCAProfile(ctx context.Context, token, mount, name string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) ListSSHCACerts(ctx context.Context, token, mount string) ([]SSHCACertSummary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockVault) GetSSHCACert(ctx context.Context, token, mount, serial string) (*SSHCACertDetail, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) RevokeSSHCACert(ctx context.Context, token, mount, serial string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) DeleteSSHCACert(ctx context.Context, token, mount, serial string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) GetSSHCAKRL(ctx context.Context, mount string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// Transit stubs
|
||||
func (m *mockVault) ListTransitKeys(ctx context.Context, token, mount string) ([]TransitKeySummary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockVault) GetTransitKey(ctx context.Context, token, mount, name string) (*TransitKeyDetail, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) CreateTransitKey(ctx context.Context, token, mount, name, keyType string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) DeleteTransitKey(ctx context.Context, token, mount, name string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) RotateTransitKey(ctx context.Context, token, mount, name string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) UpdateTransitKeyConfig(ctx context.Context, token, mount, name string, minDecryptVersion int, allowDeletion bool) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockVault) TrimTransitKey(ctx context.Context, token, mount, name string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (m *mockVault) TransitEncrypt(ctx context.Context, token, mount, key, plaintext, transitCtx string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) TransitDecrypt(ctx context.Context, token, mount, key, ciphertext, transitCtx string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) TransitRewrap(ctx context.Context, token, mount, key, ciphertext, transitCtx string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) TransitSign(ctx context.Context, token, mount, key, input string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) TransitVerify(ctx context.Context, token, mount, key, input, signature string) (bool, error) {
|
||||
return false, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) TransitHMAC(ctx context.Context, token, mount, key, input string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) GetTransitPublicKey(ctx context.Context, token, mount, name string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// User stubs
|
||||
func (m *mockVault) UserRegister(ctx context.Context, token, mount string) (*UserKeyInfo, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) UserProvision(ctx context.Context, token, mount, username string) (*UserKeyInfo, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) GetUserPublicKey(ctx context.Context, token, mount, username string) (*UserKeyInfo, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) ListUsers(ctx context.Context, token, mount string) ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockVault) UserEncrypt(ctx context.Context, token, mount, plaintext, metadata string, recipients []string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) UserDecrypt(ctx context.Context, token, mount, envelope string) (*UserDecryptResult, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) UserReEncrypt(ctx context.Context, token, mount, envelope string) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) UserRotateKey(ctx context.Context, token, mount string) (*UserKeyInfo, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
func (m *mockVault) UserDeleteUser(ctx context.Context, token, mount, username string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockVault) Close() error { return nil }
|
||||
|
||||
// ---- handleTGZDownload tests ----
|
||||
|
||||
Reference in New Issue
Block a user