Files
Unraid-AppOps-Gateway-Public/backend/app/services/repopulse_target_credential.py
T

97 lines
3.4 KiB
Python

"""One durable credential for the fixed RepoPulse legacy adoption target."""
from __future__ import annotations
import hashlib
import re
import secrets
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
from sqlalchemy.exc import SQLAlchemyError
from sqlmodel import Session
from ..core.time import utc_now
from ..db.models import Secret
from . import secret_store
_INTENT_ID = re.compile(r"^rpa-[0-9a-f]{20}$")
_REF = "ENROLL_REPOPULSE_TARGET_HMAC"
class RepoPulseTargetCredentialError(RuntimeError):
"""A sanitized fixed-target credential error."""
def get_or_create_repopulse_target_credential(
session: Session, *, intent_id: str
) -> tuple[str, bytes]:
"""Insert once, then reuse the encrypted credential on every retry.
The caller must have durably reserved the same adoption intent before this
method is called. The plaintext is returned only to the in-process private
TLS client and must never be added to a receipt, response, or log.
"""
if not isinstance(intent_id, str) or _INTENT_ID.fullmatch(intent_id) is None:
raise RepoPulseTargetCredentialError("adoption_intent_invalid")
if secret_store.secret_storage_status().get("productionReady") is not True:
raise RepoPulseTargetCredentialError("secret_store_not_ready")
enrollment_id = f"enr-{intent_id.removeprefix('rpa-')}"
candidate = secrets.token_urlsafe(48)
metadata = {
"intentId": intent_id,
"enrollmentId": enrollment_id,
"rotationState": "active",
"credentialFingerprint": hashlib.sha256(candidate.encode("ascii")).hexdigest()[
:16
],
}
now = utc_now()
try:
session.execute(
sqlite_insert(Secret)
.values(
id=_REF,
name=_REF,
encrypted_value=secret_store._fernet()
.encrypt(candidate.encode("ascii"))
.decode("ascii"),
created_at=now,
updated_at=now,
used_by_json=[f"enrollment:{enrollment_id}", "deployment-controller"],
metadata_json=metadata,
)
.on_conflict_do_nothing(index_elements=[Secret.id])
)
session.commit()
row = session.get(Secret, _REF, populate_existing=True)
if (
row is None
or row.name != _REF
or not isinstance(row.metadata_json, dict)
or row.metadata_json.get("intentId") != intent_id
or row.metadata_json.get("enrollmentId") != enrollment_id
):
raise RepoPulseTargetCredentialError("target_credential_collision")
value = secret_store.get_secret(session, _REF, touch=False)
if (
not value
or not 32 <= len(value) <= 256
or not value.isascii()
or not value.isprintable()
):
raise RepoPulseTargetCredentialError("target_credential_unavailable")
if (
row.metadata_json.get("credentialFingerprint")
!= hashlib.sha256(value.encode("utf-8")).hexdigest()[:16]
):
raise RepoPulseTargetCredentialError(
"target_credential_fingerprint_mismatch"
)
return enrollment_id, value.encode("utf-8")
except SQLAlchemyError:
session.rollback()
raise RepoPulseTargetCredentialError(
"target_credential_storage_unavailable"
) from None