59 Commits
Author SHA1 Message Date
Ben McClelland f51367853d fix: skip excluded directories and reserve their keys
Follow-up to #2514, which added PosixOpts.ExcludeDirs (--exclude-dirs,
VGW_EXCLUDE_DIRS) so the listings can skip filesystem control
directories such as ZFS's .zfs.

The walks matched skipped names against every directory entry, files
included. In WalkVersions, returning fs.SkipDir for a file skips the
rest of its parent directory, so a regular file named like an excluded
directory (for example an object "d/.zfs") made ListObjectVersions drop
every sibling that sorted after it. Walk hid the file itself.
Previously only .sgwtmp was skipped, which clients can't create, but
excluded names are chosen by the operator and any client can PUT such a
key. Walk and WalkVersions now skip only directories, so a file with an
excluded name is listed like any other object.

Excluded names were also not reserved: requests could still read and
write objects under an excluded directory that the listings never show.
On ZFS, .zfs is reachable by name even with snapdir=hidden, so GetObject
could read snapshot contents. That bypasses bucket policies scoped to a
key prefix and exposes data that was deleted or overwritten since the
snapshot was taken. On other filesystems, objects written there were
orphans that no listing reports. validateObjectName now rejects, with
ReservedObjectKey, any key that has an excluded name as a directory at
any depth, ignoring case and after resolving "..", "." and repeated
slashes. Every object operation already calls it. A directory-object
key (trailing slash) counts its last element as a directory; a plain
key with an excluded last element is still a valid file. The new
ErrExcludedObjectKey keeps the ReservedObjectKey code with a description
that fits excluded directories, leaving the .sgwtmp error unchanged.
Nothing changes when ExcludeDirs is empty.

posix.New now also rejects "." and ".." as excluded names, since they
can never match a directory entry and would silently do nothing.
2026-10-20 18:17:44 -07:00
Tung Lam e63998fb31 fix: log the client IP from a trusted proxy header
Behind a reverse proxy the request log and the S3, admin, website and WebUI
access logs record the proxy's address instead of the client's. Add a
client-ip-header option that takes the logged address from X-Forwarded-For or
X-Real-Ip. It is off by default, so an existing deployment logs exactly what it
logged before.

The header is only honoured when the connecting peer is listed in the new
trusted-proxies list of IPs and CIDRs. Without that, the value is whatever the
client sent: nginx's standard
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for appends to a
client-supplied header, leaving the client's own address leftmost.
X-Forwarded-For is walked right to left, skipping the listed proxies, so the
first unlisted address is the client and a forged leftmost entry is never
reached; the two-proxy case from #2243 works once both proxies are listed.
Every header line is walked (a proxy may add its own line instead of
appending), ip:port entries are accepted, and a request from an unlisted peer
keeps the socket address. Setting the header with an empty trusted-proxies list
fails startup rather than silently trusting every peer.

X-Real-Ip reads the last header line, so a proxy that adds a line rather than
replacing the client's is the one that speaks. An address carrying an IPv6 zone
is rejected: the zone is free text that the space-delimited access log would
write verbatim, shifting every field after RemoteIP. When every hop in
X-Forwarded-For is a trusted proxy, the leftmost hop is logged, as nginx's
real_ip_recursive does, since the socket peer is then the nearest proxy. The
trusted-proxies list accepts the entry "unix" to trust the peer of a listener
bound to a unix socket path, which fasthttp reports as 0.0.0.0.

The resolver, middleware, log tag and parsers live in internal/clientip, shared
by s3api, iamapi, website and webui; s3api/utils re-exports them for the S3
callers, so the standalone IAM service no longer pulls in the S3 side. On this
branch go list -deps ./iamapi drops from 375 to 299 packages, against 298 on
main.

ctx.IP() is unchanged and still returns the socket peer address, because it
feeds aws:SourceIp in IAM policy conditions and SourceIP in policy evaluation;
only the address written to the logs and S3 event records comes from the
header.

Fixes #2243.
2026-10-16 00:51:53 +00:00
Ben McClellandandGitHub 485b4f22d7 Merge pull request #2466 from versity/ben/reject-sse-c
feat: validate SSE-C headers and reject SSE-C in posix and azure
2026-10-03 16:24:06 -07:00
Ben McClelland c354e1a2d3 feat: validate SSE-C headers and reject SSE-C in posix and azure
Add request plumbing for server-side encryption with customer-provided
keys (SSE-C) and stop silently ignoring it on backends that cannot
honor it.

