feat: add secure agent enrollment
This commit is contained in:
1 parent
82309db79a
commit
d9f0da694b
26 files changed
+2942
-76
No files matched your search
@@ -1,37 +1,46 @@
|
||||
"""Dependencies for the authenticated Agent queue protocol."""
|
||||
|
||||
import hmac
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import Header, HTTPException
|
||||
from fastapi import Depends, Header, HTTPException
|
||||
|
||||
from app.agent_auth.exceptions import (
|
||||
AgentAuthenticationFailed,
|
||||
AgentAuthenticationUnavailable,
|
||||
AgentCredentialRevoked,
|
||||
AgentIdentityUnauthorized,
|
||||
)
|
||||
from app.agent_auth.repository import AgentAuthRepository
|
||||
from app.agent_auth.service import AgentAuthService
|
||||
from app.agent_commands.repository import AgentCommandRepository
|
||||
from app.agent_commands.service import AgentCommandService
|
||||
from app.config import settings
|
||||
|
||||
|
||||
def get_agent_command_service() -> AgentCommandService:
|
||||
return AgentCommandService(AgentCommandRepository())
|
||||
|
||||
|
||||
def get_agent_auth_service() -> AgentAuthService:
|
||||
return AgentAuthService(AgentAuthRepository())
|
||||
|
||||
|
||||
def require_agent_identity(
|
||||
agent_id: Annotated[str | None, Header(alias="X-MinerOps-Agent-ID")] = None,
|
||||
provided_secret: Annotated[
|
||||
str | None, Header(alias="X-MinerOps-Agent-Secret")
|
||||
] = None,
|
||||
service: AgentAuthService = Depends(get_agent_auth_service),
|
||||
) -> str:
|
||||
expected_id = settings.minerops_agent_id.strip()
|
||||
expected_secret = settings.minerops_agent_shared_secret.strip()
|
||||
if not expected_id or not expected_secret:
|
||||
raise HTTPException(status_code=503, detail="Agent authentication is not configured")
|
||||
|
||||
secret = (provided_secret or "").strip()
|
||||
if not secret or not hmac.compare_digest(secret, expected_secret):
|
||||
raise HTTPException(status_code=401, detail="Invalid or missing Agent secret")
|
||||
|
||||
identity = (agent_id or "").strip()
|
||||
if not identity:
|
||||
raise HTTPException(status_code=401, detail="Missing Agent identity")
|
||||
if not hmac.compare_digest(identity, expected_id):
|
||||
raise HTTPException(status_code=403, detail="Agent identity is not authorized")
|
||||
return identity
|
||||
try:
|
||||
return service.authenticate(agent_id, provided_secret)
|
||||
except AgentAuthenticationUnavailable as exc:
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Agent authentication is not configured",
|
||||
) from exc
|
||||
except AgentAuthenticationFailed as exc:
|
||||
raise HTTPException(status_code=401, detail=str(exc)) from exc
|
||||
except AgentCredentialRevoked as exc:
|
||||
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
||||
except AgentIdentityUnauthorized as exc:
|
||||
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
||||
Reference in new issue
Block a user