Skip to content

[full-ci] feat: ocisdev-533 graph#12108

Open
2403905 wants to merge 12 commits intomasterfrom
feat/OCISDEV-533-graph
Open

[full-ci] feat: ocisdev-533 graph#12108
2403905 wants to merge 12 commits intomasterfrom
feat/OCISDEV-533-graph

Conversation

@2403905
Copy link
Copy Markdown
Contributor

@2403905 2403905 commented Mar 12, 2026

Description

Provide the separated vault storage that could be MFA-protected

Implementation approach:

Provide the dedicated storage-users and graph service to care only about vault storage.

  • Provide the new vault user storage with a dedicated VaultStorageProviderID mounted to "/vault/users" and "/vault/projects".
  • Teach the storage registry to associate the vault storage with the dedicated storage-users service.
  • Modify the graph service to force using StorageProviderID in a vault-mode. Run in addition the graph API serves the /vault prefix.
  • Run the dedicated storage-users service pointed to the vault.

Related reva PR owncloud/reva#559

How to run in a Docker

UPD: 13.04.2026

  • build the dev docker image
  • goto ./deployments/examples/ocis_full
  • in a .env uncomment the line KEYCLOAK=:keycloak.yml and VAULT_STORAGE=:vault-storage.yml
  • run the docker compose IDM_ADMIN_PASSWORD=admin DEMO_USERS=true OCIS_DOCKER_TAG=dev OCIS_MFA_ENABLED=true docker compose up -d

How to run locally

UPD: 18.03.2026 - No extra graph service needed
ocis main

WEB_ASSET_CORE_PATH=/Users/roman/projects/owncloud-extra/web/dist \
OCIS_MFA_ENABLED=true \
PROXY_CREATE_VAULT_HOME=true \
GRAPH_ENABLE_VAULT_MODE=true \
IDM_ADMIN_PASSWORD=admin IDM_CREATE_DEMO_USERS=true PROXY_ENABLE_BASIC_AUTH=true OCIS_LOG_LEVEL=info ./ocis/bin/ocis server

In a Keycloak setup set to trueOCIS_MFA_ENABLED
WEB_ASSET_CORE_PATH={path to web}/web/dist \

Vault storage-users

OCIS_LOG_LEVEL=debug \
STORAGE_USERS_ENABLE_VAULT_MODE=true \
STORAGE_USERS_SERVICE_NAME=storage-users-vault \
STORAGE_USERS_GRPC_ADDR=0.0.0.0:9170 \
STORAGE_USERS_HTTP_ADDR=0.0.0.0:9168 \
STORAGE_USERS_DATA_SERVER_URL=http://localhost:9168/data \
STORAGE_USERS_DEBUG_ADDR=0.0.0.0:9169 \
STORAGE_USERS_OCIS_ROOT=${HOME}/.ocis/storage/users-vault \
STORAGE_USERS_EVENTS_CONSUMER_GROUP=vault-dcfs \
./ocis/bin/ocis storage-users server
curl 'https://localhost:9200/vault/graph/v1beta1/drives' \
-H 'Accept: application/json' \
--data-raw '{"name":"vault Space"}' \
--insecure  -uadmin:admin

curl 'https://localhost:9200/vault/graph/v1beta1/me/drives?%24orderby=name+asc&%24filter=driveType+eq+project' \
-H 'Accept: application/json' \
--insecure  -uadmin:admin

curl 'https://localhost:9200/vault/graph/v1beta1/me/drives?%24orderby=name+asc&%24filter=driveType+eq+personal' \
-H 'Accept: application/json' \
--insecure  -uadmin:admin

FS:

~/.ocis/storage
$ tree  users*
users
├── indexes
│   ├── by-group-id
│   ├── by-type
│   │   └── personal.mpk
│   └── by-user-id
│       └── a032f2bd-fa5c-430b-a163-2c19f54190d0.mpk
├── spaces
│   └── a0
│       └── 32f2bd-fa5c-430b-a163-2c19f54190d0
│           └── nodes
│               └── a0
│                   └── 32
│                       └── f2
│                           └── bd
│                               ├── -fa5c-430b-a163-2c19f54190d0
│                               ├── -fa5c-430b-a163-2c19f54190d0.mlock
│                               └── -fa5c-430b-a163-2c19f54190d0.mpk
└── uploads
users-vault
├── indexes
│   ├── by-group-id
│   ├── by-type
│   │   └── personal.mpk
│   └── by-user-id
│       └── a032f2bd-fa5c-430b-a163-2c19f54190d0.mpk
├── spaces
│   └── a0
│       └── 32f2bd-fa5c-430b-a163-2c19f54190d0
│           └── nodes
│               └── a0
│                   └── 32
│                       └── f2
│                           └── bd
│                               ├── -fa5c-430b-a163-2c19f54190d0
│                               ├── -fa5c-430b-a163-2c19f54190d0.mlock
│                               └── -fa5c-430b-a163-2c19f54190d0.mpk
└── uploads