Previously SSE-C headers were dropped before reaching the backend, so
posix stored the data unencrypted and returned success, and later
reads without the key succeeded. Clients believed their data was
encrypted when it was not. Partial or malformed SSE-C header sets were
also accepted instead of failing with 400 as S3 does. Rejecting SSE-C
explicitly is the safe behavior until posix implements it, and azure
cannot faithfully map SSE-C onto customer-provided keys.

This addresses part of #2193: invalid/partial SSE-C headers now fail
with 400. Requiring SSE-C headers on reads of SSE-C objects depends on
posix SSE-C support and remains open.

The changes also reject unsupported SSE-S3, SSE-KMS, and DSSE-KMS
requests instead of silently accepting them. And enforcea TLS for
SSE-C by default, with --disable-sse-c-tls-enforcement as the opt-out
in case the deployment handles TLS in front of the gateway.
2026-10-03 10:04:03 -07:00
Ben McClelland e448a8ae20 feat: expose POSIX I/O buffer size to scoutfs options
ScoutFS delegates buffered object transfer paths to the
POSIX backend, so expose IOBufferSize in ScoutfsOpts and
pass it through to PosixOpts. This lets operators tune
transfer buffering for ScoutFS instead of being limited
to the default.
2026-10-02 14:19:56 -07:00
Ben McClelland 0c79ae7e23 feat: add directio option for scoutfs backend 2026-09-29 09:38:12 -07:00
Ben McClelland 5847f0489a fix: update the example systemd configs with latest options 2026-09-27 13:01:48 -07:00
niksis02 966a6a8650 feat: admin API path prefix, Helm WebUI prefixes and separate IAM storage
Closes #2322

The admin API could not be served under a path prefix. Admin requests are SigV4-signed over the full path, so a reverse proxy or Gateway API route cannot strip a prefix before forwarding. That made it impossible to serve the WebUI and the admin API under one hostname. The new `--admin-path-prefix` (`VGW_ADMIN_PATH_PREFIX`) option mounts the admin routes under a single-segment prefix such as `/admin`, on `--admin-port` or, when that is unset, on the S3 port. Admin clients include the prefix in their endpoint URL, which the admin CLI and the WebUI already support.

The prefix is limited to unreserved characters, because clients and the gateway encode other characters differently when signing. When the admin API shares the S3 port, the prefix must also differ from `--webui-s3-prefix`, otherwise the WebUI mount answers the admin requests. Auto-detected WebUI admin gateway URLs and the startup banner now include the prefix. The admin routes served on the S3 port now reuse `S3AdminRouter` instead of a duplicated route list. This also stops the standalone admin server from recording bucket creation under the `ActionAdminListBuckets` action.

The Helm chart now exposes `webui.pathPrefix`, `webui.s3Prefix` and `admin.pathPrefix`. The WebUI gateway lists are also passed when only `webui.s3Prefix` is set, since the WebUI hosted on the S3 port does not require `webui.enabled`.

Internal IAM data can now live on its own volume. `iam.dir` sets the IAM directory, and `iam.persistence` creates or references a dedicated PVC when `iam.enabled` is true and `iam.type` is `internal`. Otherwise IAM data stays in the `iam` subdirectory of the backend data volume, so existing releases are unaffected.

The chart now rejects overlapping storage directories. `iam.dir` must be an absolute path outside `/mnt/data`, `gateway.backend.sidecarDir` and `gateway.backend.versioningDir`, and those three directories must not overlap each other. Deleting a bucket removes `<dir>/<bucket>` from the sidecar and versioning directories, so with nested directories, deleting a suitably named bucket could wipe IAM accounts, object versions or the entire backend data directory.
2026-09-16 23:09:14 +04:00
niksis02 1c1272c8a5 feat: add per-provider OIDC discovery URL override
`AssumeRoleWithWebIdentity` always fetched a provider's discovery document from `<provider url>/.well-known/openid-configuration`, so an identity provider that issues tokens naming a public issuer while serving its metadata and keys on a cluster-internal path could not be used: reaching it meant relaxing the endpoint checks for every registered provider. `--oidc-discovery-url` moves that one fetch to an operator-named endpoint, which is how keys can be looked up over an optimized private path while the tokens themselves stay verifiable from the public internet against the issuer alone, as the JWT spec requires.

