Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""Vault Transit encryption/decryption helpers."""
|
|
|
|
import base64
|
|
|
|
import hvac
|
|
import structlog
|
|
|
|
logger = structlog.get_logger()
|
|
|
|
|
|
class VaultTransitHelper:
|
|
"""Helper for Vault Transit encryption/decryption"""
|
|
|
|
def __init__(self, vault_client: hvac.Client, mount_point: str = "transit"):
|
|
self.vault_client = vault_client
|
|
self.mount_point = mount_point
|
|
|
|
def encrypt_field(self, key_name: str, plaintext: str) -> str:
|
|
"""Encrypt a field using Vault Transit"""
|
|
try:
|
|
# Ensure key exists
|
|
self._ensure_key_exists(key_name)
|
|
|
|
# Encrypt the data
|
|
response = self.vault_client.secrets.transit.encrypt_data(
|
|
mount_point=self.mount_point,
|
|
name=key_name,
|
|
plaintext=base64.b64encode(plaintext.encode()).decode(),
|
|
)
|
|
return str(response["data"]["ciphertext"])
|
|
except Exception as e:
|
|
logger.error("Failed to encrypt field", key_name=key_name, error=str(e))
|
|
raise
|
|
|
|
def decrypt_field(self, key_name: str, ciphertext: str) -> str:
|
|
"""Decrypt a field using Vault Transit"""
|
|
try:
|
|
response = self.vault_client.secrets.transit.decrypt_data(
|
|
mount_point=self.mount_point, name=key_name, ciphertext=ciphertext
|
|
)
|
|
return base64.b64decode(response["data"]["plaintext"]).decode()
|
|
except Exception as e:
|
|
logger.error("Failed to decrypt field", key_name=key_name, error=str(e))
|
|
raise
|
|
|
|
def _ensure_key_exists(self, key_name: str) -> None:
|
|
"""Ensure encryption key exists in Vault"""
|
|
try:
|
|
self.vault_client.secrets.transit.read_key(
|
|
mount_point=self.mount_point, name=key_name
|
|
)
|
|
# pylint: disable-next=broad-exception-caught
|
|
except Exception: # hvac.exceptions.InvalidPath
|
|
# Key doesn't exist, create it
|
|
self.vault_client.secrets.transit.create_key(
|
|
mount_point=self.mount_point, name=key_name, key_type="aes256-gcm96"
|
|
)
|
|
logger.info("Created new encryption key", key_name=key_name)
|