Summary
Creating a federated share via the Graph API driveItem/invite endpoint fails with a generic internal error, even though the OCM invitation handshake (generate-invite / accept-invite) between the two instances completed successfully and is verifiable via the sciencemesh API.
Environment
OpenCloud 7.4.0 (rolling). Two independent self-hosted instances, embedded IDM (no external LDAP) on either side. OC_ENABLE_OCM=true on both instances. Matching ocmproviders.json declaring mutual trust between both domains.
Steps to reproduce
Step 1: On instance A (a.example.com), authenticate as user A and call POST /sciencemesh/generate-invite. Returns a token and expiration.
Step 2: On instance B (b.example.com), authenticate as user B and call POST /sciencemesh/accept-invite with the token and providerDomain=a.example.com. Returns HTTP 200.
Step 3: Confirm the handshake on both instances via GET /sciencemesh/find-accepted-users. Both sides correctly list each other as an accepted federated user. This part works as documented.
Step 4: On instance A, attempt to share an existing personal folder with user B via the Graph API:
POST /graph/v1beta1/drives/{driveId}/items/{itemId}/invite
Content-Type: application/json
{
"recipients": [
{
"objectId": "@https://b.example.com",
"@libre.graph.recipient.type": "user"
}
],
"roles": ["b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5"]
}
Expected result
Per services/ocm/README.md: "we allow creating federated shares using the graph API. Clients can now discover the available sharing roles and invite federated users using the graph API." The share should be created as an OCM share.
Actual result
HTTP 400 with body:
error.code = invalidRequest
error.message = generalException: unexpected status code while getting accepted user: CODE_INTERNAL
Investigation
Traced through the source (main branch, commit-pinned dependency github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d).
DriveItemPermissionsService.Invite() in services/graph/pkg/service/v0/api_driveitem_permissions.go correctly detects that objectID is not a local user (identityCache.GetCS3User returns ErrNotFound), and since IncludeOCMSharees is enabled, falls back to identityCache.GetAcceptedCS3User(ctx, objectID) in services/graph/pkg/identity/cache/cache.go.
GetAcceptedCS3User parses the composite id via getIDAndMeshProvider, builds a cs3User.UserId{Idp, OpaqueId, Type: USER_TYPE_FEDERATED}, and calls revautils.GetAcceptedUserWithContext() (github.com/opencloud-eu/reva/v2/pkg/utils), which calls gwc.GetAcceptedUser(ctx, invitev1beta1.GetAcceptedUserRequest{RemoteUserId: userID}).
This gRPC call returns status CODE_INTERNAL, which checkStatusCode("getting accepted user", ...) turns into the generic error surfaced above.
So the failure is inside the gateway's GetAcceptedUser RPC handler, not in the Graph API request itself. The same federated user is correctly resolved by the sciencemesh HTTP API (find-accepted-users) moments earlier, so the underlying invitation data is intact; something in the gRPC path specifically breaks.
This appears to block the entire create-a-federated-share-via-the-Graph-API flow documented in services/ocm/README.md, since every code path for a federated recipient depends on this lookup succeeding.
Possibly related to the ongoing OCM compliance work in opencloud-eu/reva#383.
Additional context
objectId format tried: opaque-id@https://domain (as returned by /sciencemesh/find-accepted-users), also tried without the https:// prefix and with just the opaque id, same error in all variants.
Role ID used (b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5, Can view) is valid and works correctly for local-user invites on the same folder.
IncludeOCMSharees must be enabled on this deployment, since the code path reaches the OCM-specific lookup at all (with it disabled, the error would instead be the earlier generic failed-user-lookup error for a plain not-found user).
Summary
Creating a federated share via the Graph API driveItem/invite endpoint fails with a generic internal error, even though the OCM invitation handshake (generate-invite / accept-invite) between the two instances completed successfully and is verifiable via the sciencemesh API.
Environment
OpenCloud 7.4.0 (rolling). Two independent self-hosted instances, embedded IDM (no external LDAP) on either side. OC_ENABLE_OCM=true on both instances. Matching ocmproviders.json declaring mutual trust between both domains.
Steps to reproduce
Step 1: On instance A (a.example.com), authenticate as user A and call POST /sciencemesh/generate-invite. Returns a token and expiration.
Step 2: On instance B (b.example.com), authenticate as user B and call POST /sciencemesh/accept-invite with the token and providerDomain=a.example.com. Returns HTTP 200.
Step 3: Confirm the handshake on both instances via GET /sciencemesh/find-accepted-users. Both sides correctly list each other as an accepted federated user. This part works as documented.
Step 4: On instance A, attempt to share an existing personal folder with user B via the Graph API:
POST /graph/v1beta1/drives/{driveId}/items/{itemId}/invite
Content-Type: application/json
{
"recipients": [
{
"objectId": "@https://b.example.com",
"@libre.graph.recipient.type": "user"
}
],
"roles": ["b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5"]
}
Expected result
Per services/ocm/README.md: "we allow creating federated shares using the graph API. Clients can now discover the available sharing roles and invite federated users using the graph API." The share should be created as an OCM share.
Actual result
HTTP 400 with body:
error.code = invalidRequest
error.message = generalException: unexpected status code while getting accepted user: CODE_INTERNAL
Investigation
Traced through the source (main branch, commit-pinned dependency github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d).
DriveItemPermissionsService.Invite() in services/graph/pkg/service/v0/api_driveitem_permissions.go correctly detects that objectID is not a local user (identityCache.GetCS3User returns ErrNotFound), and since IncludeOCMSharees is enabled, falls back to identityCache.GetAcceptedCS3User(ctx, objectID) in services/graph/pkg/identity/cache/cache.go.
GetAcceptedCS3User parses the composite id via getIDAndMeshProvider, builds a cs3User.UserId{Idp, OpaqueId, Type: USER_TYPE_FEDERATED}, and calls revautils.GetAcceptedUserWithContext() (github.com/opencloud-eu/reva/v2/pkg/utils), which calls gwc.GetAcceptedUser(ctx, invitev1beta1.GetAcceptedUserRequest{RemoteUserId: userID}).
This gRPC call returns status CODE_INTERNAL, which checkStatusCode("getting accepted user", ...) turns into the generic error surfaced above.
So the failure is inside the gateway's GetAcceptedUser RPC handler, not in the Graph API request itself. The same federated user is correctly resolved by the sciencemesh HTTP API (find-accepted-users) moments earlier, so the underlying invitation data is intact; something in the gRPC path specifically breaks.
This appears to block the entire create-a-federated-share-via-the-Graph-API flow documented in services/ocm/README.md, since every code path for a federated recipient depends on this lookup succeeding.
Possibly related to the ongoing OCM compliance work in opencloud-eu/reva#383.
Additional context
objectId format tried: opaque-id@https://domain (as returned by /sciencemesh/find-accepted-users), also tried without the https:// prefix and with just the opaque id, same error in all variants.
Role ID used (b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5, Can view) is valid and works correctly for local-user invites on the same folder.
IncludeOCMSharees must be enabled on this deployment, since the code path reaches the OCM-specific lookup at all (with it disabled, the error would instead be the earlier generic failed-user-lookup error for a plain not-found user).