The flag takes `<provider url>=<discovery url>` pairs, can be repeated once per provider, and is also read from `VGW_IAM_OIDC_DISCOVERY_URLS` as a comma-separated list; the Helm chart exposes the same list as `iamServer.oidc.discoveryUrls`. The discovery URL is fetched exactly as written, so it must carry the `/.well-known/openid-configuration` path when the provider serves it there. A malformed pair is rejected at startup rather than at the first assume-role call.

Only the fetch moves. The provider URL is still what a token's `iss` claim is matched against, the fetched document's own `issuer` field must still equal it, and the key set still comes from the `jwks_uri` that document publishes. A configured discovery endpoint is named by the operator at startup rather than by a request, so it and the `jwks_uri` it publishes waive the private-address check for that provider's fetch chain only, without `--oidc-allow-private-endpoints` and its far broader effect on every other provider. Transport rules are unchanged: a plaintext discovery URL still requires `--oidc-allow-insecure-transport`.

Thumbprint auto-fetch follows the override and pins the discovery endpoint's certificate chain, since that is the host every later fetch is verified against.
2026-09-14 15:12:51 +04:00
Ben McClelland 9c363b280a fix: make conditional publish lock modes explicit
Conditional PUTs require a lock primitive that excludes competing gateway
processes sharing a backend filesystem. A successful flock call does not prove
that property: some clustered filesystem configurations accept flock but scope
it to one node, silently leaving cross-gateway check-and-publish races open.

Add an object-lock mode that lets operators select flock or fcntl for
filesystems where that primitive is cluster-coherent, local for the existing
per-process behavior, or none to reject conditional writes with NotImplemented.
Keep the legacy disable flag as an alias for local.

Shared lock modes now verify the selected primitive on the root lock filesystem
during startup and fail closed if it cannot be used. Runtime lock failures no
longer silently downgrade to process-local exclusion. The startup check cannot
establish cross-node coherence, so that remains an explicit operator
requirement.

ScoutFS defaults to none since posix locks are not cluster consistent, but
allow setting local for single node deployments.

Fixes #2351
2026-09-10 19:01:56 -07:00
niksis02 658c37907d feat: add OIDC endpoint relaxations for private/isolated networks
Closes #2364

`AssumeRoleWithWebIdentity` only ever trusted an `OIDC` provider reachable over verified `https`, at a publicly routable address, on the implicit `:443`. That posture is right for an internet-facing IdP but rejects every address an internal one can have, so a `SPIFFE/SPIRE` OIDC discovery provider in the same cluster — or as a sidecar in the same pod — could never be registered, let alone verified against, and no setting could express "this private address is the IdP".

Two opt-in flags on `versitygw iam`, both off by default:

`--oidc-allow-private-endpoints`
Permit a provider `Url` resolving to a loopback/private/link-local address, and an explicit port. Transport is unchanged: still `https`, still fully verified (a self-signed in-cluster cert is trusted the way AWS documents, through `ThumbprintList`).

`--oidc-allow-insecure-transport`
Additionally permit plaintext `http` provider URLs, discovery/JWKS endpoints and redirects, and drop TLS verification (`thumbprint` pinning included) for `https` ones.

Both apply uniformly to the thumbprint auto-fetch at `CreateOpenIDConnectProvider` time and to the discovery-document plus `JWKS` fetch at `AssumeRoleWithWebIdentity` time. Neither weakens anything past the endpoint: signature verification, issuer matching, audience and trust policy evaluation are untouched, and the DNS-resolve-once/dial-the-resolved-IP shape stays in place so a rebind still cannot redirect a connection.

An `http` provider keeps its scheme in its stored `Url`, `ARN` and `iss` matching, rather than being stripped like an `https` one — otherwise `"http://host"` and `"https://host"` would collapse onto a single ARN and storage key and each could satisfy the other's trust policy. It also stores an empty `ThumbprintList` rather than failing: a plaintext provider presents no certificate to thumbprint.