@update-docs
Copy link
Copy Markdown

update-docs Bot commented Mar 12, 2026

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@2403905 2403905 requested review from jvillafanez and kobergj March 12, 2026 11:15
@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch from 96ce268 to c79f474 Compare March 12, 2026 11:31
Comment thread services/graph/pkg/config/config.go Outdated
@jvillafanez
Copy link
Copy Markdown
Member

There are a couple of things that seems weird to me:

  • I understand that we can setup a storage-user service in "vault mode" so it's only accessible / usable with MFA, but why graph?
    • The graph service can just check if the request is under MFA to do anything with the vault.
  • Using mount ids in the configuration isn't user-friendly. If possible, I'd drop them, otherwise they MUST be documented, including where such id can be found and / or provide a command to get the id.
    • Note that it's easy to make typos and setup a mount id that doesn't exist. And people makes mistakes and might use any random id found anywhere, so it might point to who-knows-what.

@2403905
Copy link
Copy Markdown
Contributor Author

2403905 commented Mar 12, 2026

There are a couple of things that seems weird to me:

  • I understand that we can setup a storage-user service in "vault mode" so it's only accessible / usable with MFA, but why graph?

Maybe we can improve it and use only one graph. Now I use the second one for enforcing the vault storage and MFA for all graph endpoints

  • Note that it's easy to make typos and setup a mount id that doesn't exist. And people makes mistakes and might use any random id found anywhere, so it might point to who-knows-what.

Ideally, we could try to add one more storageprovider in a config and get rid of the dedicated storage-users service.

