Repository navigation
v3.13.0
Changelog for reva 3.13.0 (2026-10-06)
The following sections list the changes in reva 3.13.0 relevant to
reva users. The changes are ordered by importance.
Summary
- Sec #5839: Enforce transport TLS floor and scheme policy
- Sec #5836: Guard inbound share discovery against SSRF
- Sec #5838: Guard remaining OCM discovery inputs
- Sec #5837: Guard receiver OCM and WebDAV connections
- Sec #5834: Bound peer-controlled OCM JSON
- Fix #5825: Init admin connection instead of mounting
- Fix #5858: Set ceph user thread groups per thread
- Fix #5840: A grpc or http block with no services is no longer rejected
- Fix #5861: The lightweight scope for updating ocm shares
- Fix #5804: Rjobs timeouts + registry issues
- Fix #5816: Incorrect name for labelsprovider
- Fix #5791: Fixes for the EOSC Node
- Fix #5811: Report folder size in public links
- Fix #5817: Reconnect the service registry when publishing fails
- Fix #5849: Seperate the eos user and userid cache
- Fix #5813: Make service names unique per transport
- Enh #5826: Add embedded processing failure mode
- Enh #5692: Add the Reva Admin API
- Enh #5815: Discover app providers through the service registry
- Enh #5644: Implement LoginFlow (apptokens)
- Enh #5843: Create a home for lightweight accounts on login
- Enh #5814: Allow LW accounts to use modern paths
- Enh #5860: Log the resource id on the access line
- Enh #5859: Log who accessed a resource and who owns it
- Enh #5768: Small cleanup of notification system
- Enh #5833: Add shared OCM HTTP transport package
- Enh #5741: Add periodic job to check orphaned shares
- Enh #5771: Replace backup_job_id with backup_name in projects table
- Enh #5841: Fail over to another node when a peer cannot be reached
- Enh #5665: Add a service registry for service discovery
- Enh #5746: Implement shallow reconcile job
- Enh #5780: Add a takeout service to export a user's home directory
- Enh #5801: Cache for app passwords used by sync client
Details
-
Security #5839: Enforce transport TLS floor and scheme policy
The shared OCM HTTP transport now requires TLS 1.2 or newer on every client (including trusted
and insecure modes), rejects plain HTTP on public-only clients except an explicit
literal-loopback opt-in, and rejects HTTPS-to-HTTP redirects on public-only HTTP clients.
The address classifier also closes bounded gaps for the IANA special-purpose ranges
(0.0.0.0/8, 198.18.0.0/15, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24,
240.0.0.0/4, 64:ff9b:1::/48, 2001:db8::/32), keeping the PCP and TURN anycast exceptions
(RFC 7723/8155) and the well-known NAT64 unwrap.Explicit federation CIDR ranges do not relax that scheme policy, the TLS minimum, or redirect
enforcement. A configured private address is still HTTPS-only, and a redirect is checked
against the same address policy as the dial. -
Security #5836: Guard inbound share discovery against SSRF
Unauthenticated inbound
/sharesdiscovery now uses a public-only HTTP client built once at
handler init and reused per request, closing the SSRF where a sender-derived server could
steer the inbound service at private networks. Loopback is allowed only behind an explicit
allow_loopback_federationflag for the local two-provider integration topology; both
local integration fixtures declare the exception. The discovery timeout is now configurable
viaocm_client_timeout(seconds, default 10, preserving the existing inbound-discovery
timeout). Operators can opt the inbound public-only client into honoringHTTP_PROXY,
HTTPS_PROXY, andNO_PROXYviaocm_client_use_env_proxy(off by default; the
public-only client stays direct unless explicitly enabled).Controlled federation deployments with private RFC 1918 / IPv6 ULA destinations can opt the
inbound public-only discovery client into a narrow address exception via
allowed_federation_cidrs(off by default; each entry must be a canonical CIDR wholly
inside10.0.0.0/8,172.16.0.0/12,192.168.0.0/16, orfc00::/7). An invalid
element fails service startup before any discovery runs: no partially accepted list is
installed and the router is not served. Ordinary public destinations remain permitted,
loopback stays gated behindallow_loopback_federation, and unrelated private ranges
remain denied. -
Security #5838: Guard remaining OCM discovery inputs
The open provider authorizer's GetInfoByDomain and the ScienceMesh directory-listed
provider discovery now use the shared public-only OCM client. The operator-configured
directory fetch stays on the trusted client; only provider URLs taken from the unsigned
directory response (and request-supplied WAYF discovery) go through the public-only
client. Loopback is disabled for open-authorizer discovery. Both untrusted paths bypass
environment proxies. Blocked targets are rejected before any request reaches the server.Operators may now configure an explicit
allowed_federation_cidrsexception list for the
public-only OCM discovery clients (ScienceMesh WAYF and the open provider authorizer). The
list is empty by default and admits only canonical RFC 1918 IPv4 or IPv6 ULA prefixes; invalid
entries abort initialization before any directory fetch. Directory fetches stay trusted;
listed providers and request-supplied discovery remain public-only with the configured
exception only. TLS verification, loopback, and proxy controls stay independent. -
Security #5837: Guard receiver OCM and WebDAV connections
Inbound legacy WebDAV type probes, received-share OCM discovery and token exchange, and
received-share WebDAV operations now all use the public-only transport from the shared OCM
client package. One stored OCM client guards both discovery and token exchange; one driver
helper builds every gowebdav client and always applies the guarded transport, including the
retry and one-off upload paths. Loopback is allowed only behind an explicit
allow_loopback_federationflag on the received-storage config; private targets stay
denied. Enforcement is at dial time, not in URI syntax validation. Operators can opt the
received public-only clients into honoringHTTP_PROXY,HTTPS_PROXY, andNO_PROXY
viaocm_use_env_proxyon the received-storage config (off by default; the public-only
clients stay direct unless explicitly enabled).Both received transports, the OCM discovery and token-exchange client and the WebDAV round
tripper, share the explicit private ranges from allowed_federation_cidrs on the
received-storage config. -
Security #5834: Bound peer-controlled OCM JSON
Every OCM control-plane response body and peer-controlled error snippet is now capped at a 1
MiB default limit throughreadOCMBodyanddecodeOCMJSONhelpers, which read the body
once and returnErrResponseTooLargefor oversized input. This prevents
decode-after-drain regressions inNewShareandInviteAcceptedand bounds the existing
unsigned directory JSON at the same limit. -
Bugfix #5825: Init admin connection instead of mounting
The ceph admin connection was mounted instead of initialized, which worked when the key had
mounting permissions but it does not anymore -
Bugfix #5858: Set ceph user thread groups per thread
Syscall.Setgroups sets the groups for ALL threads of the process, which caused race
conditions when multiple users were using the same process. Similarly, when a user thread
finished, the original groups were restored on ALL threads.This is fixed by using unix.Setgroups, which only applies to the calling thread.
-
Bugfix #5840: A grpc or http block with no services is no longer rejected
Declaring a block that carries only settings, such as a [grpc] with nothing but
control_address, failed at startup with "grpc.services must be a map". The services key was
read with a type assertion, which also fails when the key is simply absent. A process whose only
grpc listener is its control channel can now start. -
Bugfix #5861: The lightweight scope for updating ocm shares
The lightweight scope for updating ocm shares was missing and lightweight users were unable to
process embedded shares. -
Bugfix #5804: Rjobs timeouts + registry issues
- Jobs that are killed because of an overlap are no longer seen as a failure and are not retried *
Daemons that cannot reach the gateway die * Failed resolutions are retried for a few times * The
scheduler reads only its own schedule keys instead of listing the whole bucket, which timed out
and stopped all periodic jobs
- Jobs that are killed because of an overlap are no longer seen as a failure and are not retried *
-
Bugfix #5816: Incorrect name for labelsprovider
The labels provider was incorrectly named labels and this caused an issue where the other
services could not find it via the service registry -
Bugfix #5791: Fixes for the EOSC Node
-
Bugfix #5811: Report folder size in public links
-
Bugfix #5817: Reconnect the service registry when publishing fails
A process whose NATS write failed marked its registry connection as lost and queued the write,
but only the watch path ever reconnected. A process with a healthy watcher therefore never
reconnected: it kept queueing its own heartbeats, silently, while its peers aged its nodes out
and stopped being able to resolve it, until the process was restarted. Writes now reconnect
too, so a NATS outage recovers on the next heartbeat, and a reconnect no longer leaves the
previous connection open. -
Bugfix #5849: Seperate the eos user and userid cache
Fixes a bug where an invalid value was stored due to the shared cache, essentially the routine
that updates missing values updated an incorrect key with a UserId instead of a User. -
Bugfix #5813: Make service names unique per transport
Currently, multiple services with the same name (e.g.
preferences), but using different
transports (httpvsgrpc) could conflict. This caused connections to be randomly to
either of the services. We now bind this to specific transports, so a service is queried with a
transport. -
Enhancement #5826: Add embedded processing failure mode
Embedded transfers may fail due to a number of reasons, an internal service could be down or the
remote repository could be unreachable. Instead of being stuck in the "Transferring" state,
shares are now put in the "Rejected" state so that this can be surfaced to the user in a reasonable
way. -
Enhancement #5692: Add the Reva Admin API
Reva gains an operator API for inspecting and safely operating a running deployment, driven by
a newreva admincommand. It is authenticated, audited, and off by default — it turns on only
where a process is configured with an admin group.At its core is a lightweight control channel that every reva process runs next to its normal
services. Through it the admin can reach a live service instance to read its state or ask it to
perform an operation (an "invocation"). Targets are resolved through the service registry,
so a single command can address one instance, every instance of a service, or the whole fleet,
and the results come back merged.With this an operator can see what the fleet is doing — list services and their health, read and
diff configuration, read or follow logs, trace a single request or user across services, dump
goroutines, and watch an instance's in-flight request activity — and act on it — set a
process's log level at runtime, take instances out of and back into rotation for maintenance,
drive the background jobs runner (list and enqueue jobs, trigger or cancel runs), and
impersonate a user.On the same host it needs no login: it is reached over a Unix socket and authorised by the caller's
OS identity. Remotely, an operator first steps up to a short-lived, admin-only token. -
Enhancement #5815: Discover app providers through the service registry
The app registry kept its own copy of the running app providers, built from a registration each
app provider pushed once, a few seconds after starting. That copy was keyed by address, so app
providers sharing one address collapsed into a single entry and all but one became unreachable
by name, and it was lost whenever the registry restarted, since nothing ever pushed again.App providers are ordinary reva services, so they are already in the service registry with a
reachable address and a liveness state. They now describe the app they serve in their node
metadata, and the app registry reads them from there. An app is identified by its app name rather
than by an address, it stops being offered when its providers go away, it comes back on its own
when they return, and an app served by several nodes is load balanced across them.As a consequence the app registry no longer has drivers: there is one implementation,
configured directly under[grpc.services.appregistry], and thestaticdriver
together with its[grpc.services.appregistry.drivers.static]section is gone.
AddAppProvidernow returnsUNIMPLEMENTED, and theapp_provider_urlsetting of the
app provider has been removed. -
Enhancement #5644: Implement LoginFlow (apptokens)
Add support for a new login flow, so that different sync clients can: - be registered and removed
individually - use a token per sync client, instead of relying on basic authThis uses NextCloud's /login/v2 flow.
-
Enhancement #5843: Create a home for lightweight accounts on login
When
lightweight_home_layoutis set in the gateway, a lightweight account that cannot
reach the folder at that path on login triggersCreateHomeon the storage provider holding
it. The EOS driver then runscreate_lightweight_home_hook, which creates the folder and
shares it with the account. -
Enhancement #5814: Allow LW accounts to use modern paths
Allows LW accounts to use the more modern path version without
/remote.php/ -
Enhancement #5860: Log the resource id on the access line
The owner alone says somebody else's data was reached, not which data. The resource id
distinguishes them, and unlike the share id it is already in hand. -
Enhancement #5859: Log who accessed a resource and who owns it
The HTTP log middleware runs outside authentication and sees neither value, so ocdav records
them on the context logger, which already carries the trace id. -
Enhancement #5768: Small cleanup of notification system
-
Enhancement #5833: Add shared OCM HTTP transport package
Introduces
pkg/ocm/clientwithTransportConfigand trusted/public-only HTTP client
constructors, centralizing the transport and address-policy logic previously inlined in
ocmd. The public-only dial guard refuses non-public targets and rejects IPv6 addresses
carrying a zone suffix, which would otherwise bypass the NAT64 and denied-prefix checks.
Public-only clients default to direct mode and ignore environment proxies; a service can opt
in to honoringHTTP_PROXY/HTTPS_PROXY/NO_PROXYvia the newUseEnvProxytransport
field. Trusted clients honor environment proxies regardless. Existingocmd.OCMClient
callers are unchanged.Public-only clients accept an explicit private-network exception list. The list is empty by
default, so private addresses stay denied until a caller installs prefixes parsed by
ParseFederationCIDRs. Trusted clients do not consult that list and keep their existing
proxy behavior. -
Enhancement #5741: Add periodic job to check orphaned shares
-
Enhancement #5771: Replace backup_job_id with backup_name in projects table
The backup_name column stores the project name plus a salt, used to identify the project in the
backup system. -
Enhancement #5841: Fail over to another node when a peer cannot be reached
A client resolved through the service registry used to be pinned to the node it resolved at, so a
call to a peer that had died failed even when other nodes of that service were serving. The caller
had to know about nodes to do anything about it.Clients now resolve a node per call. A call that fails because its node could not be reached is
sent to another node of the same service, up to three distinct nodes, within the caller's
deadline. Whether a call may be replayed is decided from what the connection was doing when it
broke: a connection that was not yet ready never handed the request over, so any call is moved on,
while a connection that broke mid-flight only replays reads, never a write.A node that could not be reached is then passed over for thirty seconds, so the calls that follow
start somewhere else instead of rediscovering the same dead peer, and is picked up again as soon
as it answers. This is tracked per process, because a node re-registers itself as ready on every
heartbeat: the failure worth reacting to — a peer that is healthy to the registry but
unreachable from here — is one only the calling process can observe.None of this is visible to the caller, which still asks for a client and makes a call.
-
Enhancement #5665: Add a service registry for service discovery
Reva services now find each other through a registry instead of hard-coded addresses. Each
revad self-registers its loaded services, and inter-service calls resolve a peer by kind
through a Clients resolver, with no address passed or seen by the caller. The HTTP data path
(data gateway and data provider) is discovered the same way through a generic endpoint lookup,
with the data provider selected by mount_id affinity. The registry is backed by an in-memory
store by default or by NATS JetStream for a shared fleet view, with a liveness state machine that
skips quiet or dead nodes. The per-peer address keys (gatewaysvc, the *_svc keys,
[shared].datagateway, and data_server_url) are removed from configuration. -
Enhancement #5746: Implement shallow reconcile job
-
Enhancement #5780: Add a takeout service to export a user's home directory
Users can now request an export of their whole home directory, which runs as a background job
that streams their files into one or more archives and emails the download links once ready.
Expired exports are removed by a periodic cleanup job. The archiver service now shares its core
with the takeout job through the new bundler package. -
Enhancement #5801: Cache for app passwords used by sync client
This ensures we dont need to do a DB call for every connection of a sync client