Complete service-account credential administration

This commit is contained in:
2026-08-04 01:04:39 +02:00
parent 1409dbf94d
commit 998d47ae94
15 changed files with 1672 additions and 17 deletions
@@ -525,6 +525,18 @@ def _resolve_api_key_principal_context(
or user.tenant_id != api_key.tenant_id
):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive or inconsistent API-key principal")
if (
account.auth_provider == "service_account"
or user.auth_provider == "service_account"
):
return _resolve_service_account_credential_context(
session,
api_key=api_key,
account=account,
user=user,
tenant=tenant,
activity_touch_pending=activity_touch_pending,
)
idm_assignments, idm_roles = _principal_idm_context(
session,
user=user,
@@ -560,6 +572,61 @@ def _resolve_api_key_principal_context(
return ResolvedPrincipalContext(principal=principal, account=account, user=user, tenant=tenant, api_key=api_key)
def _resolve_service_account_credential_context(
session: Session,
*,
api_key: ApiKey,
account: Account,
user: User,
tenant: Tenant,
activity_touch_pending: bool,
) -> ResolvedPrincipalContext:
item = (
session.query(ServiceAccount)
.filter(
ServiceAccount.tenant_id == tenant.id,
ServiceAccount.account_id == account.id,
ServiceAccount.membership_id == user.id,
)
.one_or_none()
)
if (
item is None
or account.auth_provider != "service_account"
or user.auth_provider != "service_account"
or not item.is_active
or item.retired_at is not None
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Inactive or inconsistent service-account credential",
)
effective_scopes = intersect_api_key_scopes(
item.scope_ceiling,
api_key.scopes or [],
)
principal = PrincipalRef(
account_id=account.id,
membership_id=user.id,
tenant_id=tenant.id,
scopes=frozenset(effective_scopes),
auth_method="service_account",
api_key_id=api_key.id,
service_account_id=item.id,
email=None,
display_name=item.name,
)
if activity_touch_pending:
session.commit()
return ResolvedPrincipalContext(
principal=principal,
account=account,
user=user,
tenant=tenant,
api_key=api_key,
)
def _resolve_session_principal_ref(
request: Request,
session: Session,