Helm: `iamServer.oidc.{allowPrivateEndpoints,allowInsecureTransport}`, alongside `disableThumbprintAutofetch` moved into the same block (the flat `iamServer.disableOidcThumbprintAutofetch` stays honored). Chart `0.4.1 -> 0.4.2`.

The WebUI's create-provider form no longer rejects `http` URLs and ports client-side; it cannot see the service's settings, so those two rules are left to the server, whose error surfaces as a toast like any other.
2026-09-08 16:30:37 +04:00
Ben McClellandandGitHub 4a22b6d9d7 Merge pull request #2348 from versity/ben/access-log-stdout
feat: support admin/access logs on standard streams
2026-09-03 07:55:46 -07:00
Ben McClelland 5f9041ff5f feat: support admin/access logs on standard streams
The access-log and admin-access-log options now accept stdout, stderr, or - for
stdout in addition to file paths. Standard stream destinations are kept open
during shutdown and SIGHUP handling, while file destinations continue to support
normal reopen behavior for log rotation. CLI help, embedded config comments, and
the example configuration describe the new destination values.

Fixes #2245
2026-09-02 14:21:28 -07:00
Ben McClelland c9e26b58c4 feat: add standalone iam service to systemd config setup 2026-09-02 14:05:30 -07:00
Ben McClelland 9a73e222ca fix: harden posix conditional publish locking
Fail closed on unexpected advisory-lock errors instead of silently reducing
cross-process exclusion to a local mutex. Make local publish-slot waits honor
request cancellation. Move version snapshots under the publish lock so
concurrent versioned PUTs preserve publication order. Add regression coverage
for canceled lock waiters.

Also add an option to disable flock files and only rely on in process locking.
2026-08-31 19:00:00 -07:00
Kyd CaoandBen McClelland 45a532e6a6 feat: add configurable file permissions for new objects
Replace the hardcoded 0644 defaultFilePerm with a NewFilePerm option on
the posix and scoutfs backends, exposed as the --file-perms flag and
VGW_FILE_PERMS env var alongside the existing dir-perms option.

The mode passed to open() is masked by the process umask, so the
O_TMPFILE path now chmods explicitly to match the CreateTemp fallback
path and give new objects the configured mode regardless of umask.
2026-08-28 08:51:03 -07:00
niksis02 ab2b816633 feat: add STS web identity federation, IAM policy Condition support, and access control enforcement
Implements the `AssumeRoleWithWebIdentity` and `GetCallerIdentity` STS actions, letting callers exchange an external OIDC token for temporary credentials scoped to an IAM role. Token handling covers JWT claim parsing, issuer/audience resolution (including `azp` override semantics), JWKS fetching and caching with `singleflight`-deduplicated refresh, and rate-limited forced refresh on unrecognized `kid` values. OIDC provider thumbprint fetching now performs a real TLS handshake verified against the system trust store and the provider hostname (previously `InsecureSkipVerify`), since the observed certificate is persisted as a long-lived trust anchor rather than used once and discarded; all discovery-document and JWKS fetches go through an SSRF-safe HTTP client with bounded redirects and response size.

Adds policy `Condition` block evaluation, supporting `String`, `Numeric`, `Date`, `Bool`, `BinaryEquals`, and `IpAddress` operators along with their `IfExists`/`Not` variants and `ForAllValues`/`ForAnyValues` set qualifiers, plus policy variable substitution (e.g. `${aws:username}`) in supported operators. Adds identity-based inline policy evaluation and a new IAM authorization middleware that authorizes each request against action, resource, and condition context together, applying the session-policy-intersects-role-policy semantics for assumed-role sessions.

Adds a new debug logger `--log-level` flag (`silent`/`debug`/`unsafe`), along with a tree-based XML masker that redacts secrets and tokens at the property level in logged request/response bodies instead of skipping the whole body. The old `--debug/VGW_DEBUG` flag is kept as a deprecated alias for `--log-level=debug`, printing a console warning that points users at `--log-level` for finer-grained control.

Fixes a Vault storage bug where CAS (check-and-set) writes always read the current document version as 0 because `kvVersion` asserted metadata as `float64` while the Vault client actually returns `json.Number`, causing every write past the first to be rejected as a concurrent modification. Also adds a constant-time `SecureCompare` for signature/token comparisons in sigv4 auth.

