feat(cloud-auth): bind host principals
This commit is contained in:
@@ -17,10 +17,31 @@ PLUGINS_ADMIN_SCOPE = "plugins:admin"
|
||||
class Principal:
|
||||
id: str = "anonymous"
|
||||
scopes: frozenset[str] = field(default_factory=frozenset)
|
||||
host_id: str | None = None
|
||||
|
||||
def has_scope(self, scope: str) -> bool:
|
||||
return "*" in self.scopes or scope in self.scopes
|
||||
|
||||
def require_host(self, requested_host_id: str) -> None:
|
||||
if self.host_id is None:
|
||||
raise HostPrincipalRequiredError("a host-bound principal is required")
|
||||
if self.host_id != requested_host_id:
|
||||
raise HostIdentityMismatchError(
|
||||
"authenticated host cannot act for the requested host"
|
||||
)
|
||||
|
||||
|
||||
class HostAuthorizationError(PermissionError):
|
||||
pass
|
||||
|
||||
|
||||
class HostPrincipalRequiredError(HostAuthorizationError):
|
||||
pass
|
||||
|
||||
|
||||
class HostIdentityMismatchError(HostAuthorizationError):
|
||||
pass
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class AuthProvider(Protocol):
|
||||
@@ -39,12 +60,15 @@ class BearerCredential:
|
||||
principal_id: str
|
||||
token: str = field(repr=False)
|
||||
scopes: frozenset[str] = field(default_factory=frozenset)
|
||||
host_id: str | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not self.principal_id.strip():
|
||||
raise ValueError("bearer credential principal_id must not be empty")
|
||||
if not self.token:
|
||||
raise ValueError("bearer credential token must not be empty")
|
||||
if self.host_id is not None and not self.host_id.strip():
|
||||
raise ValueError("bearer credential host_id must not be empty")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -62,6 +86,7 @@ class ConfiguredBearerAuthProvider:
|
||||
principal=Principal(
|
||||
id=credential.principal_id,
|
||||
scopes=frozenset(credential.scopes),
|
||||
host_id=credential.host_id,
|
||||
),
|
||||
token_digest=_token_digest(credential.token),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user