Document governed file connector boundaries
This commit is contained in:
@@ -6,6 +6,9 @@ from govoplan_core.core.access import CAPABILITY_AUTH_PERMISSION_EVALUATOR, CAPA
|
|||||||
from govoplan_core.core.files import CAPABILITY_FILES_ACCESS
|
from govoplan_core.core.files import CAPABILITY_FILES_ACCESS
|
||||||
from govoplan_core.core.module_guards import drop_table_retirement_provider, persistent_table_uninstall_guard
|
from govoplan_core.core.module_guards import drop_table_retirement_provider, persistent_table_uninstall_guard
|
||||||
from govoplan_core.core.modules import (
|
from govoplan_core.core.modules import (
|
||||||
|
DocumentationCondition,
|
||||||
|
DocumentationLink,
|
||||||
|
DocumentationTopic,
|
||||||
FrontendModule,
|
FrontendModule,
|
||||||
MigrationSpec,
|
MigrationSpec,
|
||||||
ModuleContext,
|
ModuleContext,
|
||||||
@@ -138,6 +141,73 @@ manifest = ModuleManifest(
|
|||||||
package_name="@govoplan/files-webui",
|
package_name="@govoplan/files-webui",
|
||||||
nav_items=(NavItem(path="/files", label="Files", icon="folder", required_any=("files:file:read",), order=40),),
|
nav_items=(NavItem(path="/files", label="Files", icon="folder", required_any=("files:file:read",), order=40),),
|
||||||
),
|
),
|
||||||
|
documentation=(
|
||||||
|
DocumentationTopic(
|
||||||
|
id="files.governed-connectors-and-provenance",
|
||||||
|
title="Governed file connectors and source provenance",
|
||||||
|
summary="Connector profiles control who may browse an external source, which destinations are permitted, and how imported files retain verifiable source context.",
|
||||||
|
body=(
|
||||||
|
"Users select only connector profiles visible in their current scope and import remote content into managed Files storage before another module uses it. "
|
||||||
|
"Administrators define profiles, separate credential references, and ordered system/tenant/owner policies; deny rules win and profile responses never expose secrets. "
|
||||||
|
"Operators control private-network access deployment-wide and must keep every remote connection pinned to a policy-validated DNS/IP answer. "
|
||||||
|
"The built-in HTTP transport pins each connection and refuses redirects. Live S3 and SMB SDK access fails closed until S3 redirects and SMB DFS referrals can be revalidated and pinned. "
|
||||||
|
"Successful imports store the connector id, provider, remote path and identity, source revision, and selected metadata as provenance on the managed file and its audit events."
|
||||||
|
),
|
||||||
|
layer="configured",
|
||||||
|
documentation_types=("admin", "user"),
|
||||||
|
audience=("file_user", "file_admin", "tenant_admin", "operator"),
|
||||||
|
order=42,
|
||||||
|
conditions=(
|
||||||
|
DocumentationCondition(
|
||||||
|
required_modules=("files",),
|
||||||
|
any_scopes=(
|
||||||
|
"files:file:read",
|
||||||
|
"files:file:upload",
|
||||||
|
"files:file:admin",
|
||||||
|
"admin:settings:read",
|
||||||
|
"system:settings:read",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
links=(
|
||||||
|
DocumentationLink(label="Files", href="/files", kind="runtime"),
|
||||||
|
DocumentationLink(label="Tenant connector administration", href="/admin?section=tenant-file-connectors", kind="runtime"),
|
||||||
|
DocumentationLink(label="Connector profiles API", href="/api/v1/files/connectors/profiles", kind="api"),
|
||||||
|
DocumentationLink(label="Connector providers API", href="/api/v1/files/connectors/providers", kind="api"),
|
||||||
|
DocumentationLink(label="Tenant connector policy API", href="/api/v1/files/connectors/policies/tenant", kind="api"),
|
||||||
|
),
|
||||||
|
related_modules=("campaigns",),
|
||||||
|
unlocks=("Campaigns can consume managed attachments while Files preserves frozen source provenance.",),
|
||||||
|
configuration_keys=(
|
||||||
|
"GOVOPLAN_CONNECTOR_ALLOW_PRIVATE_NETWORKS",
|
||||||
|
"GOVOPLAN_FILES_CONNECTOR_PROFILES_JSON",
|
||||||
|
"GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE",
|
||||||
|
"GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST",
|
||||||
|
),
|
||||||
|
metadata={
|
||||||
|
"kind": "reference",
|
||||||
|
"perspectives": {
|
||||||
|
"user": "Choose a visible connection, browse it read-only, and import a selected file into managed storage before using it elsewhere.",
|
||||||
|
"admin": "Govern profile visibility, separate credential references, provider allow/deny policy, and permitted connector operations.",
|
||||||
|
"operator": "Control private-network access deployment-wide, provide credential and CA allowlists, and investigate fail-closed transport errors without weakening peer validation.",
|
||||||
|
},
|
||||||
|
"security_invariants": [
|
||||||
|
"Every network peer must be policy-validated and pinned at connection time.",
|
||||||
|
"Redirects and protocol referrals must be rejected or independently revalidated and pinned.",
|
||||||
|
"SDK transports that cannot provide those guarantees fail before client construction.",
|
||||||
|
],
|
||||||
|
"provenance_fields": [
|
||||||
|
"connector_id",
|
||||||
|
"provider",
|
||||||
|
"external_id",
|
||||||
|
"external_path",
|
||||||
|
"revision",
|
||||||
|
"metadata",
|
||||||
|
],
|
||||||
|
"related_topic_ids": ["mail.profiles-and-policy"],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
migration_spec=MigrationSpec(
|
migration_spec=MigrationSpec(
|
||||||
module_id="files",
|
module_id="files",
|
||||||
metadata=Base.metadata,
|
metadata=Base.metadata,
|
||||||
|
|||||||
21
tests/test_manifest_documentation.py
Normal file
21
tests/test_manifest_documentation.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class FilesManifestDocumentationTests(unittest.TestCase):
|
||||||
|
def test_connector_topic_covers_governance_pinning_and_provenance_perspectives(self) -> None:
|
||||||
|
from govoplan_files.backend.manifest import manifest
|
||||||
|
|
||||||
|
topic = next(item for item in manifest.documentation if item.id == "files.governed-connectors-and-provenance")
|
||||||
|
|
||||||
|
self.assertEqual(("admin", "user"), topic.documentation_types)
|
||||||
|
self.assertEqual({"user", "admin", "operator"}, set(topic.metadata["perspectives"]))
|
||||||
|
self.assertIn("fails closed", topic.body)
|
||||||
|
self.assertIn("DFS referrals", topic.body)
|
||||||
|
self.assertIn("revision", topic.metadata["provenance_fields"])
|
||||||
|
self.assertIn("/api/v1/files/connectors/profiles", {link.href for link in topic.links})
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user