Archive: System v4 - Estado al 2024-12-24
This commit is contained in:
595
v4-archive/contratos-comunes/docs/KEY_VAULT.md
Normal file
595
v4-archive/contratos-comunes/docs/KEY_VAULT.md
Normal file
@@ -0,0 +1,595 @@
|
||||
# 07c. KEY VAULT Y CRIPTOGRAFÍA
|
||||
**Manual de Arquitectura Técnica — Documento 07c**
|
||||
**Versión:** 1.2
|
||||
**Dependencia:** `S-CONTRACT.md`
|
||||
**Estado:** Enterprise Standard
|
||||
|
||||
---
|
||||
|
||||
# C.1 Introducción
|
||||
|
||||
El Key Vault es el **tercer espacio de almacenamiento** del ecosistema, separado de:
|
||||
- **Libro Mayor (SFE)**: Datos de negocio
|
||||
- **Almacenamiento de archivos**: Hostinger/S3
|
||||
- **Key Vault**: Llaves, credenciales y secretos
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ PRINCIPIO DE SEPARACIÓN │
|
||||
│ │
|
||||
│ "Las llaves nunca viajan con los datos que protegen" │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.2 Arquitectura del Key Vault
|
||||
|
||||
## C.2.1 Componentes
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ KEY VAULT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ SECRETS │ │ KEYS │ │ CERTS │ │
|
||||
│ │ STORE │ │ STORE │ │ STORE │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └──────────────────┼──────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ ACCESS │ │
|
||||
│ │ CONTROL │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ AUDIT LOG │ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## C.2.2 Tipos de Secretos
|
||||
|
||||
| Tipo | Descripción | Ejemplo | Rotación |
|
||||
|------|-------------|---------|----------|
|
||||
| **API_KEY** | Llaves de APIs externas | OpenRouter, Groq | 90 días |
|
||||
| **ENCRYPTION_KEY** | Llaves de cifrado de datos | AES-256 keys | 365 días |
|
||||
| **DB_CREDENTIAL** | Credenciales de bases de datos | NocoDB, PostgreSQL | 30 días |
|
||||
| **SERVICE_TOKEN** | Tokens de servicios internos | n8n, Nextcloud | 7 días |
|
||||
| **USER_SECRET** | Secretos específicos de usuario | OAuth tokens | Variable |
|
||||
| **CERTIFICATE** | Certificados TLS/mTLS | SSL certs | 90 días |
|
||||
| **SIGNING_KEY** | Llaves de firma digital | JWT signing | 180 días |
|
||||
|
||||
---
|
||||
|
||||
# C.3 Modelo de Datos
|
||||
|
||||
## C.3.1 Tabla VAULT_SECRETS
|
||||
|
||||
```sql
|
||||
CREATE TABLE VAULT_SECRETS (
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- IDENTIFICACIÓN
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
secret_id VARCHAR(100) UNIQUE NOT NULL,
|
||||
version INTEGER DEFAULT 1,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CLASIFICACIÓN
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
secret_type VARCHAR(50) NOT NULL,
|
||||
category VARCHAR(50),
|
||||
tags VARCHAR(50)[],
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- VALOR (CIFRADO)
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
encrypted_value BYTEA NOT NULL,
|
||||
encryption_algorithm VARCHAR(50) DEFAULT 'AES-256-GCM',
|
||||
key_encryption_key_id VARCHAR(100),
|
||||
nonce BYTEA,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- METADATA
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
description TEXT,
|
||||
owner_id UUID,
|
||||
owner_type VARCHAR(50),
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CICLO DE VIDA
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
status VARCHAR(20) DEFAULT 'ACTIVE',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
expires_at TIMESTAMPTZ,
|
||||
last_rotated_at TIMESTAMPTZ,
|
||||
rotation_interval_days INTEGER,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- ACCESO
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
access_policy JSONB DEFAULT '{}',
|
||||
allowed_modules VARCHAR(50)[],
|
||||
allowed_players UUID[],
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- AUDITORÍA
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
access_count INTEGER DEFAULT 0,
|
||||
last_accessed_at TIMESTAMPTZ,
|
||||
last_accessed_by VARCHAR(100),
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CONSTRAINTS
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
CONSTRAINT valid_status CHECK (
|
||||
status IN ('ACTIVE', 'DISABLED', 'EXPIRED', 'ROTATING', 'DELETED')
|
||||
),
|
||||
CONSTRAINT valid_type CHECK (
|
||||
secret_type IN ('API_KEY', 'ENCRYPTION_KEY', 'DB_CREDENTIAL',
|
||||
'SERVICE_TOKEN', 'USER_SECRET', 'CERTIFICATE', 'SIGNING_KEY')
|
||||
)
|
||||
);
|
||||
|
||||
-- Índices
|
||||
CREATE INDEX idx_vault_secret_id ON VAULT_SECRETS(secret_id);
|
||||
CREATE INDEX idx_vault_type ON VAULT_SECRETS(secret_type);
|
||||
CREATE INDEX idx_vault_status ON VAULT_SECRETS(status);
|
||||
CREATE INDEX idx_vault_expires ON VAULT_SECRETS(expires_at) WHERE expires_at IS NOT NULL;
|
||||
CREATE INDEX idx_vault_owner ON VAULT_SECRETS(owner_id);
|
||||
```
|
||||
|
||||
## C.3.2 Tabla VAULT_ACCESS_LOG
|
||||
|
||||
```sql
|
||||
CREATE TABLE VAULT_ACCESS_LOG (
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- IDENTIFICACIÓN
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- SECRETO ACCEDIDO
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
secret_id VARCHAR(100) NOT NULL,
|
||||
secret_version INTEGER,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CONTEXTO DE ACCESO
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
trace_id UUID,
|
||||
step_id UUID,
|
||||
module_name VARCHAR(50),
|
||||
operation VARCHAR(50) NOT NULL,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- ACTOR
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
accessor_type VARCHAR(50) NOT NULL,
|
||||
accessor_id VARCHAR(100) NOT NULL,
|
||||
accessor_ip INET,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- RESULTADO
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
status VARCHAR(20) NOT NULL,
|
||||
error_code VARCHAR(50),
|
||||
error_message TEXT,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- TEMPORALIDAD
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
||||
duration_ms INTEGER,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- SEGURIDAD
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
encryption_profile VARCHAR(20),
|
||||
purpose TEXT,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CONSTRAINTS
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
CONSTRAINT valid_operation CHECK (
|
||||
operation IN ('READ', 'CREATE', 'UPDATE', 'DELETE', 'ROTATE',
|
||||
'ENABLE', 'DISABLE', 'LIST', 'DECRYPT', 'ENCRYPT')
|
||||
),
|
||||
CONSTRAINT valid_access_status CHECK (
|
||||
status IN ('SUCCESS', 'DENIED', 'ERROR', 'EXPIRED', 'NOT_FOUND')
|
||||
),
|
||||
CONSTRAINT valid_accessor CHECK (
|
||||
accessor_type IN ('MODULE', 'PLAYER', 'SYSTEM', 'ADMIN', 'SERVICE')
|
||||
)
|
||||
);
|
||||
|
||||
-- Índices para auditoría eficiente
|
||||
CREATE INDEX idx_vault_log_secret ON VAULT_ACCESS_LOG(secret_id);
|
||||
CREATE INDEX idx_vault_log_trace ON VAULT_ACCESS_LOG(trace_id) WHERE trace_id IS NOT NULL;
|
||||
CREATE INDEX idx_vault_log_timestamp ON VAULT_ACCESS_LOG(timestamp);
|
||||
CREATE INDEX idx_vault_log_accessor ON VAULT_ACCESS_LOG(accessor_type, accessor_id);
|
||||
CREATE INDEX idx_vault_log_denied ON VAULT_ACCESS_LOG(status, timestamp)
|
||||
WHERE status = 'DENIED';
|
||||
```
|
||||
|
||||
## C.3.3 Tabla VAULT_ENCRYPTION_KEYS (KEK)
|
||||
|
||||
```sql
|
||||
CREATE TABLE VAULT_ENCRYPTION_KEYS (
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- IDENTIFICACIÓN
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
key_id VARCHAR(100) UNIQUE NOT NULL,
|
||||
version INTEGER DEFAULT 1,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- PROPIEDADES
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
algorithm VARCHAR(50) NOT NULL DEFAULT 'AES-256-GCM',
|
||||
key_size_bits INTEGER NOT NULL DEFAULT 256,
|
||||
purpose VARCHAR(50) NOT NULL,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- VALOR (protegido por Master Key externa)
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
encrypted_key_material BYTEA NOT NULL,
|
||||
master_key_ref VARCHAR(100),
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CICLO DE VIDA
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
status VARCHAR(20) DEFAULT 'ACTIVE',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
activated_at TIMESTAMPTZ,
|
||||
expires_at TIMESTAMPTZ,
|
||||
deactivated_at TIMESTAMPTZ,
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
-- CONSTRAINTS
|
||||
-- ═══════════════════════════════════════════════════════════
|
||||
CONSTRAINT valid_kek_status CHECK (
|
||||
status IN ('PENDING', 'ACTIVE', 'DEACTIVATED', 'DESTROYED')
|
||||
),
|
||||
CONSTRAINT valid_purpose CHECK (
|
||||
purpose IN ('DATA_ENCRYPTION', 'SECRET_ENCRYPTION', 'SIGNING', 'KEY_WRAPPING')
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.4 Perfiles de Cifrado
|
||||
|
||||
## C.4.1 Perfil NONE
|
||||
|
||||
```yaml
|
||||
profile: NONE
|
||||
description: "Sin cifrado gestionado por el sistema"
|
||||
transport: TLS 1.3 (obligatorio)
|
||||
at_rest: Sin cifrar
|
||||
use_cases:
|
||||
- Datos públicos
|
||||
- Logs técnicos no sensibles
|
||||
- Métricas de rendimiento
|
||||
key_vault: No requerido
|
||||
```
|
||||
|
||||
## C.4.2 Perfil E2E_BASIC
|
||||
|
||||
```yaml
|
||||
profile: E2E_BASIC
|
||||
description: "Cifrado estándar para datos internos"
|
||||
transport: TLS 1.3
|
||||
at_rest:
|
||||
algorithm: AES-256-GCM
|
||||
key_derivation: PBKDF2-SHA256
|
||||
key_rotation: Anual
|
||||
use_cases:
|
||||
- Documentos internos
|
||||
- Emails corporativos
|
||||
- Datos de configuración
|
||||
key_vault:
|
||||
required: true
|
||||
key_type: ENCRYPTION_KEY
|
||||
access_policy: module_based
|
||||
```
|
||||
|
||||
## C.4.3 Perfil E2E_STRICT
|
||||
|
||||
```yaml
|
||||
profile: E2E_STRICT
|
||||
description: "Cifrado fuerte para datos sensibles"
|
||||
transport: mTLS (mutual TLS)
|
||||
at_rest:
|
||||
algorithm: AES-256-GCM
|
||||
key_derivation: Argon2id
|
||||
key_rotation: Trimestral
|
||||
envelope_encryption: true
|
||||
additional:
|
||||
- PII masking antes de procesar
|
||||
- Audit logging obligatorio
|
||||
- Zero-knowledge donde sea posible
|
||||
use_cases:
|
||||
- PII (datos personales)
|
||||
- Datos financieros
|
||||
- Información médica
|
||||
- Biometría
|
||||
key_vault:
|
||||
required: true
|
||||
key_type: ENCRYPTION_KEY
|
||||
access_policy: per_record
|
||||
key_isolation: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.5 Operaciones del Key Vault
|
||||
|
||||
## C.5.1 URIs del Key Vault
|
||||
|
||||
El contrato común usa referencias URI al Key Vault:
|
||||
|
||||
```
|
||||
kv://production/encryption/player_abc123
|
||||
kv://production/api-keys/openrouter
|
||||
kv://staging/certificates/mtls-client
|
||||
```
|
||||
|
||||
Formato:
|
||||
```
|
||||
kv://{environment}/{category}/{secret_id}
|
||||
```
|
||||
|
||||
## C.5.2 Integración con el Contrato
|
||||
|
||||
En el request:
|
||||
```json
|
||||
"security": {
|
||||
"encryption_profile": "E2E_STRICT",
|
||||
"data_sensitivity": "HIGH",
|
||||
"key_vault_ref": "kv://production/encryption/player_abc123"
|
||||
}
|
||||
```
|
||||
|
||||
Alfred al procesar:
|
||||
1. Extrae `key_vault_ref`
|
||||
2. Solicita la llave al Key Vault (pasando `trace_id`)
|
||||
3. Descifra el payload si viene cifrado
|
||||
4. Procesa con GRACE
|
||||
5. Cifra el resultado con la misma llave (o una derivada)
|
||||
6. Almacena resultado cifrado
|
||||
|
||||
---
|
||||
|
||||
# C.6 Flujo de Cifrado End-to-End
|
||||
|
||||
## C.6.1 Envelope Encryption
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ENVELOPE ENCRYPTION │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ Plaintext │ │
|
||||
│ │ Data │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Data │◄───│ DEK │ (Data Encryption Key) │
|
||||
│ │ Encrypted │ │ (efímera) │ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ │ DEK │◄───│ KEK │ │
|
||||
│ │ │ Encrypted │ │ (Key Vault) │ │
|
||||
│ │ └──────┬──────┘ └─────────────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────────────────────────────┐ │
|
||||
│ │ Stored Package: │ │
|
||||
│ │ - encrypted_data │ │
|
||||
│ │ - encrypted_dek │ │
|
||||
│ │ - kek_id │ │
|
||||
│ │ - nonce │ │
|
||||
│ │ - algorithm │ │
|
||||
│ └──────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## C.6.2 Implementación Python
|
||||
|
||||
```python
|
||||
import os
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
import base64
|
||||
|
||||
class EnvelopeEncryption:
|
||||
"""Implementa envelope encryption para E2E_STRICT."""
|
||||
|
||||
def __init__(self, key_vault_client):
|
||||
self.vault = key_vault_client
|
||||
|
||||
async def encrypt(self, plaintext: bytes, kek_id: str) -> dict:
|
||||
"""Cifra datos usando envelope encryption."""
|
||||
# 1. Generar DEK efímera
|
||||
dek = os.urandom(32)
|
||||
data_nonce = os.urandom(12)
|
||||
|
||||
# 2. Cifrar datos con DEK
|
||||
aesgcm = AESGCM(dek)
|
||||
encrypted_data = aesgcm.encrypt(data_nonce, plaintext, None)
|
||||
|
||||
# 3. Obtener KEK y cifrar DEK
|
||||
kek = await self.vault.get_secret(kek_id)
|
||||
dek_nonce = os.urandom(12)
|
||||
kek_aesgcm = AESGCM(kek)
|
||||
encrypted_dek = kek_aesgcm.encrypt(dek_nonce, dek, kek_id.encode())
|
||||
|
||||
return {
|
||||
"encrypted_data": base64.b64encode(encrypted_data).decode(),
|
||||
"encrypted_dek": base64.b64encode(encrypted_dek).decode(),
|
||||
"data_nonce": base64.b64encode(data_nonce).decode(),
|
||||
"dek_nonce": base64.b64encode(dek_nonce).decode(),
|
||||
"kek_id": kek_id,
|
||||
"algorithm": "AES-256-GCM"
|
||||
}
|
||||
|
||||
async def decrypt(self, package: dict) -> bytes:
|
||||
"""Descifra datos usando envelope encryption."""
|
||||
# 1. Obtener KEK
|
||||
kek = await self.vault.get_secret(package["kek_id"])
|
||||
|
||||
# 2. Descifrar DEK
|
||||
kek_aesgcm = AESGCM(kek)
|
||||
dek = kek_aesgcm.decrypt(
|
||||
base64.b64decode(package["dek_nonce"]),
|
||||
base64.b64decode(package["encrypted_dek"]),
|
||||
package["kek_id"].encode()
|
||||
)
|
||||
|
||||
# 3. Descifrar datos
|
||||
aesgcm = AESGCM(dek)
|
||||
return aesgcm.decrypt(
|
||||
base64.b64decode(package["data_nonce"]),
|
||||
base64.b64decode(package["encrypted_data"]),
|
||||
None
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.7 Gestión de Llaves
|
||||
|
||||
## C.7.1 Jerarquía de Llaves
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ JERARQUÍA DE LLAVES │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ MASTER KEY (MK) │ │
|
||||
│ │ Almacenada fuera del sistema │ │
|
||||
│ │ (HSM / KMS externo / Variable de entorno) │ │
|
||||
│ └────────────────────────┬────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────┼───────────────┐ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ KEK-DATA │ │ KEK-SECRETS │ │ KEK-SIGNING │ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ DEK-1..n │ │ API Keys │ │ JWT Keys │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## C.7.2 Política de Rotación
|
||||
|
||||
| Tipo de Llave | Rotación | Período de Gracia | Automatizable |
|
||||
|---------------|----------|-------------------|---------------|
|
||||
| Master Key | Anual | 30 días | No (manual) |
|
||||
| KEK | Semestral | 14 días | Sí |
|
||||
| DEK | Por sesión | N/A | Automático |
|
||||
| API Keys | 90 días | 7 días | Sí |
|
||||
|
||||
---
|
||||
|
||||
# C.8 Control de Acceso
|
||||
|
||||
## C.8.1 Políticas de Acceso
|
||||
|
||||
```json
|
||||
{
|
||||
"secret_id": "openrouter-api-key",
|
||||
"access_policy": {
|
||||
"type": "MODULE_BASED",
|
||||
"rules": [
|
||||
{
|
||||
"principal_type": "MODULE",
|
||||
"principals": ["CLASSIFIER", "SUMMARIZER", "OCR_CORE"],
|
||||
"operations": ["READ"],
|
||||
"conditions": {
|
||||
"require_trace_id": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"principal_type": "ADMIN",
|
||||
"principals": ["admin@tzzr.pro"],
|
||||
"operations": ["READ", "UPDATE", "ROTATE", "DELETE"],
|
||||
"conditions": {
|
||||
"require_mfa": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_deny": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.9 Integración con SENTINEL
|
||||
|
||||
## C.9.1 Reglas de Auditoría
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
KV-001:
|
||||
name: "Accesos denegados excesivos"
|
||||
severity: HIGH
|
||||
condition: "denied_count_1h > 5 per accessor"
|
||||
action: ALERT_SECURITY
|
||||
|
||||
KV-002:
|
||||
name: "Secreto próximo a expirar"
|
||||
severity: MEDIUM
|
||||
condition: "expires_at < NOW() + 7 days"
|
||||
action: NOTIFY_ADMIN
|
||||
|
||||
KV-003:
|
||||
name: "Rotación pendiente"
|
||||
severity: MEDIUM
|
||||
condition: "last_rotated_at < NOW() - rotation_interval"
|
||||
action: SCHEDULE_ROTATION
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# C.10 Checklist de Implementación
|
||||
|
||||
## Infraestructura:
|
||||
- [ ] Crear tablas VAULT_SECRETS, VAULT_ACCESS_LOG, VAULT_ENCRYPTION_KEYS
|
||||
- [ ] Configurar Master Key (variable de entorno o KMS)
|
||||
- [ ] Generar KEKs iniciales
|
||||
- [ ] Configurar backup automático
|
||||
|
||||
## Integración:
|
||||
- [ ] Implementar cliente Key Vault
|
||||
- [ ] Integrar con ContractBuilder
|
||||
- [ ] Implementar envelope encryption
|
||||
|
||||
## Seguridad:
|
||||
- [ ] Configurar políticas de acceso
|
||||
- [ ] Habilitar logging de accesos
|
||||
- [ ] Configurar alertas SENTINEL
|
||||
- [ ] Establecer rotación automática
|
||||
|
||||
---
|
||||
|
||||
**Fin del Documento 07c — Key Vault y Criptografía**
|
||||
|
||||
*Referencia: `S-CONTRACT.md` v1.2*
|
||||
Reference in New Issue
Block a user