"services": map[string]interface{}{
"storageprovider": map[string]interface{}{
"driver": cfg.Driver,
"drivers": StorageProviderDrivers(cfg),
"mount_id": cfg.MountID,
"expose_data_server": cfg.ExposeDataServer,
"data_server_url": cfg.DataServerURL,
"upload_expiration": cfg.UploadExpiration,
"events": map[string]interface{}{
"nats_address": cfg.Events.Addr,
"nats_clusterid": cfg.Events.ClusterID,
"tls_insecure": cfg.Events.TLSInsecure,
"tls_root_ca_cert": cfg.Events.TLSRootCaCertPath,
"nats_enable_tls": cfg.Events.EnableTLS,
"nats_username": cfg.Events.AuthUsername,
"nats_password": cfg.Events.AuthPassword,
},
},
},
"interceptors": map[string]interface{}{

Thank you.

@jvillafanez
Copy link
Copy Markdown
Member

Maybe we can improve it and use only one graph. Now I use the second one for enforcing the vault storage and MFA for all graph endpoints

MFA needs to be enforced in the vault storage. Technically, graph shouldn't need to enforce MFA; it can make the request and the request will fail. The fact that we want graph to check for MFA is mostly for convenience, to avoid making a request that we know it will fail.

In addition, whether the request is under MFA or not is information that should be part of the request, and should be propagated as part of the request. This is very similar to what is done with telemetry. Graph shouldn't need a configuration flag to know if it can access to the vault or if MFA is active.

@2403905 2403905 changed the title Feat/ocisdev 533 graph [full-ci] feat: ocisdev-533 graph Mar 14, 2026
@2403905 2403905 requested review from Copilot and mklos-kw March 16, 2026 14:33
@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch from df07882 to a9fa2c1 Compare March 16, 2026 14:35
@2403905 2403905 marked this pull request as ready for review March 16, 2026 14:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the vendored reva dependency and introduces “vault mode” support across gateway, storage-users, proxy, and graph, including storage scoping for events and storage space selection.

Changes:

  • Bump github.com/owncloud/reva/v2 vendor version and adapt code to upstream changes (events, storage registry filtering, gateway client acquisition).
  • Add vault-mode plumbing: vault storage provider IDs/constants, vault-specific space provider config, and passing storage_id via CS3 opaque to target the vault storage.
  • Add configurable event consumer group and storage-aware filtering for decomposedfs postprocessing events; add MFA middleware integration for graph routes.

Reviewed changes

Copilot reviewed 18 out of 34 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vendor/modules.txt Updates vendored module version for reva/v2.
vendor/github.com/owncloud/reva/v2/pkg/utils/utils.go Adds vault storage provider/space IDs.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/options/options.go Adds consumer_group event option + default.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go Uses configurable consumer group; filters events by storage.
vendor/github.com/owncloud/reva/v2/pkg/storage/registry/spaces/spaces.go Filters vault spaces unless explicitly requested; supports storage_id filter.
vendor/github.com/owncloud/reva/v2/pkg/storage/cache/createpersonalspace.go Removes create-personal-space cache implementation.
vendor/github.com/owncloud/reva/v2/pkg/storage/cache/createhome.go Removes create-home cache implementation.
vendor/github.com/owncloud/reva/v2/pkg/storage/cache/cache.go Removes create-home/create-personal-space cache APIs.
vendor/github.com/owncloud/reva/v2/pkg/events/postprocessing.go Adds ResourceID to postprocessing events.
vendor/github.com/owncloud/reva/v2/internal/http/.../shares/spaces.go Simplifies provider client creation via pool directly.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/storageprovider/storageprovider.go Ensures root-info IDs get storage provider IDs filled.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovidercache.go Adjusts cache keying to include storage_id (opaque).
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovider.go Forwards storage_id via opaque and provider selection; removes some caching wrappers.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/gateway.go Removes create-personal-space cache wiring.
services/storage-users/pkg/revaconfig/drivers.go Passes consumer_group to reva storage config.
services/storage-users/pkg/config/defaults/defaultconfig.go Sets MountID to vault provider ID when vault mode enabled.
services/storage-users/pkg/config/config.go Adds enable_vault_mode and consumer_group config fields.
services/proxy/pkg/middleware/create_home.go Adds short-lived in-process TTL cache; creates regular + vault homes via storage_id.
services/proxy/pkg/config/defaults/defaultconfig.go Adds proxy policy route for /vault/graph/.
services/postprocessing/pkg/postprocessing/postprocessing.go Propagates ResourceID into emitted events.
services/policies/pkg/service/event/service.go Propagates ResourceID into emitted events.
services/graph/pkg/service/v0/service.go Adds RequireMFA middleware and vault-mode MFA routing behavior.
services/graph/pkg/service/v0/graph_test.go Updates tests to exercise router (ServeHTTP) instead of direct handler calls.
services/graph/pkg/service/v0/drives.go Forces vault storage selection via storage_id in opaque; removes inline MFA checks.
services/graph/pkg/service/v0/driveitems.go Adds vault-mode filtering for personal root children.
services/graph/pkg/middleware/mfa.go New middleware to enforce MFA.
services/graph/pkg/config/service.go Adds env/yaml tags for service name.
services/graph/pkg/config/config.go Adds enable_vault_mode config field.
services/gateway/pkg/revaconfig/config.go Adds a dedicated vault spaces provider definition.
services/gateway/pkg/config/defaults/defaultconfig.go Removes create-home cache defaults.
services/gateway/pkg/config/config.go Removes create-home cache configuration fields.
go.mod / go.sum Updates reva/v2 dependency version checksums.
.gitignore Ignores .agents/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/proxy/pkg/middleware/create_home.go Outdated
Comment thread services/graph/pkg/service/v0/driveitems.go Outdated
Comment thread services/graph/pkg/config/config.go Outdated
Comment thread services/graph/pkg/config/service.go Outdated
Comment thread services/storage-users/pkg/config/config.go Outdated
Comment thread services/storage-users/pkg/config/config.go Outdated
@2403905
Copy link
Copy Markdown
Contributor Author

2403905 commented Mar 17, 2026

Maybe we can improve it and use only one graph. Now I use the second one for enforcing the vault storage and MFA for all graph endpoints

MFA needs to be enforced in the vault storage. Technically, graph shouldn't need to enforce MFA; it can make the request and the request will fail. The fact that we want graph to check for MFA is mostly for convenience, to avoid making a request that we know it will fail.

In addition, whether the request is under MFA or not is information that should be part of the request, and should be propagated as part of the request. This is very similar to what is done with telemetry. Graph shouldn't need a configuration flag to know if it can access to the vault or if MFA is active.

That is a good point. @jvillafanez
The idea is to implement the Vault that doesn't require MFA dependencies.
The Vault-graph should ensure that requests go to Vault storage by requiring that some requests, like CreateStorageSpace and GetAllDrives, use the Vault storage ID explicitly.
So, the Vault graph can work without MFA, ensuring the drives' separation.
Then I assumed that the Graph is a good place to force MFA for all of the routes under the /vault with minimal effort.
The cons of this we still need to take care of the ocdav api MFA protection.

We can get rid of the extra vault-graph instance to provide an additional router that could be above the MFA

@2403905
Copy link
Copy Markdown
Contributor Author

2403905 commented Mar 17, 2026

@jvillafanez @mklos-kw I made a commit that makes the graph able to handle the vault prefix. no extra service needed
d456f68

@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch 2 times, most recently from b53fb87 to 5fc45db Compare March 18, 2026 08:53
@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Mar 18, 2026

The envvar description text says the following:
"GRAPH_ENABLE_VAULT_MODE" desc:"Enable vault mode for the graph service running in addition to the regular graph service. Requires running the storage-users-vault additional service."

This part confuses me: Requires running the storage-users-vault additional service.
We have an additional service (which I cant identify) or just an instance of the storage-users service with a different config? (a config example (or reference) should be added e.g. in the storage-users readme)

The envvar text should be precised (or the missing service added).

@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch 3 times, most recently from 8fcac29 to f9c326c Compare March 19, 2026 18:16
@2403905
Copy link
Copy Markdown
Contributor Author

2403905 commented Mar 20, 2026

The envvar description text says the following: "GRAPH_ENABLE_VAULT_MODE" desc:"Enable vault mode for the graph service running in addition to the regular graph service. Requires running the storage-users-vault additional service."

This part confuses me: Requires running the storage-users-vault additional service. We have an additional service (which I cant identify) or just an instance of the storage-users service with a different config? (a config example (or reference) should be added e.g. in the storage-users readme)

The envvar text should be precised (or the missing service added).

For now, the Vault mode requires running the storage-users as an additional service with specific configuration

@mmattel
Copy link
Copy Markdown
Contributor

mmattel commented Mar 20, 2026

For now, the Vault mode requires running the storage-users as an additional service with specific configuration

OK, makes sense. Please rewrite the envvar text accordingly because the current one does not match.

@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch from 85d7fdb to 702c7c7 Compare March 23, 2026 09:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a dedicated “vault” storage provider (with optional MFA enforcement) by adding a vault-mode storage-users instance and extending Graph/WebDAV + supporting services to route and filter vault requests appropriately.

Changes:

  • Add a vault storage provider ID and wiring to route /vault/* spaces to a dedicated storage-users-vault service.
  • Enforce/propagate MFA state across HTTP → go-micro → gRPC hops and add gRPC-side MFA blocking for vault storage.
  • Update Graph (vault-mode routing + filtering) and WebDAV copy/move restrictions for vault resources.

Reviewed changes

Copilot reviewed 36 out of 59 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vendor/modules.txt Bump vendored reva/v2 version.
vendor/github.com/owncloud/reva/v2/pkg/utils/utils.go Add VaultStorageProviderID constant.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go Include StorageId in postprocessing event ResourceID.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/options/options.go Add events consumer_group option + default.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go Use configurable consumer group + ignore events for other storages.
vendor/github.com/owncloud/reva/v2/pkg/storage/registry/spaces/spaces.go Filter vault spaces unless storage_id is explicitly requested.
vendor/github.com/owncloud/reva/v2/pkg/events/postprocessing.go Add ResourceID to postprocessing events.
vendor/github.com/owncloud/reva/v2/pkg/ctx/mfactx.go Define MFA HTTP header + gRPC autoprop metadata key.
vendor/github.com/owncloud/reva/v2/pkg/auth/manager/serviceaccounts/serviceaccounts.go Import order adjustment (vendored).
vendor/github.com/owncloud/reva/v2/pkg/auth/manager/oidc/oidc.go Import order adjustment (vendored).
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go Simplify storage provider client acquisition.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go Consider StorageId when checking parent/child refs; add vault destination restriction helper.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/move.go Block MOVE from vault to non-vault destinations.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/copy.go Block COPY from vault to non-vault destinations.
vendor/github.com/owncloud/reva/v2/internal/http/services/archiver/handler.go Emit X-Ocis-Mfa-Required header on MFA-related permission denials.
vendor/github.com/owncloud/reva/v2/internal/http/interceptors/auth/auth.go Forward MFA HTTP header into outgoing gRPC metadata.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/storageprovider/storageprovider.go Ensure storage provider ID is set on additional resource IDs in Stat responses.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovidercache.go Include storage_id in cache keying for provider listing.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovider.go Propagate storage_id through CreateHome/CreateStorageSpace/ListStorageSpaces.
vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/auth/mfa.go Add gRPC-side MFA blocking response helper.
vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/auth/auth.go Add mfa_enabled option and enforce MFA via incoming metadata.
services/webdav/pkg/service/v0/service.go Forward MFA status via go-micro metadata for thumbnails calls.
services/thumbnails/pkg/thumbnail/imgsource/cs3.go Bridge go-micro MFA metadata into gRPC metadata for gateway calls.
services/thumbnails/pkg/service/grpc/v0/service.go Bridge MFA metadata during Stat calls used for thumbnail generation.
services/storage-users/pkg/revaconfig/drivers.go Pass mount ID + event consumer group into reva storage driver configs.
services/storage-users/pkg/revaconfig/config.go Enable mfa_enabled in reva auth interceptor when vault mode is active.
services/storage-users/pkg/config/defaults/defaultconfig.go Force mount ID to VaultStorageProviderID in vault mode.
services/storage-users/pkg/config/config.go Add vault-mode toggle + consumer group config fields.
services/proxy/pkg/middleware/options.go Add MFA store + CreateVaultHome option plumbing.
services/proxy/pkg/middleware/mfa.go Persist MFA verification status for non-OIDC flows.
services/proxy/pkg/middleware/create_home.go Optionally provision vault home (forcing MFA metadata for provisioning call).
services/proxy/pkg/config/defaults/defaultconfig.go Route /vault/graph/ to Graph via proxy policies.
services/proxy/pkg/config/config.go Add create_vault_home config flag.
services/proxy/pkg/command/server.go Wire MFA store and CreateVaultHome into middleware chain.
services/postprocessing/pkg/postprocessing/postprocessing.go Include ResourceID in emitted PostprocessingFinished events.
services/policies/pkg/service/event/service.go Propagate ResourceID into PostprocessingStepFinished events.
services/graph/pkg/service/v0/spacetemplates.go Use vault-mode to target the vault storage-users instance for template operations.
services/graph/pkg/service/v0/sharedwithme.go Filter received shares by vault vs non-vault mode.
services/graph/pkg/service/v0/sharedbyme.go Filter “shared by me” results by vault vs non-vault mode.
services/graph/pkg/service/v0/service.go Add /vault/graph routing + require MFA for drives listing endpoints.
services/graph/pkg/service/v0/graph_test.go Update tests to execute via router (middleware-aware).
services/graph/pkg/service/v0/drives.go Force storage_id in vault mode for space creation/listing.
services/graph/pkg/service/v0/driveitems_test.go Add tests ensuring vault mode injects storage_id filter.
services/graph/pkg/service/v0/driveitems.go Inject storage_id filter for root drive children listing in vault mode.
services/graph/pkg/middleware/vault.go Add vault-mode context/middleware.
services/graph/pkg/middleware/mfa.go Add Graph middleware to require MFA.
services/graph/pkg/middleware/auth.go Propagate MFA status into outgoing gRPC metadata.
services/graph/pkg/config/service.go Make Graph service name configurable via env var.
services/graph/pkg/config/config.go Add Graph vault-mode toggle.
services/gateway/pkg/revaconfig/config.go Register dedicated vault storage provider and mountpoints.
services/collaboration/pkg/service/grpc/v0/service.go Carry MFA state into WOPI context.
services/collaboration/pkg/middleware/wopicontext.go Propagate WOPI MFA claim into outgoing gRPC metadata.
services/collaboration/pkg/connector/httpadapter.go Propagate MFA HTTP header into outgoing gRPC metadata for connector ops.
go.mod / go.sum Update dependencies for reva bump.
deployments/examples/ocis_full/vault-storage.yml Add example compose overlay for vault storage-users service.
deployments/examples/ocis_full/.env Add VAULT_STORAGE compose overlay toggle.
.make/go.mk Adjust debug docker build flags.
.gitignore Add ignores for local agent/tool files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/storage-users/pkg/config/config.go Outdated
Comment thread services/graph/pkg/config/config.go Outdated
Comment thread .make/go.mk
Comment thread services/graph/pkg/service/v0/spacetemplates.go
Comment thread services/storage-users/pkg/config/config.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a dedicated “vault” storage area intended to be MFA-protected by splitting responsibilities across a dedicated storage-users-vault instance and adding vault-aware routing/filtering in Graph, WebDAV, and supporting services.

Changes:

  • Add a vault storage provider ID and wire a dedicated storage-users-vault provider/mount (/vault/users, /vault/projects) into the gateway registry and space/provider lookups.
  • Enforce/propagate MFA across HTTP → gRPC hops (proxy, graph, webdav, thumbnails, collaboration/WOPI) and add a gRPC MFA gate for the vault storage-users instance.
  • Add vault-mode Graph routing (/vault/graph/...) and filter spaces/shares/drives based on the vault storage provider.

Reviewed changes

Copilot reviewed 36 out of 59 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
vendor/modules.txt Bumps vendored module listing for updated reva version.
vendor/github.com/owncloud/reva/v2/pkg/utils/utils.go Adds VaultStorageProviderID constant.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go Includes StorageId in emitted postprocessing ResourceID.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/options/options.go Adds events consumer_group option with default.
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go Uses configurable consumer group + ignores postprocessing events for other storages.
vendor/github.com/owncloud/reva/v2/pkg/storage/registry/spaces/spaces.go Adds vault-aware filtering and supports storage_id filter propagation.
vendor/github.com/owncloud/reva/v2/pkg/events/postprocessing.go Extends postprocessing events with ResourceID.
vendor/github.com/owncloud/reva/v2/pkg/ctx/mfactx.go Introduces MFA metadata/header constants for propagation.
vendor/github.com/owncloud/reva/v2/pkg/auth/manager/serviceaccounts/serviceaccounts.go Import ordering adjustment due to vendoring changes.
vendor/github.com/owncloud/reva/v2/pkg/auth/manager/oidc/oidc.go Import ordering adjustment due to vendoring changes.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go Simplifies storage provider client acquisition.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go Adds storage ID check in recursion detection + helper to restrict vault copies/moves.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/move.go Blocks moving from vault to non-vault destinations.
vendor/github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/copy.go Blocks copying from vault to non-vault destinations.
vendor/github.com/owncloud/reva/v2/internal/http/services/archiver/handler.go Emits MFA-required header + status behavior for MFA-protected accesses.
vendor/github.com/owncloud/reva/v2/internal/http/interceptors/auth/auth.go Forwards MFA status from HTTP header into outgoing gRPC metadata.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/storageprovider/storageprovider.go Ensures storage provider IDs are set (incl. root_info.id).
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovidercache.go Improves cache key derivation to include storage_id and avoid collisions.
vendor/github.com/owncloud/reva/v2/internal/grpc/services/gateway/storageprovider.go Propagates storage_id through create/list requests for vault handling.
vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/auth/mfa.go Adds MFA-blocking responder for many storageprovider RPCs.
vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/auth/auth.go Adds mfa_enabled config and enforces MFA based on incoming metadata.
services/webdav/pkg/service/v0/service.go Bridges MFA into go-micro metadata for thumbnail requests.
services/thumbnails/pkg/thumbnail/imgsource/cs3.go Bridges MFA from go-micro metadata into gRPC outgoing metadata.
services/thumbnails/pkg/service/grpc/v0/service.go Preserves request context and bridges MFA when stat’ing via gateway.
services/storage-users/pkg/revaconfig/drivers.go Passes mount ID and event consumer group into reva driver config.
services/storage-users/pkg/revaconfig/config.go Enables MFA enforcement in auth interceptor when vault mode is on.
services/storage-users/pkg/config/defaults/defaultconfig.go Sets mount ID to VaultStorageProviderID when vault mode is enabled.
services/storage-users/pkg/config/config.go Adds vault mode and event consumer group configuration options.
services/proxy/pkg/middleware/options.go Adds MFAStore and CreateVaultHome middleware options.
services/proxy/pkg/middleware/mfa.go Persists MFA status for non-OIDC requests via store with TTL.
services/proxy/pkg/middleware/create_home.go Optionally provisions a vault home (forcing MFA metadata for provisioning).
services/proxy/pkg/config/defaults/defaultconfig.go Adds proxy policy entry for /vault/graph/.
services/proxy/pkg/config/config.go Adds PROXY_CREATE_VAULT_HOME config option.
services/proxy/pkg/command/server.go Wires MFAStore and CreateVaultHome into middleware chain.
services/postprocessing/pkg/postprocessing/postprocessing.go Includes ResourceID in finished postprocessing event.
services/policies/pkg/service/event/service.go Propagates ResourceID through policies-driven postprocessing events.
services/graph/pkg/service/v0/spacetemplates.go Selects storage-users(-vault) address based on vault mode.
services/graph/pkg/service/v0/sharedwithme.go Filters “shared with me” results based on vault vs regular mode.
services/graph/pkg/service/v0/sharedbyme.go Filters “shared by me” results based on vault vs regular mode.
services/graph/pkg/service/v0/service.go Adds /vault/graph routes and applies vault/MFA middleware.
services/graph/pkg/service/v0/graph_test.go Updates tests to route through the service router for middleware coverage.
services/graph/pkg/service/v0/drives.go Forces vault storage_id in Create/List flows when vault mode is enabled.
services/graph/pkg/service/v0/driveitems_test.go Adds tests for vault-mode storage_id filtering behavior.
services/graph/pkg/service/v0/driveitems.go Forces vault storage_id when listing personal root drive children in vault mode.
services/graph/pkg/middleware/vault.go Adds vault-mode context marker + middleware.
services/graph/pkg/middleware/mfa.go Adds Graph-level RequireMFA middleware.
services/graph/pkg/middleware/auth.go Propagates MFA state to outgoing gRPC metadata from Graph.
services/graph/pkg/config/service.go Makes graph service name configurable via env/yaml.
services/graph/pkg/config/config.go Adds GRAPH_ENABLE_VAULT_MODE config option.
services/gateway/pkg/revaconfig/config.go Registers dedicated storage-users-vault provider with vault mount points.
services/collaboration/pkg/service/grpc/v0/service.go Carries MFA status into WOPI token context.
services/collaboration/pkg/middleware/wopicontext.go Propagates MFA status from WOPI token into outgoing gRPC metadata.
services/collaboration/pkg/connector/httpadapter.go Propagates MFA header into outgoing gRPC metadata for connector calls.
go.sum Updates checksums for new reva version.
go.mod Bumps github.com/owncloud/reva/v2 dependency.
deployments/examples/ocis_full/vault-storage.yml Adds example compose overlay to run storage-users-vault and enable vault mode.
deployments/examples/ocis_full/.env Adds VAULT_STORAGE compose overlay toggle.
.make/go.mk Adjusts debug docker build flags (removes -trimpath).
.gitignore Adds additional ignore entries (but introduces duplication).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/graph/pkg/service/v0/spacetemplates.go
Comment thread services/graph/pkg/service/v0/service.go Outdated
Comment thread services/graph/pkg/service/v0/service.go
Copy link
Copy Markdown
Member

@jvillafanez jvillafanez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The collaboration service is using "custom" HTTP clients in some places such as

so we'll need to check those. Those clients won't send the MFA header, which might cause problems (we need to fix those). GRPC services should be covered with the AppendToOutgoingContext calls.
Note that the discovery part will connect to the office app, which is an external system, so we don't need to propagate data there.

Comment thread services/graph/pkg/middleware/mfa.go
Comment thread services/collaboration/pkg/connector/httpadapter.go Outdated
@jvillafanez
Copy link
Copy Markdown
Member

Before I forget, a couple of things to investigate:

ocis-1                 | {"level":"info","service":"auth-service","pkg":"rgrpc","traceid":"2c619983da969c56a58b7b0f2f1ff57c","time":"2026-04-28T16:49:51Z","line":"/home/juan/src/ocis/ocis/vendor/github.com/owncloud/reva/v2/internal/grpc/services/authprovider/authprovider.go:146","message":"user idp:\"none\" opaque_id:\"13dbb844-e104-4ddf-ad53-aeb8af6b44ea\" type:USER_TYPE_SERVICE authenticated"}
storage-users-vault-1  | {"level":"warn","service":"storage-users-vault","pkg":"rgrpc","traceid":"485cc04473abe3df886c51f92b169968","user_id":"13dbb844-e104-4ddf-ad53-aeb8af6b44ea","mfa_values":[],"time":"2026-04-28T16:49:51Z","line":"/home/juan/src/ocis/ocis/vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/auth/auth.go:162","message":"MFA is required"}
storage-users-vault-1  | {"level":"debug","service":"storage-users-vault","pkg":"rgrpc","traceid":"485cc04473abe3df886c51f92b169968","user-agent":"grpc-go/1.80.0","from":"tcp://172.26.0.5:42394","uri":"/cs3.storage.provider.v1beta1.ProviderAPI/Stat","start":"28/Apr/2026:16:49:51 +0000","end":"28/Apr/2026:16:49:51 +0000","time_ns":147804,"code":"OK","time":"2026-04-28T16:49:51Z","line":"/home/juan/src/ocis/ocis/vendor/github.com/owncloud/reva/v2/internal/grpc/interceptors/log/log.go:69","message":"unary"}
ocis-1                 | {"level":"error","service":"search","error":"error: permission denied: MFA required to access vault storage","time":"2026-04-28T16:49:51Z","line":"/home/juan/src/ocis/ocis/services/search/pkg/search/service.go:454","message":"error walking the tree"}
ocis-1                 | {"level":"error","service":"search","error":"error: permission denied: MFA required to access vault storage","spaceID":{"opaque_id":"1a01c2c4-4309-4483-a845-842fd56d8622$bca1b64f-c5c5-43d8-93ac-02d000241c3a"},"time":"2026-04-28T16:49:51Z","line":"/home/juan/src/ocis/ocis/services/search/pkg/search/events.go:56","message":"error while indexing a space"}

The "thumbnails", "webdav", "search" and "collaboration" services use custom HTTP clients to make some requests to other oCIS services. These clients won't send the MFA header automatically, so we need to add the header manually.
I assume the MFA error above is caused by the search client, although we'll need to confirm.
The collaboration service should be fixed already (I haven't found anything wrong accessing to the vault from collabora). The other services need to be checked.

@jvillafanez
Copy link
Copy Markdown
Member

Regarding the errors shown in #12108 (comment) I'm not sure if that will be a blocking issue, but I think it's out of scope for the time being.
I'm pretty sure the problem is caused by the data propagation in the events. There are several problems to tackle first:

  • Context handling in the events: Right now, there is no context associated to the event. When the event starts being processed, a new context should be created. Additional contexts might be derived from it if needed.
  • Data propagation between event publisher and consumer: This is also missing. Outside if the event itself and the data it carries, no other data is propagated. In particular, contextual data such as the MFA isn't propagated (this seems the cause of the error above). Note that without a context to set the propagated data into, it's going to be problematic for the data to reach the relevant components.
  • Tracing information: the tracing information seems to be sent with the event, but the consumer might not use it or link it with the publisher. This leads to inconsistent data shown in tools like jaeger. Since the consumer trace isn't linked, it will appear as a new trace with a weird starting point (like the reva gateway).

In addition to the points above, the search service will need additional refactoring to accommodate context usage in some parts of its code, so the information can be propagated from the event processor through the context.

For the short term, the plan is to sort this out for the search service (in a different PR). Once it's done and merged, we should be able to fix the issue above. Other services might still need similar changes.

httpReq.Header.Add("X-Access-Token", wopiContext.AccessToken)
}
if wopiContext.HasMFA {
httpReq.Header.Add(mfa.MFAHeader, "true")
Copy link
Copy Markdown
Contributor Author

@2403905 2403905 Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jvillafanez Please use mfa.SetHeader(httpReq, true) instead.

Comment thread deployments/examples/ocis_full/vault-storage.yml Outdated
Comment thread deployments/examples/ocis_full/vault-storage.yml Outdated
Comment thread services/gateway/pkg/config/config.go Outdated
Comment thread services/graph/pkg/config/config.go Outdated
Comment thread services/graph/pkg/config/config.go Outdated
Comment thread services/graph/pkg/config/service.go Outdated
Comment thread services/proxy/pkg/config/config.go Outdated
Comment thread services/storage-users/pkg/config/config.go Outdated
Comment thread services/storage-users/pkg/config/config.go Outdated
AuthServiceEndpoint string `yaml:"auth_service_endpoint" env:"GATEWAY_AUTH_SERVICE_ENDPOINT" desc:"The endpoint of the auth-service service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"7.0.0"`
StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint" env:"GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT" desc:"The endpoint of the storage-publiclink service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"7.0.0"`
StorageUsersEndpoint string `yaml:"storage_users_endpoint" env:"GATEWAY_STORAGE_USERS_ENDPOINT" desc:"The endpoint of the storage-users service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"7.0.0"`
StorageUsersVaultEndpoint string `yaml:"storage_users_vault_endpoint" env:"GATEWAY_STORAGE_USERS_VAULT_ENDPOINT" desc:"The endpoint of the storage-users-vault service. The storage-users-vault is an additional storage-users service that runs in vault mode. It can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"Deledda"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sentence:
It can take a service name or a gRPC URI with the dns, kubernetes or unix protocol.
Where will that name or URI used?
Imho we should add a readme addon to describe this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is related to the Space template being applied.
The L#45 is a duplicate of the L#44 but for valut.

Co-authored-by: Martin <github@diemattels.at>

Update services/gateway/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update services/graph/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update services/graph/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update services/storage-users/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update services/proxy/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update services/storage-users/pkg/config/config.go

Co-authored-by: Martin <github@diemattels.at>

Update deployments/examples/ocis_full/vault-storage.yml

Co-authored-by: Martin <github@diemattels.at>
@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch from 86c41c2 to 82f04d7 Compare May 4, 2026 16:33
@2403905 2403905 force-pushed the feat/OCISDEV-533-graph branch from c82ad90 to 81399ea Compare May 5, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants