Save the MFA status after the user is resolved so signed-URL downloads
inherit it, and check its age on read. Build the signing-key URL with
the URL API so it works with the vault base URL.
* fix: [OCISDEV-1476] fix AuthApp requests failing with a custom PROXY_USER_OIDC_CLAIM
* fix: [OCISDEV-1476] map ErrAccountNotFound to 401 in verifyUser
AccountResolver.verifyUser only mapped ErrAccountDisabled to 401 before
falling through to a generic 500. The identity backend excludes disabled
accounts from by-username lookups and returns ErrAccountNotFound instead,
so a disabled user authenticating via AppAuth or basic auth got a 500
instead of a 401, caught by the acceptance test suite.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Requests on unprotected routes can carry a reva token without a resolved
user: reva's internal downloads to the data gateway (/data) are sent with
the caller's token. create_home logged "no user in context" at error level
for each of them, so every download added an error line. Log at debug with
the path instead; the request is passed on unchanged, as before.
Fixes#13101
Claude-Session: https://claude.ai/code/session_01WpoeSoKYEdgQcWjEzTVKpT
Signed-off-by: Paul Faure <paul@faure.ca>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The next oCIS release is 9.0.0, so all envvars that were annotated with
the previously planned 8.3.0 introduction version need to be updated.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* fix: the public share configuration and fixed graceful shutdown
* fix: [OCISDEV-1433] remove GRPC_MAX_CONNECTION_AGE
The setting closed healthy grpc connections on a timer so that clients would redo
their DNS lookup. It never helped against the failure it was reached for - a
connection whose peer stopped answering - because the age limit is enforced by
the server, the grace period was left at infinity so a request already in flight
was never ended, and any value without a unit suffix silently disabled it again.
Detecting a peer that stops answering is now the job of the grpc clients, which
ping the peer while a request is in flight. The servers here got the matching
enforcement policy so they accept those pings; the client side arrives with the
next reva bump.
* fix: Added the new variable OCDAV_DISABLE_PROPFIND_PUBLIC_LINK_RESOLUTION that disable the resolution of public link shares when answering PROPFIND requests.
* chore: bump reva
* fix: The keepalive added to grpc clinet
* chore: bump reva
* build(deps): bump go 1.26.8, grpc-go dependency
---------
(cherry picked from commit e86eb4d210)
For the 9.0 branch, the reva dependency was pointed at reva's main-branch
merge of PR #748 (commit 373f9509a, pseudo-version
v2.0.0-20261005091647-373f9509a363) instead of the 8.2-targeted
e0beaa380005, since the 8.2 merge predates the VaultMode/UploadSessionFilter.Orphaned
APIs already present on the 9.0 reva lineage.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts:
# changelog/unreleased/security-bump-grpc.md
# go.mod
# go.sum
# vendor/google.golang.org/grpc/server.go
# vendor/google.golang.org/grpc/stream.go
# vendor/google.golang.org/grpc/version.go
# vendor/modules.txt
The proxy public share authenticator set the brute force protection skip
marker on every authentication, including requests where the proxy is the
only authenticator. Failed password attempts on those requests were never
counted, so the rate limit for password protected public links was not
enforced.
The skip marker is now only set for requests that are re-authenticated
downstream, so failed attempts are reliably counted and the throttle is
applied consistently.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document that the *_TLS_INSECURE options for the nats-js-kv store, cache and
service registry disable authentication of the NATS server and are for testing
only, so operators securing a multi-node deployment are not misled into
weakening the connection they just enabled TLS on.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: use specific gookit config instance instance of using global
Using the global instance was causing a panic when the service was
restarted. That panic won't happen now.
* chore: add changelog entry
* chore: Add audience restriction for OIDC access tokens
* fix: add new envvar to added table
Signed-off-by: Martin Mattel <github@diemattels.at>
* fix: add updated env_vars.yaml file
* chore: var name to plural. update config
---------
Signed-off-by: Martin Mattel <github@diemattels.at>
Co-authored-by: Martin Mattel <github@diemattels.at>
* fix(proxy,graph): do not disable personal space on inconclusive permission check
When a user's role is (re-)assigned, both the proxy (on OIDC login) and the
graph appRoleAssignment handler check the Drives.Create permission to decide
whether to restore or disable the user's personal space. An indeterminate
permission result (transport error or a non-OK status other than
PERMISSION_DENIED) was treated as a denial, which disabled (trashed) the
personal space on a transient settings/gateway fault — with no automatic
re-enable. See OCISDEV-884.
Both call sites now fail closed: on an indeterminate result they leave the
personal space untouched, revert the just-persisted role assignment so the
user is not left in a half-applied state, and surface the error (the proxy
retries on the next login, the graph handler returns 500). Relies on the
matching reva utils.CheckPermission change that surfaces non-authoritative
statuses as an error.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* rebased
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix(proxy): use events endpoint (not cluster id) for the readyz NATS check
The proxy readiness handler passed Events.Cluster (the cluster ID) to
NewNatsCheck, which forwards it to nats.Connect as an address. NATS then tried
to resolve the cluster ID as a host name and always failed, so /readyz reported
the proxy as not ready regardless of NATS reachability. Every other service
passes Events.Endpoint; the proxy now does too.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: David Walter <david.walter@kiteworks.com>
* test: drop now-passing proxy readiness expected-failure
The proxy /readyz fix makes serviceAvailabilityCheck.feature:115 ("check default
services readiness (graph, idp, proxy)") pass, so remove it from the expected
failures. The auth-bearer health/readiness entries (:124, :135) remain, as they
are a separate part of #10661 not addressed here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: David Walter <david.walter@kiteworks.com>
---------
Signed-off-by: David Walter <david.walter@kiteworks.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SyncGroupMemberships reconciles a user's groups against the groups claim and
removes them from any group not present in it. When a token carried no groups
claim at all (e.g. issued for an OIDC client without a groups mapper, such as a
dedicated desktop-client registration), the parsed group set was empty and the
user was removed from ALL of their groups.
Skip the sync when the groups claim is absent or null; a present-but-empty claim
is still treated as a legitimate "no groups" and reconciled. This mirrors the
guard the role-assignment path already has for a missing roles claim.
Signed-off-by: David Walter <david.walter@kiteworks.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
getClaims rejected a request with jwt.ErrTokenExpired whenever the cached
userinfo entry's expiry had passed, instead of re-verifying the access token.
The cached "exp" is not always the real token expiry: for opaque access tokens
extractExpiration falls back to the configured cache TTL. A still-valid token
could therefore be rejected merely because its cache entry aged out, producing
spurious logouts (most visible under frequent PROPFIND requests).
getClaims now treats an expired cache entry as a cache miss and falls through to
VerifyAccessToken/UserInfo re-verification. A genuinely expired or invalid token
is still rejected by that re-verification, so authentication is not weakened.
The test's mock now returns a fresh claims map per call, mirroring the real
client, so the suite is race-clean (getClaims caches asynchronously).
Signed-off-by: David Walter <david.walter@kiteworks.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
signatureIsValid indexed signingKey[0] without checking the slice length. When
the signing-key store returns an empty result without an error — which the
"noop" store does, and OCIS_CACHE_STORE=noop also switches the presigned-URL
signing-key store to noop — every signed-URL download panicked with
"index out of range [0] with length 0" (recovered per request as a 502), so all
signed-URL downloads failed.
Guard the index access and return a real authentication error. The previous
empty-value branch also returned a nil error, which would have accepted an empty
signing key; it now returns an error so the request is rejected.
Signed-off-by: David Walter <david.walter@kiteworks.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: metadata autopropagation
* feat: autoprop support for MFA / vault mode
* fix: replace some http clients with reva ones
* chore: required lib update
* fix: adjust unit tests and generate new mocks
* fix: apply autopropagation to all regular graph routes
* chore: updated reva dependency
* fix: return the right decorator for the thumbnails
* fix: remove autopropagation headers in the proxy
The space management middleware removed users from all project spaces
when processing signed URL requests because no OIDC claims are present
in that auth context. Return early when claims are nil to prevent the
oscillating add/remove cycle.
Signed-off-by: Julian Koberg <julian.koberg@kiteworks.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Implemet the vault-storage
feat: Separate the storage-users and graph to handle
feat: move the space create cache
configurate the vault srorage Postprocessing
hide the assignment of the MountID to VaultStorageProviderID behind a flag to avoid the ID mismatch
configurate the proxy to create the vault home space
update the filter
Make the graph able to handle vault prefix. no extra service needed
apply the vault filter to sharedbyme and sharedwithme
added vault-storage docker
use squashed reva
fix the finishUpload event
restict webdav copy/move from the vault
feat: provide the mfa to webdav and grpc
feat: refactoring: provide the mfa to webdav and grpc
mfa collaboration
fix GetRootDriveChildren and more
fix: send the MFA header in HTTP clients from the collaboration service
provide the default storage user vault configuration
update create_home middleware
Update deployments/examples/ocis_full/vault-storage.yml
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>
bump reva
deduplicate the requireMFA middeware on vault routes. fix AppendPlainToOpaque.
added the changlog and comments
* feat: add the vault mode search
* Update changelog/unreleased/enhancement-vault-storage.md
Co-authored-by: Martin <github@diemattels.at>
* update the readme. the reva vault storage provider configuration disabled by default
* feat: [OCISDEV-531] add vault capabilities to the OCS capabilities endpoint
* the port range allocated. the configuration updated.
---------
Co-authored-by: Martin <github@diemattels.at>
- Change introductionVersion from "8.0.0" to "Daledda" (codename)
- Clarify that the cache is a process-lifetime cache tracking which
users have a personal space, not one of the general proxy caches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract homeKnown() and createHome() from ServeHTTP to bring
cognitive complexity under the SonarCloud limit of 15.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow operators to disable the in-memory CreateHome cache via
PROXY_CREATEHOME_CACHE_DISABLED as a fallback if the cache causes
unexpected behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use canonical header casing "X-Access-Token" (canonicalheader)
- Return true instead of nil on success to avoid nilnil (nilnil)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CreateHome middleware fired a gRPC CreateHome request on every
authenticated HTTP request. On first login the browser sends ~11
parallel requests, each triggering a redundant call. Use singleflight
to collapse concurrent calls for the same user and sync.Map to cache
successful results so subsequent requests skip the gRPC call entirely.
Fixes: #12068
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The bundled Web UI CSS (from owncloud/web) inlines the KaTeX_Size3 font
as a base64 data:font/woff2 URI. The default CSP sets font-src to 'self'
only, which blocks these data URIs and produces a console error on every
page load:
Loading the font 'data:font/woff2;base64,...' violates the following
Content Security Policy directive: "font-src 'self'".
Add 'data:' to font-src, matching the existing pattern where img-src
already permits data: URIs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The server handlers for go-micro reuse the data from reva so the
propagation also works with reva services.
Both reva and go-micro services will propagate the data correctly.