Adds an integration test suite (`iam_access_control.go`) covering IAM access control across user, role, and session identities.
2026-08-25 01:06:25 +04:00
Ben McClelland 29256f0ab5 feat: add optional data-integrity ETag mode for posix/scoutfs
Introduce an opt-in mode that derives ETags from checksums instead of relying on
MD5 assumptions, aligning with AWS-compatible scenarios where ETag should be
treated as an opaque identifier rather than a content-MD5 signal.

This can significantly reduce CPU load on the server to disable MD5 checksums
when we are already validating data with other checksums.

This change adds --data-integrity-etag and VGW_DATA_INTEGRITY_ETAG support for
both posix and scoutfs backends. In this mode, PUT object ETags, multipart part
ETags, and completed multipart object ETags are checksum-derived.
2026-07-31 14:58:21 -07:00
Ben McClelland 062bf0bf47 feat: add best-effort O_DIRECT support for posix put/get-object put-part
This change introduces an opt-in O_DIRECT mode for POSIX object data paths while
keeping behavior safe and predictable across different filesystems and kernel
constraints. We now use direct I/O when available and beneficial, but preserve
correctness by falling back to buffered I/O when runtime read behavior indicates
alignment or capability mismatches.

The implementation keeps fast paths available for full-object reads and
descriptor-to-descriptor copy operations so kernel-level optimizations can still
be used where possible. At the same time, it avoids global assumptions from
single runtime failures and performs fallback at the stream level so requests
can continue successfully without broad feature disablement.
2026-07-31 13:29:48 -07:00
Ben McClelland dbc9bb1b08 fix: update example config with recent options 2026-07-02 20:47:38 -07:00
Ben McClelland 9db2c9c702 feat: add configurable default ETag for files without metadata
When versitygw serves files that were placed on the filesystem outside
of the gateway, those files have no stored etag attribute and are
served with an empty ETag. This causes problems for S3 clients that
rely on ETags being non empty.

The new --default-etag flag (VGW_DEFAULT_ETAG) lets operators specify
a fallback ETag value returned for any object that lacks a stored etag
attribute, making pre-existing filesystem data behave more predictably
under S3 workloads without requiring a metadata migration.
2026-07-02 18:09:27 -07:00
Marc Singerandniksis02 375c2764d5 Add website integration tests and remove NotImplemented stubs
Replace PutBucketWebsite, GetBucketWebsite, DeleteBucketWebsite
NotImplemented test stubs with comprehensive integration tests covering:
- non-existing bucket errors
- validation (empty suffix, suffix with slash, invalid protocol, mutual
  exclusion of RedirectAllRequestsTo and IndexDocument)
- successful put/get round-trips for both index+error and redirect-all configs
- delete idempotency and verification

Signed-off-by: Marc Singer <marc@singer.gg>

Add error document serving, routing rules, and integration tests

Implement Features 1 and 2 of S3 static website hosting:

- WebsiteErrorDocument controller wrapper intercepts 4xx errors on
  website-enabled buckets and serves the configured error document or
  evaluates post-request routing rules (error code match redirects)
- ResolveWebsiteIndex middleware now caches parsed WebsiteConfiguration
  in context, handles RedirectAllRequestsTo, evaluates pre-request
  routing rules (key prefix match redirects), and rewrites directory
  keys for index document
- MatchPreRequestRule and MatchPostRequestRule methods on
  WebsiteConfiguration for routing rule evaluation
- 14 unit tests for routing rule matching
- 7 integration tests covering error document, routing rules,
  redirect-all, and index document behavior

Signed-off-by: Marc Singer <marc@singer.gg>

Add separate website hosting endpoint with virtual-host routing

Signed-off-by: Marc Singer <marc@singer.gg>

Support catch-all mode for website endpoint when --website-domain is omitted

Signed-off-by: Marc Singer <marc@singer.gg>
2026-06-10 12:41:51 +04:00
Ben McClelland 0dc074acbf feat: add --socket-perm option for UNIX socket file permissions
Add a --socket-perm flag (VGW_SOCKET_PERM env var) to control the
file-mode permissions on file-backed UNIX domain sockets. This allows
operators to limit access permission without relying on process umask.
The option applies to S3, admin, and WebUI sockets and has no effect
on TCP/IP addresses or Linux abstract namespace sockets.

