Provide first system administrator authority
This commit is contained in:
@@ -9,6 +9,7 @@ from govoplan_core.core.access import (
|
||||
CAPABILITY_ACCESS_ADMINISTRATION,
|
||||
CAPABILITY_ACCESS_DIRECTORY,
|
||||
CAPABILITY_ACCESS_EXPLANATION,
|
||||
CAPABILITY_ACCESS_FIRST_ADMIN_PROVISIONER,
|
||||
CAPABILITY_ACCESS_GOVERNANCE_MATERIALIZER,
|
||||
CAPABILITY_ACCESS_PERMISSION_EVALUATOR,
|
||||
CAPABILITY_ACCESS_PRINCIPAL_RESOLVER,
|
||||
@@ -269,6 +270,39 @@ ADMIN_READ_SCOPES = (
|
||||
)
|
||||
|
||||
ACCESS_DOCUMENTATION: tuple[DocumentationTopic, ...] = (
|
||||
DocumentationTopic(
|
||||
id="access.operator.enroll-first-administrator",
|
||||
title="Enroll the first production administrator",
|
||||
summary="A local operator can issue one expiring credential while no durable system administrator exists, then use it once to create the protected system owner and an initial tenant membership.",
|
||||
body=(
|
||||
"Run the Core first-admin issue command after migrations and after Access is installed. The command stores the random secret in a local mode-0600 artifact and prints only its path, fingerprint, and expiry. "
|
||||
"The public bootstrap status endpoint exposes only minimum readiness. The enrollment endpoint accepts only the first account and initial tenant fields, creates one protected system owner plus one tenant-owner membership atomically, and retires the credential. "
|
||||
"Identical retries return the completed account without creating another owner. Lost or expired material can be rotated only by the local recovery command and only while the durable-administrator check remains empty. Development bootstrap settings are a separate dev-only path and are never enabled by enrollment."
|
||||
),
|
||||
layer="always",
|
||||
documentation_types=("admin",),
|
||||
audience=("operator", "system_admin"),
|
||||
order=10,
|
||||
links=(
|
||||
DocumentationLink(label="Bootstrap readiness API", href="/api/v1/bootstrap/status", kind="api"),
|
||||
DocumentationLink(label="First-administrator enrollment API", href="/api/v1/bootstrap/first-admin", kind="api"),
|
||||
),
|
||||
metadata={
|
||||
"kind": "operator_workflow",
|
||||
"commands": [
|
||||
"python -m govoplan_core.commands.first_admin status",
|
||||
"python -m govoplan_core.commands.first_admin issue --reason 'initial production installation'",
|
||||
"python -m govoplan_core.commands.first_admin recover --reason 'lost or expired handoff'",
|
||||
],
|
||||
"security_properties": [
|
||||
"random expiring credential",
|
||||
"mode-0600 local artifact",
|
||||
"single-use idempotent enrollment",
|
||||
"empty-install authority gate",
|
||||
"hash-chained and audit evidence",
|
||||
],
|
||||
},
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="access.workflow.grant-user-access",
|
||||
title="Grant a person access",
|
||||
@@ -670,6 +704,13 @@ def _tenant_provisioner(context: ModuleContext) -> object:
|
||||
return LegacyTenantAccessProvisioner()
|
||||
|
||||
|
||||
def _first_admin_provisioner(context: ModuleContext) -> object:
|
||||
del context
|
||||
from govoplan_access.backend.tenancy.provisioning import LegacyFirstAdminProvisioner
|
||||
|
||||
return LegacyFirstAdminProvisioner()
|
||||
|
||||
|
||||
def _access_administration(context: ModuleContext) -> object:
|
||||
del context
|
||||
from govoplan_access.backend.administration import SqlAccessAdministration
|
||||
@@ -801,6 +842,7 @@ manifest = ModuleManifest(
|
||||
CAPABILITY_ACCESS_SEMANTIC_DIRECTORY: _access_semantic_directory,
|
||||
CAPABILITY_ACCESS_EXPLANATION: _access_explanation_service,
|
||||
CAPABILITY_ACCESS_TENANT_PROVISIONER: _tenant_provisioner,
|
||||
CAPABILITY_ACCESS_FIRST_ADMIN_PROVISIONER: _first_admin_provisioner,
|
||||
CAPABILITY_ACCESS_ADMINISTRATION: _access_administration,
|
||||
CAPABILITY_ACCESS_GOVERNANCE_MATERIALIZER: _governance_materializer,
|
||||
CAPABILITY_ACCESS_PEOPLE_SEARCH: _people_search,
|
||||
|
||||
Reference in New Issue
Block a user