Files
beaver_project/app-instance/backend/docs/security/user-filesystem-minio-authz.md
2026-06-03 12:06:34 +08:00

4.1 KiB

User File System MinIO/AuthZ Setup

The user file system is exposed through Beaver APIs and user_files_* tools. MinIO remains an implementation detail.

The ordinary Files page should only call Beaver's /api/user-files/* routes and render the virtual roots uploads/, outputs/, shared/, and tasks/. It should not show bucket names, endpoint fields, access keys, secret keys, object prefixes, or MinIO administration actions.

AuthZ Settings

Each backend identity can store MinIO settings in AuthZ:

curl -X POST "$AUTHZ_URL/backends/$BACKEND_ID/settings/minio" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTHZ_ADMIN_TOKEN" \
  -d '{
    "endpoint": "minio.example.internal:9000",
    "access_key": "user-access-key",
    "secret_key": "user-secret-key",
    "bucket": "beaver-user-files",
    "namespace": "users/{backend_id}",
    "secure": false,
    "region": null
  }'

Public reads return masked settings. Internal reads require AUTHZ_INTERNAL_TOKEN and return the secret key for protected MCP services.

Deployed personal files use a shared bucket with a backend-scoped namespace. For backend alice, Beaver maps:

  • uploads/report.pdf to users/alice/uploads/report.pdf
  • outputs/summary.md to users/alice/outputs/summary.md
  • tasks/task-123/result.json to users/alice/tasks/task-123/result.json

The MinIO policy for Alice's access key must be limited to beaver-user-files/users/alice/*. The frontend must still only show Beaver virtual paths, not the shared bucket or namespace.

Check the public, masked view:

curl "$AUTHZ_URL/backends/$BACKEND_ID/settings/minio" \
  -H "Authorization: Bearer $AUTHZ_ADMIN_TOKEN"

Check the internal protected view used by MCP services:

curl "$AUTHZ_URL/internal/backends/$BACKEND_ID/settings/minio" \
  -H "Authorization: Bearer $AUTHZ_INTERNAL_TOKEN"

Protected MinIO MCP

Run the MinIO MCP service in protected mode:

bw-minio-mcp serve \
  --host 0.0.0.0 \
  --port 8001 \
  --authz-url "$AUTHZ_URL" \
  --authz-token "$AUTHZ_INTERNAL_TOKEN" \
  --resource-server-url "$MINIO_MCP_PUBLIC_URL/mcp" \
  --state-root /var/lib/bw-minio-mcp

In protected mode, the MCP service does not use static MinIO credentials at startup. Each authenticated tool call resolves the backend identity from the bearer token, loads that backend's MinIO settings from AuthZ, and constructs a per-call provider.

Outside protected mode, bw-minio-mcp serve requires explicit --endpoint, --access-key, and --secret-key values. It intentionally has no embedded production fallback credentials.

Beaver Runtime

Beaver should register the MinIO MCP endpoint with backend-token auth when raw object tools are needed:

{
  "tools": {
    "mcpServers": {
      "minio_mcp": {
        "url": "https://minio-mcp.example.internal/mcp",
        "auth": "oauth_backend_token",
        "authAudience": "mcp:minio_mcp"
      }
    }
  },
  "authz": {
    "baseUrl": "https://authz.example.internal",
    "backendId": "backend-user-id"
  }
}

Product-level file interactions should still go through Beaver's user file system:

  • Frontend: /api/user-files/status, /api/user-files/browse, /api/user-files/upload, /api/user-files/preview, /api/user-files/download, /api/user-files/delete, and /api/user-files/mkdir.
  • Agent tools: user_files_list, user_files_read, user_files_write, user_files_delete, and user_files_mkdir.
  • Storage boundary: only uploads/, outputs/, shared/, and tasks/ are valid user paths.

The local workspace browser APIs and generic filesystem tools are retained for runtime/development compatibility, but they are not the user-visible file boundary.

Verification Checklist

  • The Files page root renders exactly uploads, outputs, shared, and tasks.
  • The Files page source does not call /api/workspace/browse.
  • /api/user-files/status does not return local workspace paths or MinIO bucket details.
  • AuthZ public settings responses mask secret_key.
  • Protected BW_MinIO_Mcp returns a clear configuration error if a backend has no MinIO settings instead of falling back to another user's credentials.