Fixes #2010
2026-04-20 19:07:08 -07:00
Ben McClelland 9816c2fdb3 fix: add gcs compatibility flag to fix s3proxy GCS SigV4 signature mismatch
The AWS SDK v2 includes Accept-Encoding in SigV4 signed headers
which causes GCS to return a SignatureDoesNotMatch error because
GCS rewrites that header internally before verifying the signature.

Add a --gcs-compatibility / VGW_S3_GCS_COMPATIBILITY option for the s3proxy
backend that injects two Smithy finalize-layer middlewares: one removes
Accept-Encoding from the request immediately before the Signing step, and
a second restores it after signing so the header is still sent on the wire.

see: https://github.com/aws/aws-sdk-go-v2/issues/1816

This can be removed once GCS fixes this incompatibility.
2026-04-14 10:53:26 -07:00
Ben McClelland 14b0aabb0b feat: add cli option to generate shell auto completion
The urfave/cli/v2 has built-in auto-completion support for bash.
This enables generating the auto completions with a cli option
that can be added to environment setup scripts.

Also adding some distro support scripts for rpm and deb for the
auto completion setup.

To enable auto completion in zsh, this still needs to be added
to user .zshrc:
fpath=(/usr/share/zsh/site-functions $fpath)
autoload -Uz compinit && compinit

Fixes #2015
2026-04-13 19:17:56 -07:00
niksis02 48bfa9f4cf fix: correct HeadObject restore status for offline objects in scoutfs
Fixes #2030

When an object has offline blocks, the restore status was incorrectly set to `ongoing-request="false"` instead of omitting the header entirely, which causes s3 clients fail on parsing the x-amz-restore header.
Remove the incorrect `stageNotInProgress` constant and simplify the `requestOngoing` initialization to reflect the correct default.
2026-04-09 19:15:31 +04:00
niksis02 bbe246e8ec fix: enforce 5gb copy source object size threshold.
Fixes #1896

Enforces the S3 `5 GiB` copy source size limit across the posix and azure
backends for `CopyObject` and `UploadPartCopy`, returning `InvalidRequest` when
the source object exceeds the threshold.

The limit is now configurable via `--copy-object-threshold`
(`VGW_COPY_OBJECT_THRESHOLD`, default 5 GiB).
A new `--mp-max-parts flag` (`VGW_MP_MAX_PARTS`, default `10000`) has been added to make multipart upload parts number limit configurable.

No integration test has been added, as GitHub Actions cannot reliably
handle large objects.
2026-03-31 22:44:03 +04:00
Ben McClellandandGitHub 6e13be6984 Merge pull request #1945 from versity/ben/webui-s3-port
feat: option to host webui on s3 port
2026-03-10 08:57:01 -07:00
Ben McClelland a152f29113 feat: option to host webui on s3 port
This adds the webui-s3-prefix option to specify a prefix and host
the webui on the same port as the s3 service. Like the health
endpoint, this will mask any bucket with the same name as the
webui prefix.

The benefit of hosting this on the same interface as the s3
service is no longer needing the CORS headers for the browser
access if the webui and s3 access are on the same IP:PORT.
2026-03-10 08:20:19 -07:00
Ben McClelland 8795c15621 feat: s3proxy default to credential chain with optional anonymous access
When access/secret are not provided, let AWS SDK v2 resolve credentials
from the default provider chain (env vars, IRSA, ECS/EC2 roles, etc.)
instead of forcing anonymous credentials.

Add an explicit anonymous credentials option for s3 proxy to force
backend anonymous access.

Fixes #1955
2026-03-09 17:41:50 -07:00
Ben McClelland 9a3ccf68f3 feat: add option to change webui path prefix
New option webui-path-prefix that specifies a prefix for the
webui endpoint. The default is the old behavior at the root.
2026-03-09 16:45:16 -07:00
Ben McClelland 710003f341 feat: add unix domain socket listener support to port option
This adds the ability to specify unix domain socket paths for the
service listener with the --port <path> option. Where <path> can
be either a path to a file in a filesystem or prefixed with @ for
an abstract socket name.

Anything not matching the <host>:<port> pattern in the --port
option will be considered a socket filename.
2026-03-07 22:05:41 -08:00
Ben McClelland fbff3f6365 fix: update deprecated StandardOutput/StandardError type
Fix warnings from newer systemd:
Standard output type syslog is obsolete,
 automatically updating to journal.

