feat: harden file sharing and integrity
This commit is contained in:
@@ -34,6 +34,8 @@ register_files_change_tracking()
|
||||
|
||||
_files_table_retirement_provider = drop_table_retirement_provider(
|
||||
file_models.FileBlob,
|
||||
file_models.FileIntegrityScan,
|
||||
file_models.FileIntegrityFinding,
|
||||
file_models.FileFolder,
|
||||
file_models.FileAsset,
|
||||
file_models.FileVersion,
|
||||
@@ -100,7 +102,7 @@ PERMISSIONS = (
|
||||
_permission("files:file:download", "Download files", "Download managed files and generated archives."),
|
||||
_permission("files:file:upload", "Upload files", "Upload new managed file versions."),
|
||||
_permission("files:file:organize", "Organize files", "Create folders, rename, move or copy managed files."),
|
||||
_permission("files:file:share", "Share files", "Grant or update managed file shares; revocation is not available yet."),
|
||||
_permission("files:file:share", "Share files", "List, grant, update, expire, and revoke managed file shares."),
|
||||
_permission("files:file:delete", "Delete files", "Delete or hide managed files and folders where policy allows it."),
|
||||
_permission("files:file:admin", "Administer file spaces", "Administer all file spaces in the tenant."),
|
||||
)
|
||||
@@ -344,11 +346,11 @@ manifest = ModuleManifest(
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="files.workflow.share-managed-files",
|
||||
title="Grant or update access to managed files",
|
||||
summary="Grant or update read, write, or manage access through a supporting workflow or API client without changing ownership.",
|
||||
title="Manage access to managed files",
|
||||
summary="List, grant, update, expire, or revoke direct read, write, and manage access without changing ownership.",
|
||||
body=(
|
||||
"The Files service can grant or update a share for a user, group, tenant, or campaign. The Files page does not yet provide a general share editor, and the API has no share-revocation route. "
|
||||
"Do not use this task when access must later be revoked until that explicit capability is implemented."
|
||||
"File owners and file administrators can manage direct shares for users, groups, the tenant, and Campaign. Expired and revoked grants stop authorizing access immediately while independent active grants remain effective. "
|
||||
"The Files share dialog lists active and historical grants, and revocation is idempotent."
|
||||
),
|
||||
layer="available",
|
||||
documentation_types=("user",),
|
||||
@@ -362,7 +364,7 @@ manifest = ModuleManifest(
|
||||
),
|
||||
links=(
|
||||
DocumentationLink(label="Files", href="/files", kind="runtime"),
|
||||
DocumentationLink(label="Grant or update a share", href="/api/v1/files/{file_id}/shares", kind="api"),
|
||||
DocumentationLink(label="List and manage shares", href="/api/v1/files/{file_id}/shares", kind="api"),
|
||||
DocumentationLink(label="Files handbook", href="govoplan-files/docs/FILES_HANDBOOK.md", kind="repository"),
|
||||
),
|
||||
related_modules=("campaigns",),
|
||||
@@ -373,22 +375,21 @@ manifest = ModuleManifest(
|
||||
"screen": "Files",
|
||||
"help_contexts": ["files.list"],
|
||||
"prerequisites": [
|
||||
"You may view and share the managed file and have write/manage access to that specific asset; the global share permission alone does not grant resource access.",
|
||||
"A supporting workflow or API client is available; the Files page has no general share editor yet.",
|
||||
"The process does not require share revocation, because no revocation route exists yet.",
|
||||
"You have the Files share permission and own the file, or administer file spaces for the active tenant.",
|
||||
"The intended user, group, tenant, or Campaign target exists and is active.",
|
||||
],
|
||||
"steps": [
|
||||
"Open Files and verify the file owner, logical path, current version, and checksum.",
|
||||
"Through the supporting workflow, identify the intended user, group, tenant, or campaign and choose read, write, or manage access.",
|
||||
"Select one managed file, choose Manage shares, and review the effective and historical direct grants.",
|
||||
"Select the intended user, group, or tenant and choose read, write, or manage access plus an optional expiry.",
|
||||
"Grant or update the share without changing file ownership.",
|
||||
"Have the intended recipient verify access and an unrelated account verify denial.",
|
||||
"Revoke a grant when it is no longer needed; repeated revocation is a no-op.",
|
||||
],
|
||||
"limitations": [
|
||||
"The Files page has no general share editor.",
|
||||
"Shares can be granted or updated, but not revoked through the current API.",
|
||||
"Campaign-target grants are normally created by the Campaign integration rather than selected manually in the Files dialog.",
|
||||
"A user may retain access through another active direct grant or ownership path after one share is revoked.",
|
||||
],
|
||||
"outcome": "The requested access is granted or updated while the managed asset keeps its owner.",
|
||||
"verification": "Test one intended and one denied access path. Do not claim that the share can later be revoked.",
|
||||
"outcome": "Direct access has the requested permission and lifetime while the managed asset keeps its owner.",
|
||||
"verification": "Test one intended and one denied path, then expire or revoke the grant and verify that only independent access paths remain.",
|
||||
"related_topic_ids": [
|
||||
"files.workflow.find-and-download-files",
|
||||
"files.assurance.process-and-release-readiness",
|
||||
@@ -507,7 +508,7 @@ manifest = ModuleManifest(
|
||||
title="Operate Files integrity, recovery, and connector transport safety",
|
||||
summary="Back up database evidence, blob bytes, and the encryption key as one recovery unit, and keep unsupported SDK transports fail-closed.",
|
||||
body=(
|
||||
"Local durable storage is the operational baseline. Recover Files from a coordinated database/blob snapshot with the original master key, then verify representative checksums and access paths. "
|
||||
"Local durable storage is the operational baseline. Recover Files from a coordinated database/blob snapshot with the original master key, then run the bounded resumable integrity scan and verify representative access paths. Missing or mismatched blobs are quarantined; orphan objects are reported before dry-run-first, explicitly authorized cleanup. "
|
||||
"Live S3 managed storage/connectors and SMB connectors fail closed until botocore redirects/endpoint discovery and SMB initial connections/DFS referrals support connection-time DNS/IP pinning. Destructive module retirement drops database tables but does not remove backend blob objects."
|
||||
),
|
||||
layer="configured",
|
||||
@@ -528,6 +529,7 @@ manifest = ModuleManifest(
|
||||
links=(
|
||||
DocumentationLink(label="System file connections", href="/admin?section=system-file-connectors", kind="runtime"),
|
||||
DocumentationLink(label="Connector provider status", href="/api/v1/files/connectors/providers", kind="api"),
|
||||
DocumentationLink(label="Create an integrity scan", href="/api/v1/files/integrity/scans", kind="api"),
|
||||
DocumentationLink(label="Files handbook", href="govoplan-files/docs/FILES_HANDBOOK.md", kind="repository"),
|
||||
),
|
||||
related_modules=("audit", "ops"),
|
||||
@@ -549,7 +551,7 @@ manifest = ModuleManifest(
|
||||
"screen": "System file connections and deployment operations",
|
||||
"section": "Storage integrity, backup/recovery, and fail-closed transports",
|
||||
"recovery_unit": ["Files database rows", "managed blob namespace", "MASTER_KEY_B64", "deployment-owned connector configuration"],
|
||||
"verification": "After restore, download representative files, compare their bytes with recorded SHA-256 values, verify authorized and denied access, and test one permitted pinned HTTP connector.",
|
||||
"verification": "After restore, complete a checksum-enabled integrity scan, resolve every missing/corrupt finding, approve or retain every reported orphan, verify authorized and denied access, and test one permitted pinned HTTP connector.",
|
||||
"related_topic_ids": [
|
||||
"files.governed-connectors-and-provenance",
|
||||
"files.reference.snapshot-provenance-and-capabilities",
|
||||
@@ -601,7 +603,7 @@ manifest = ModuleManifest(
|
||||
summary="Check a process against the implemented Files boundary, exercise permitted and denied paths, and retain evidence before approving a release or operational use.",
|
||||
body=(
|
||||
"A process owner must distinguish implemented controls from planned capabilities before relying on Files. A release is not ready until all package and manifest versions align and representative authorization, upload limits, conflict handling, download, deletion, connector, and recovery paths have been exercised. "
|
||||
"Current limitations include no general share-management UI or share revocation, no self-service restore or hard purge, no enforced retention or legal hold, and no dedicated canonical audit event for every ordinary Files mutation. Record these limitations in the process assessment instead of treating soft deletion or change-sequence entries as stronger evidence."
|
||||
"Current limitations include no self-service restore or hard purge, no enforced retention or legal hold, and no dedicated canonical audit event for every ordinary Files mutation. Share grant, change, expiry, and revocation operations do emit dedicated audit records. Record remaining limitations in the process assessment instead of treating soft deletion or change-sequence entries as stronger evidence."
|
||||
),
|
||||
layer="configured",
|
||||
documentation_types=("admin", "user"),
|
||||
|
||||
Reference in New Issue
Block a user