This updates the stdout/stderr to journal output type which is
what is getting set anyways after the syslog type has been
deprecated.

No expected behavior change with this other than quieting
warnings.
2026-03-06 08:39:26 -08:00
niksis02 5ae791b154 feat: configuration option to disable ACLs
Closes #1847

This PR introduces a global optional gateway CLI flag `--disable-acl` (`VGW_DISABLE_ACL`) to disable ACL handling. When this flag is enabled, the gateway ignores all ACL-related headers, particularly in `CreateBucket`, `PutObject`, `CopyObject`, and `CreateMultipartUpload`.

`GetBucketAcl` behavior is unchanged simply returning the bucket ACL config.
There's no change in object ACL actions(`PutObjectACL`, `GetObjectACL`). They return a`NotImplemented` error as before.

A new custom error is added for PutBucketAcl calls when ACLs are disabled at the gateway level. Its HTTP status code and error code match AWS S3’s behavior, with only a slightly different error message.

In the access-control checker, ACL evaluation is fully bypassed. If ACLs are disabled only the bucket owner gets access to the bucket and all grantee checks are ignored.

The PR also includes minor refactoring of the S3 API server and router. The growing list of parameters passed to the router’s Init method has been consolidated into fields within the router struct, initialized during router construction. Parameters not needed by the S3 server are no longer stored in the server configuration and are instead forwarded directly to the router.
2026-02-27 20:04:13 +04:00
Ben McClellandandGitHub 744cf2491d Merge pull request #1884 from versity/ben/s3proxy-disable-data-integrity
feat: add option to disable s3proxy client data integrity checks
2026-02-24 08:33:56 -08:00
Ben McClelland e2821fc855 feat: add option to disable s3proxy client data integrity checks
AWS introduced a relatively newer option for data integrity checks
that not all non-AWS server support yet. See this for mmore info:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html

This change adds a new option: disable-data-integrity-check
to disable the data integrity checks in the client sdk for the
servers that may not yet support this. Use this only when the s3
service for the proxy does not support the data integrity features.

Fixes #1867
2026-02-21 11:49:20 -08:00
Ben McClelland e7a1231e77 feat: add cli options to specify webui gateway/admin listing
New cli options added:
webui-gateways - override auto-detected S3 gateway URLs for WebUI
webui-admin-gateways - override auto-detected admin gateway URLs
 for WebUI

These also accept env vars VGW_WEBUI_GATEWAYS and
VGW_WEBUI_ADMIN_GATEWAYS for the options.

When setting these, this will override the url auto-detection for
the webui service urls dropdown options. By default, the gateway
auto-detects URLs based on the configured port settings. Use these
options to specify custom URLs when the auto-detected values are
incorrect (e.g., when running behind a reverse proxy or load
balancer). Multiple URLs can be specified with repeated options
or a comma-separated list with the environment variables.
for example:
--webui-gateways https://s3.example.com \
--webui-gateways http://192.168.1.100:7070
or
VGW_WEBUI_GATEWAYS=https://s3.example.com,http://192.168.1.100:7070

The gateway will validate the provided URLs with warnings for any
invalid URL specified. The gateway will terminate if these options
are set but contain no valid URLs.

Also added sorting to the auto-detected URLs so that localhost
URLs will be last in the list, since these will not likely work
on remote systems. The specified lists when provided are left
in the order they are specified to allow admins to determine
dropdown list ordering.

Fixes #1851
2026-02-21 11:35:01 -08:00
Ben McClelland 599ab1b743 feat: add multi-address listener for s3/admin/webui
This allows specifying the following options more than once:
port, admin-port, webui

or using a comma-separated list for the env vars:
e.g., VGW_PORT=:7070,:8080,localhost:9090

This will also expand multiple interfaces from hostnames, for example
"localhost" in this case would resolve to both IPv4 and IPv6 interfaces:
localhost has address 127.0.0.1
localhost has IPv6 address ::1

This updates the banner to reflect all of the listening interfaces/ports,
and starts the service listener on all requested interfaces/ports.

Fixes #1761
2026-02-17 14:16:43 -08:00
Andrii BrataninandGitHub 9c212997dc feat: allow anonymous access for s3proxy backend
* Update client.go to support anonymous S3 access

* Update s3.go to make access and secret parameters optional

* Update example.conf for more clear S3 access and secret usage

Fixes #1836
2026-02-11 11:03:02 -08:00
Ben McClelland 68d7924afa feat: add web-based UI for S3 object management and admin operations
Implements a web interface for VersityGW with role-based access:
- Object explorer for all users to browse, upload, and download S3 objects
- Admin dashboard showing system overview and gateway status
- Admin-only user management for IAM user administration
- Admin-only bucket management for creating and configuring S3 buckets
- User authentication with automatic role-based page access

The web UI is disabled by default and only enabled with the --webui or
VGW_WEBUI_PORT env options that specify the listening address/port for
the web UI server. This preserves previous version behavior to not enable
any new ports/services unless opted in.

Login to the web UI login page with accesskey/secretkey credentials as
either user or admin account. UI functionality will auto detect login
role.

Regular users have access to the object explorer for managing files within
their accessible buckets. Admins additionally have access to user and bucket
management interfaces. The web UI is served on a separate port from the S3
server and integrates with existing S3 and Admin API endpoints.

All requests to the S3 and Admin services are signed by the browser and sent
directly to the S3/Admin service handlers. The login credentials are never
sent over the network for security purposes. This requires the S3/Admin
service to configure CORS Access-Control-Allow-Origin headers for these
requests.
2026-01-19 14:22:12 -08:00
Ben McClelland 3c3e9dd8b1 feat: add project id support for scoutfs backend
The scoutfs filesystem allows setting project IDs on files and
directories for project level accounting tracking. This adds the
option to set the project id for the following:
create bucket
put object
put part
complete multipart upload

The project id will only be set if all of the following is true:
- set project id option enabled
- filesystem format version supports projects (version >1)
- account project id > 0
2025-11-14 15:36:10 -08:00
madic-creates 2dd442c24d Allow self-signed certificates 2025-10-17 17:37:35 +02:00
Ben McClelland 4c3965d87e feat: add option to disable strict bucket name checks
Some systems may choose to allow non-aws compliant bucket names
and/or handle the bucket naem validation in the backend instead.
This adds the option to turn off the strict bucket name validation
checks in the frontend API handlers.

When frontend bucket name validation is disabled, we need to do
sanity checks for posix compliant names in the posix/scoutfs
backends. This is automatically enabled when strict bucket
name validation is disabled.

Fixes #1564
2025-10-08 14:34:52 -07:00
Ben McClelland 7aa733ae9e feat: use docker entrypoint for flexible env var docker config
Using Docker ENTRYPOINT should allow for configuration of running
versitygw within Docker container similar to how the systemd
service is setup with environment variables.

This also adds the backends azure and plugin to the acceptable
backend options for both docker and systemd.

Fixes #1335
2025-10-03 09:34:51 -07:00
Ben McClelland 1eeb7de0b6 feat: add versioning dir option to scoutfs backend
This adds the same versioning dir option that is found in the
posix backend to scoutfs backend. Functionality is the same.
2025-08-26 11:20:35 -07:00
Ben McClelland 36d2a55162 feat: add rabbitmq s3 event notification support
This adds support for rabbitmq publisher for s3 events. The
mechanics are similar to kafka and nats, but will use the amqp
protocol to send bucket events.
2025-08-13 12:46:57 -07:00
Ben McClelland e2905b6880 feat: update example service config for virtual host option 2025-05-23 15:26:03 -07:00
Ben McClelland f0a1184459 feat: add option to disable use of O_TMPFILE
O_TMPFILE can fail if the location we need to link the final
file is not within the same filesystem. This can happen if
there are different filesystem mounts within a bucket or if
using zfs nested datasets within a bucket.

Fixes #1194
Fixes #1035
2025-04-16 10:49:00 -07:00
Ben McClelland 31e748277f chore: update example config with scoutfs VGW_DISABLE_NOARCHIVE 2025-03-10 16:14:37 -07:00
Ben McClelland 565000c3e7 chore: update example service config for directory perms option
This was missed when we added an option for setting directory permissions
different than the default 0755. This adds the VGW_DIR_PERMS option and
description to the example.conf file.
2024-10-28 09:33:50 -07:00