Commit Graph
2804 Commits
Author SHA1 Message Date
dependabot[bot]andGitHub 3742fa6571 chore(deps): bump github/codeql-action from 4.37.9 to 4.38.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.37.9 to 4.38.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v4.37.9...v4.38.0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 21:08:00 +00:00
Ben McClellandandGitHub 9eea7dabe9 Merge pull request #2386 from versity/sis/oidc-discovery-urls
feat: add per-provider OIDC discovery URL override
2026-09-14 11:22:44 -07:00
Ben McClellandandGitHub fd8de62c6f Merge pull request #2349 from versity/test/website_redirect
Test/website redirect
2026-09-14 08:06:02 -07: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
Luke McCrone 642b65f1f1 test: website redirect test, multipart upload util cleanup, install updates 2026-09-13 11:36:46 -03:00
Ben McClellandandGitHub f002073a07 Merge pull request #2385 from crsolucoes/webui-upload-progress-indicator
webui: show upload progress in the Explorer
2026-09-11 17:09:48 -07:00
b1f8cea9f6 webui: show upload progress in the Explorer
Uploading a large file through the Explorer gives no feedback at all
today — the toast only fires once at the start ("Uploading...") and
once at the end ("Uploaded"), so a multi-GB multipart upload looks
completely stalled to the user for however long it actually takes,
with no way to tell it apart from a hung connection.

Adds a small persistent widget (bottom-right, in the same visual
style as the existing toasts) that tracks bytes uploaded / total
bytes across the whole upload batch, updating after each part of a
multipart upload completes (or once a small single-PUT file
finishes). It disappears once the batch is done, right before the
existing success/failure toast.

No changes to any upload/network behavior — this only observes
progress already being made by the existing uploadMultipart/putObject
calls and renders it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:05:02 -07:00
Ben McClellandandGitHub a0a07ba10b Merge pull request #2387 from versity/test/mc_hotfix
test: mc hotfix
2026-09-11 15:50:23 -07:00
Luke McCrone d13b5dfc62 test: mc hotfix 2026-09-11 19:23:11 -03:00
Ben McClellandandGitHub 678ce3738e Merge pull request #2384 from versity/sis/azure-accessdenied-err-mapping
fix: map azure `AuthorizationPermissionMismatch` to `AccessDenied`
2026-09-11 07:59:53 -07:00
Ben McClellandandGitHub 843bed4380 Merge pull request #2359 from versity/ben/lock-options
fix: make conditional publish lock modes explicit
2026-09-11 07:57:08 -07:00
niksis02 859f81fb5d fix: map azure AuthorizationPermissionMismatch to AccessDenied
Originated from #2302

When the Azure credential is valid but its RBAC role does not grant a data action, Azure answers with `403 AuthorizationPermissionMismatch`. This code had no mapping, so the gateway returned `500 InternalError` to the S3 client. A common case is `CompleteMultipartUpload` under a managed identity with `Storage Blob Data Contributor`: the Get Blob Tags call on the `.sgwtmp` multipart staging blob needs `blobs/tags/read`, which that role does not include.

`azErrToS3err` now maps `AuthorizationPermissionMismatch` to `AccessDenied`. `parseMpError` used to return the raw Azure error for every code except `NoSuchKey`, so the new mapping never reached the multipart paths. It now also passes `AccessDenied` through, and the client gets a `403 AccessDenied` instead of a `500 InternalError`.
2026-09-11 16:41:41 +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
Ben McClellandandGitHub 8d57a38e37 Merge pull request #2377 from RaduBerinde/posix-no-chdir
posix: add AbsolutePaths option for embedding without chdir
2026-09-10 17:19:45 -07:00
RaduBerindeandGitHub db0d2cc185 Merge branch 'main' into posix-no-chdir 2026-09-10 16:55:58 -07:00
Ben McClellandandGitHub 107714caa0 Merge pull request #2382 from versity/sis/cuobjserver-2.0.0-port
fix: port the cuObjServer wrapper to libcuobjserver 2.0.0
2026-09-10 15:48:04 -07:00
Radu Berinde 7ae119d654 posix: add AbsolutePaths option for embedding without chdir
Problem:
- `posix.New` calls `os.Chdir(rootdir)` and uses cwd-relative paths for
  every bucket and object. That is the cheapest way to address files, but
  the cwd is process-wide: embedding the gateway (`embedgw`) silently moves
  the host program's cwd. In particular, Go unit tests that embed the
  gateway can no longer read their test data files by relative path.

Change:
- New `PosixOpts.AbsolutePaths`. When set, `New` leaves the working
  directory alone and builds every path from the absolute root; a relative
  `VersioningDir`/`SideCarDir` is then resolved against the working
  directory rather than the root. The default is unchanged: chdir and
  relative paths.
- All bucket and object paths go through new `BucketPath`/`ObjectPath`,
  which return the name as-is by default and prefix the root with
  `AbsolutePaths`. An absolute "bucket" (the versioning directory
  substitution) is passed through unchanged.
- `tmpfile` records the bucket directory path so `link()` and its fallbacks
  use the same addressing; `ListBuckets` reads the root through the same
  helper.
- `meta.XattrMeta` needs the same root with `AbsolutePaths`. New
  `meta.RootDirSetter` interface; `posix.New` calls `WithRootDir` on
  storers that implement it in that mode. A zero `XattrMeta` keeps
  resolving against the cwd. `SideCar`/`NoMeta` unchanged. A type that
  embeds `XattrMeta` inherits a `WithRootDir` that returns a bare
  `XattrMeta`, so it needs its own (documented on `RootDirSetter`).
- `DeleteObject` (directory object), `ListParts`, and `UploadPartCopy`
  passed filesystem paths where the metadata API expects bucket/object
  names; they now pass names, so the sidecar layout is unchanged in both
  modes.
- Windows `handleParentDirError` walks up until `filepath.Dir` is a fixed
  point, which works for relative and absolute paths.
- scoutfs used cwd-relative bucket/object paths in `CreateBucket`,
  `GetObject`, `HeadObject`, `RestoreObject` and the glacier walk; they now
  go through `BucketPath`/`ObjectPath`. `scoutfs.New` resolves `rootdir`
  before `posix.New` so a relative root no longer reopens `rootdir/rootdir`
  after the chdir.
- `isBucketValid` unconditionally rejects names that do not denote a single
  entry under the root: `""`, `.`, `..`, names containing a path separator,
  and absolute paths. `XattrMeta` rejects `""`, `.` and `..` likewise.
  With relative paths `os.Stat("")` and `os.RemoveAll(".")` failed by
  accident; with absolute paths they would act on the root directory itself
  (reachable with strict bucket names disabled, or via the admin
  `change-bucket-owner` endpoint which does not validate `bucket`).
- scoutfs had its own `isBucketValid` whose `validateBucketName` flag was
  never set, so it accepted everything. It now delegates to the new exported
  `Posix.IsBucketValid`.
- `UploadPartCopy` did not validate the copy source's bucket name (unlike
  `CopyObject`); it does now.
- `New` opens the root after validating the versioning and sidecar
  directories, so those error paths no longer leak the root handle. The
  chdir still happens first, so a relative directory resolves against the
  root as before.

Tests:
- New `TestDefaultModeChangesWorkingDirectory` documents the default.
- New `TestRootDirIndependentOfWorkingDirectory`: `AbsolutePaths` with a
  relative root from an unrelated cwd, checks cwd is untouched and that
  put/get/list/delete, copy, multipart upload with checksums and part copy,
  directory-object delete, and invalid bucket names behave correctly under
  the root, for both metadata storers.
- New `TestVersioningDirIndependentOfWorkingDirectory`: same setup with a
  relative versioning directory; versions land there and not under the
  root or cwd.
- New `TestXattrMetaPath` covers cwd-relative and root resolution, absolute
  pass-through and the rejected names.
- New `BenchmarkPosix*` benchmarks (small-object head/get/put/list, both
  storers, both path modes). The default mode matches `main` within noise
  on both Linux and macOS. `AbsolutePaths` costs about 0.2µs (Linux) to
  0.4µs (macOS) per path lookup; on Linux (arm64 VM, overlayfs) that is
  +2-3% on PutObject and +10-27% on the metadata-heavy small-object
  HeadObject/GetObject/ListObjectsV2 with xattr metadata, which is why it
  is opt-in.
2026-09-10 13:28:01 -07:00
niksis02 ee25c95948 fix: port the cuObjServer wrapper to libcuobjserver 2.0.0
NVIDIA's rolling cuda-rhel9 repository bumped libcuobjserver from `1.2.0` to `2.0.0` and `build/vgwrdma-builder/Dockerfile` installs it unpinned, so `make vgwrdma-docker` broke: `setTelemFlags` gained a second mask and `initRDMAConfigParams` vanished along with the `RDMAConnection` base class that 2.0.0 deletes entirely. Rather than pin the package, this ports the C wrapper and the Go `rdma` package to the new API.

Telemetry now calls `setTelemFlags(flags, 0)`, where 0 reproduces the old behaviour. `Server.InitRDMAConfig` and its C entry point are removed, which drops a method from the exported API of `github.com/versity/versitygw/rdma`; it had no callers, and 2.0.0 only accepts tunables through the four-argument constructor that `NewServer` already uses. The `dlsym` lookups for `startRDMASession` and `closeRDMASession` go too, as dead code: 1.2.0 never exported those symbols either, so the fallback paths were always what ran. `HandleGet` and `HandlePut` now wrap the library's negative return in a `syscall.Errno` so 2.0.0's new `-EPROTO` is legible, and the wrapper compile rule gains `-std=c++17`. No defaults change.

`make vgwrdma-docker` passes and the binary links `libcuobjserver.so.2`, so it requires a 2.x install at runtime. `cuobjtest-gpu` and `cuobjtest-host` are unaffected. The RDMA data path itself is not verified here; that needs Mellanox hardware with DC transport.
2026-09-10 21:15:01 +04:00
Ben McClellandandGitHub a5004b99fb Merge pull request #2381 from versity/sis/empty-versionid-validation
fix: reject empty `versionId` query parameter in object actions
2026-09-10 10:06:39 -07:00
niksis02 1e0d7b218d fix: reject empty versionId query parameter in object actions
S3 returns `InvalidArgument` when an object action receives a `versionId` query parameter with no value. The gateway silently treated it as an unversioned request instead.

Added a shared `versionId` validation helper and apply it to the object actions that accept the parameter, so malformed requests are rejected up front rather than reaching the backend.
2026-09-10 16:35:05 +04:00
Ben McClellandandGitHub be3ec8ba4d Merge pull request #2378 from versity/ben/request-body-drain
fix: close connections with unread chunked bodies
2026-09-09 15:38:28 -07:00
niksis02 d383e1f32f fix: track how the request body ended before closing the connection
The body stream is now wrapped in a `bodyStreamTracker` before the handler touches it, which remembers the stream's first terminal result rather than asking fasthttp a second, unsafe question. `io.EOF` means the body was read out in full and the connection is still in sync; no terminal result means the handler stopped partway, so the leftovers are drained the way a
`Content-Length` body already was; a framing error means nothing decodable is left and the connection cannot carry another request.

`fasthttp.Request.SetBodyStream` cannot install the wrapper, as it releases the current `*requestStream` back to its pool, so `requestBodyStream` is now the accessor every body reader takes the stream from.

Broken framing no longer gives up on draining either. The connection is closed either way, so a bounded read off the raw socket costs nothing and lets the client finish its write and read the S3 error instead of a reset.
2026-09-09 23:30:32 +04:00
Ben McClellandandGitHub 2c157f8974 Merge pull request #2380 from versity/sis/posix-create-exsiting-bucket-err
fix: return `BucketAlreadyExists` for existing dirs without acl meta attr
2026-09-09 08:59:23 -07:00
Ben McClellandandGitHub 4e862bb7d9 Merge pull request #2368 from versity/sis/s3-conditional-write-condition-keys
feat: add s3:if-match and s3:if-none-match policy condition keys
2026-09-09 08:57:30 -07:00
Ben McClellandandGitHub dd6ab01d6d Merge pull request #2366 from potatogim/rc-parity-pr4
rdma: publish RC transfer outcomes into the gateway operational services
2026-09-09 08:23:01 -07:00
Ben McClellandandGitHub 073178511a Merge pull request #2379 from versity/sis/restore-ipa-kra-compat-jwk-panic-fix
fix: restore IPA KRA compatibility and fix JWK parse panic
2026-09-09 08:07:11 -07:00
niksis02 a58e125184 fix: return BucketAlreadyExists for existing dirs without acl meta attr
`CreateBucket` on an existing directory read the bucket acl meta attribute to decide between `BucketAlreadyOwnedByYou` and `BucketAlreadyExists`. For a directory that predates the gateway (or was created outside it) the attribute is missing, so the retrieve failed with `meta.ErrNoSuchKey` and the call returned a wrapped internal error instead of an S3 error. Treat a missing acl attribute as a bucket that exists and is not owned by the caller.
2026-09-09 18:57:18 +04:00
niksis02 d68efb6df9 fix: restore IPA KRA compatibility and fix JWK parse panic
`293d9f50` migrated `auth/iam_ipa.go`'s KRA session-key wrap from `rsa.EncryptPKCS1v15` to `rsa.EncryptOAEP` to silence a Go 1.26 deprecation warning. FreeIPA's KRA can be configured to unwrap session keys with either PKCS#1 v1.5 (its default) or OAEP, and the REST API has no way to query which one a given deployment uses — the same constraint FreeIPA's own client (`ipaclient/plugins/vault.py`) works around by trying one padding and falling back to the other. Hardcoding OAEP with no fallback breaks `GetUserAccount` against any KRA using the default PKCS#1 v1.5 configuration, which includes every deployment that worked before that change.

This restores compatibility by trying PKCS#1 v1.5 first, matching the pre-`293d9f50` behavior, and falling back to OAEP on failure so FIPS-mode KRAs (which reject PKCS#1 v1.5) keep working too.

Separately, `293d9f50` also changed `iamapi/internal/iamutil/webidentity.go`'s OIDC JWKS parsing to build EC public keys via `ecdsa.ParseUncompressedPublicKey` instead of setting `ecdsa.PublicKey`'s `X`/`Y` fields directly — a real improvement, since it validates the point is on the curve, which the old code never did. But it writes the JWK's `x`/`y` coordinates into a fixed-size buffer via `big.Int.FillBytes` without checking their length first, so an oversized `x` or `y` in a JWKS response panics instead of returning an error. That JWKS is fetched from the OIDC issuer configured on a role's trust policy, so a malformed or compromised response can crash request handling for `AssumeRoleWithWebIdentity`. This adds a bounds check before the `FillBytes` calls, plus `TestJwkPublicKeyEC` covering both the valid round-trip and the oversized-coordinate case, since `jwk.publicKey()`'s EC branch had no prior test coverage.
2026-09-09 18:31:12 +04:00
niksis02 23d8384ec0 feat: add s3:if-match and s3:if-none-match policy condition keys
Closes #2294

Support AWS's conditional-write condition keys in both S3 bucket policies and IAM identity policies, so a policy can require that an upload or delete carry an `If-Match`/`If-None-Match` precondition.

`requestConditionContext` now populates both keys from the request headers, which covers both policy types at once: the same map is evaluated in-process for bucket policies and shipped to the IAM service for identity policies. Only the three requests whose preconditions the gateway actually enforces contribute - PutObject, CompleteMultipartUpload and DeleteObject. Copies, form uploads, DeleteObjects batches, upload parts and the sub-resource writes all ignore the headers, and a policy must never grant on a precondition that won't be checked; reads are excluded for the same reason, since GET and HEAD take these headers as ordinary HTTP cache preconditions. The value is the ETag with its surrounding quotes stripped, matching what the gateway enforces against.

Bucket policies validate condition keys against a fixed catalogue at `PutBucketPolicy` time, so both keys are added there with the action sets AWS accepts: `s3:if-match` on `s3:PutObject` and `s3:DeleteObject`, `s3:if-none-match` on `s3:PutObject` alone. Identity policies validate only the operator vocabulary, matching AWS, so they need no change.
2026-09-09 17:18:42 +04:00
Jihyeon Gim ae2a3a6d55 rdma: acquire session admission credit atomically
Checking the publication backlog and taking the admission
credit were separate steps, so concurrent registrations could
each observe the same headroom and overshoot the session quota
together. Both now share one critical section, and a concurrent
test pins the behavior: sixteen registrations against a limit
of eight with one record pending admit exactly seven.

An admission refusal now publishes the same SlowDown error the
wire response carries, so operational accounting matches what
the client saw, and unregister releases the credit an
unfinalized registration was holding so the admission budget
cannot leak.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 60bec2c00d rdma: gate session admission on audit publication backlog
The native side releases its session quota when it fires the
teardown notification, before the audit record lands in a sink,
so session turnover can queue more unpublished records than the
live-session limit allows. Hold an admission credit per session
from registration until its record is published, and refuse new
sessions while the backlog of unpublished session records reaches
the native session quota: the refusal rolls the prepare back,
still publishes the request-level audit record, and answers
SlowDown so the client retries. A stalled sink now turns into
latency instead of unbounded memory.

Count dropped request records under the publication mutex so the
shutdown drop-count report cannot miss an increment racing it.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 51e63e2636 rdma: cap the session-less publication backlog
Bound the records a stalled sink can accumulate from requests
that never opened a session (failed authentications): beyond
4096 queued, dispatchOrDrop drops the record and counts it, and
shutdown reports the drop count once. Session publications stay
uncapped - each session publishes exactly once and the session
table has a hard limit, so their backlog is structurally bounded.

Cancel the metrics child context on constructor failure so a
malformed publisher endpoint does not leak the derived context
onto the parent.
2026-09-09 13:16:52 +09:00
Jihyeon Gim c9668b40b7 rdma: keep sinks outside the publication lock and self-close metrics
Detach queued work under the publication mutex and execute the
sinks after releasing it: the overflow servicing and the shutdown
drain now swap out the pending list inside the critical section
and publish outside, so a slow sink delays its own records but
never blocks a dispatcher or a native terminal callback.

Move the worker-stopped transition under the same mutex. The
worker marks itself stopped before emptying the channel and the
overflow list, and dispatchers test that flag rather than the
done channel inside the critical section, closing the window
where an append could land between the sweep completing and the
deferred channel close only to be stranded.

Give the metrics manager its own cancellation. The forwarder
terminates through a child context the manager derives and
cancels in Close, so a standalone use of the API shuts down
without relying on an external context being canceled.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 64a6ed0c37 rdma: synchronize publication acceptance with the drain boundary
Service the overflow list during normal operation: the worker
publishes and clears it after every channel job, so a burst that
exceeds the channel buffer drains as soon as the sink recovers
instead of accumulating until shutdown.

Make dispatch and the drain sweep share one critical section. An
append either lands before the sweep and is drained, or runs
after the worker exited and publishes inline; the check-then-send
window that could strand a record between the two is closed.
Request publications use the same boundary with drop semantics:
once the drain finished, no owner can guarantee the sinks are
still open, so the record is dropped rather than published.

Never close the metrics datapoint channel. The forwarder exits
through the canceled context after draining the buffer, the
closed flag turns late producers into drops, and no send can race
a closure. Implement the new Manager method in the test mock.
2026-09-09 13:16:52 +09:00
Jihyeon Gim e9a2a2f98b rdma: never run operational sinks on callback threads
Rework the publication handoff so a native callback can never
execute a sink: the channel buffer absorbs the common case, and a
full buffer appends to an overflow list that the worker drains
after the channel instead of falling back to inline publication.
Queued records accumulate across successive sessions and failed
authentications consume no session at all, so capacity accounting
cannot bound the backlog; only removing the fallback closes the
stall. Drop the now-unused session-limit accessor.

Move signature verification back outside the admission barrier:
IAM lookups carry no cancellation, so holding the barrier across
verification let one stalled lookup defer RC shutdown
indefinitely. The handlers enforce admission themselves, and a
failure publication checks the drain state before dispatching, so
it cannot land after the sinks close.

Synchronize metrics producers with Close: the manager now marks
itself closed before closing the datapoint channel, and a
producer that still races the closure recovers instead of
panicking on a send over a closed channel.

Exercise real stale tokens in the reservation generation test:
the original token attempts both release and publish after a
newer claim took over.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 55c82f5e4e rdma: size publications to session capacity and preserve committed PUT facts
Size the publication queue from the configured session limit instead
of a fixed depth with an overflow semaphore: each session publishes
exactly one terminal record, so the queue can never fill and native
callbacks hand off without waiting. Remove the semaphore fallback.

Admit verification failures under the shutdown barrier so an
authentication publication cannot land after the sinks close. Give
the metrics manager a lifetime independent of the gateway context so
shutdown drain updates are counted, and pass the captured bucket
explicitly so RC datapoints appear in bucket-filtered metrics.

Track reservations by claim generation: release and publication
validate the generation, so a stale claim cannot consume a newer
owner's record. Install the reservation cleanup defer immediately
after acquisition so a panic during authorization cannot orphan it.

Preserve committed PUT facts independent of the native finalizer:
when the backend object exists, record the commit, keep the
committed byte count on the error publication, and still emit the
object-created event.
2026-09-09 13:16:52 +09:00
Jihyeon Gim d3e45fdb41 rdma: track terminal events held off by an active reservation
A teardown callback that arrived while its record was reserved
was dropped: if the READY that held the reservation then rolled
its claim back, the session had lost both publication paths - no
request owner and no callback owner - and the record stayed
forever, unpublished. The record now stashes the terminal event;
releasing the reservation after a rollback consumes the stash and
publishes the expiry, since the native session is gone and no
second callback will arrive.

A duplicate READY that lost the reservation race still proceeded
to claim the native transfer, so the transfer could complete with
no publication owner. The READY handler now refuses to claim when
the reservation is not granted, answering as a duplicate claim.
Publication also validates ownership against the record's emitter,
so a stale reservation cannot publish over or consume the current
owner's record.

The shutdown drain raced its producers: a callback could enqueue
a publication after the drain checked the queue but before the
worker exited, stranding the record behind a stopped worker. The
drain now runs after the RC service close, which quiesces the
native reaper before returning, so no producer can enqueue behind
the drain; ordering replaces locking.

Error paths that published directly bypassed the single-shot
guard, letting the deferred panic safety net attempt a second
publication of the same record. All outcome publications in the
READY completion flow now go through the guarded path.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 96be4d1407 rdma: bound publication backpressure and close the reservation window
Overflow publications ran one goroutine per job: a stalled sink
with a full queue grew them without bound (a probe reached a
thousand blocked calls). Overflow now runs inline under a bounded
semaphore, so at most a fixed number of callers wait and every
record still publishes.

The publication worker outlived the operational sinks: gateway
shutdown closed the RC service and then the sinks while
publications were still queued, losing terminal records (reached
"file already closed" with the real file logger). The shutdown
wrapper now drains the publication queue before closing the RC
service, and the route handler exposes the drain; late terminals
after the drain publish inline instead of queueing behind a
stopped worker.

The publication reservation happened after the transfer claim
returned: in the window between the claim and the reservation, a
concurrent READY's re-authorization denial consumed the unreserved
record, so the claimant's successful transfer lost its publication
to the denial. The READY handler now reserves before the claim and
before re-authorization; a rolled-back claim (wire failure, peer
busy) releases the reservation instead of publishing, so the
session keeps its record for the next claimant or the reaper.

The tracker test now joins the worker through the shutdown drain
and asserts per-session outcomes and byte counts instead of an
aggregate count that a pending fifth record could satisfy.
2026-09-09 13:16:52 +09:00
Jihyeon Gim d30ace72ad rdma: keep reaper callbacks off sink threads
The teardown callback ran audit, metrics, and event sinks inline on
whatever thread fired it, which is the native reaper thread: one
blocking sink (a synchronous file write on a stalled filesystem)
would stall reaping for every other session. Publications now hand
off to a dedicated worker through a bounded queue; a full queue
falls back to a detached goroutine, so the callback never waits on
a sink and no record is dropped.

A denial issued while a completion owner holds the reservation
(concurrent READY re-authorization failure) no longer steals the
publication: reserved records are invisible to the denial path,
which previously produced a denial record plus the owner's success
record for one transfer.

The tracker tests now drive a recording audit sink and assert the
published record count across expiry, reserved, denied-while-
reserved, and consume-or-noop paths: one record per session.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 97238d80ad rdma: reserve session publication before completion calls
A native completion call fires the teardown callback before it
returns, so an outcome recorded after the call is too late: every
successful transfer published as an expiry, and PUT failures and
panics lost their real outcome to the callback's placeholder.

The READY handler now reserves the session record before invoking
any completion call. A reserved record is invisible to the
callback, and the handler publishes the real outcome exactly once
after the result is known. A deferred safety net publishes on
panic unwinds before the unwind finalizer retires the session.
Successful PUTs forward the backend-assigned ETag and version into
the object-created event, and the audit record carries the
transferred byte count as the object size.

A READY whose re-authorization fails now publishes the denial
itself before canceling, instead of letting the cancel publish an
expiry.

The native side keeps the terminal reason on every failure exit:
a verify failure no longer overwrites the wire-failure outcome,
and QP transition or re-arm failures record the wire failure they
return. The unclaimed-teardown classification follows the wire
mapping, so every transfer-level failure the client would see as
502 publishes as the same 502 instead of a diverging per-cause
code.

The metrics bucket tag is documented as absent on synthesized
publications: route parameters come from route matching, which a
synthesized request never runs; the audit log derives the bucket
from the path and stays accurate.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 23a7121bb8 rdma: make the teardown callback the single RC publication owner
Round-3 review of the ownership model found that moving publication
between the request path and the callback by hand leaves edges where
a record is published twice or lost. The publication model is now
structural instead: request paths only record outcomes, and the
native teardown callback - which the ABI fires exactly once per
destroyed session, after every completion call - is the single
publisher.

The READY handler records its outcome (success with the reported
byte count, or the mapped failure) and lets the callback publish.
A deferred recorder covers panic unwinds, so every path through
the handler leaves a final outcome behind. A failed PREPARE
finalization publishes through a consume-or-noop helper: when the
finalizing call already reaped the session the entry is gone and
the helper is a no-op, otherwise it publishes the failure itself.

Unclaimed teardowns no longer all read as expiries: the record is
classified from the native outcome, so a transfer that died on the
wire, failed verification, or timed out carries its own code and
status.

The synthesized publication context runs on an immutable app, so
string accessors copy instead of exposing the pooled request buffer
to the asynchronously serializing event senders. Captured account
and region strings are cloned for the same reason. The nil-error
publication no longer asserts on the S3 error interface, and the
panic marker is a proper internal S3 error.

Unit tests cover the table semantics: expiry publication,
first-record-wins, consume-or-noop failure publication, unregister,
unknown sessions, error normalization, status mapping, and the
outcome classification.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 279f5e7d2f rdma: harden RC outcome publication ownership and record fidelity
Review of the publication path found that ownership could change
hands at the wrong moment and that records could disagree with both
the wire response and the underlying operation.

Successful transfers lost their completion record: the native
completion calls fire the teardown callback synchronously, so the
callback claimed the publication first and logged every completed
transfer as an expiry, and committed PUTs produced no object-created
events. The READY handler now reserves the publication before
invoking any completion call; a reserved record is invisible to the
callback, and the handler publishes the real outcome exactly once.

The same race existed at creation: the PREPARE finalizer can reap an
expired session and fire the callback before the session is
registered, leaving an orphan entry whose only notification already
happened. Registration now runs before the finalizing call, a
notification that arrives first is parked and consumed by the
registration, and a failed finalization drops the entry.

Retained records referenced the request's pooled header buffer, so
a later request could rewrite a tracked session's bucket and key;
captured strings are cloned now. The synthesized publication path
follows the same rule for the event senders, which serialize
asynchronously.

Operational sinks classify plain errors as 500 on their own, so a
resource-limit rejection logged 500 while the client saw 429. The
publication renders non-S3 errors through the route error mapping
before the record reaches the sinks, and the expiry record carries
a dedicated SessionExpired code instead of a generic one. Malformed
PUT headers now preserve the operation in the record.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 39aae5435c rdma: close publication gaps for RC pre-session failures
Review of the operational publication found four gaps where the
records disagreed with the S3 surface or were missing entirely.

Authorization-failure records lost the requester because the
pre-session publisher did not carry the authenticated account; the
account now flows into the record, so the audit trail names who was
denied.

Signature failures and malformed PREPARE headers ended the request
before any publication point. The auth adapter now publishes
authentication failures through the route handler, and header
validation failures publish with whatever object identity the
headers still carried, matching the S3 surface where every denied
request still logs.

RC requests carried no region: the custom routes run before the
middleware that stores the region local, so event records lacked
awsRegion and audit host headers read s3..amazonaws.com. The auth
adapter sets the region for every verified RC request.

Operational records reported generic 500 statuses for protocol
errors that the wire answers with a specific status (a resource
limit rejection logged 500 while the client saw 429). Status
mapping now reuses the route error mapping, so the recorded status
always equals the wire status.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 49b1c6f6bc rdma: publish RC transfer outcomes into the gateway operational services
Two-phase RC transfers were invisible to the access log, metrics,
and bucket notifications: every outcome record on the S3 surface is
driven by the fiber request context, and the RC wire requests carry
the transfer session rather than the object.

Publish one record per session by tracking the operational context
from PREPARE through completion. A tracker table registers each
successfully prepared session with its account, region, object, and
start time; whichever path confirms the final outcome first (READY
completion, READY failure, or the reaper teardown callback) claims
the entry and publishes exactly once. Sessions that end before
PREPARE succeeds publish a request record directly.

The record is emitted through a synthetic fiber context carrying
the object path and the captured locals, so the existing logger,
metrics manager, and event sender produce the same schema as the
S3 surface without any interface change. Bucket notifications fire
for completed PUTs.

The gateway creates the operational services inside RunVersityGW,
after the RC routes exist. Add an OnServicesReady callback to the
embedded gateway config and wire it in vgwrdma to hand the services
to the RC routes and install the teardown callback.
2026-09-09 13:16:52 +09:00
Jihyeon Gim 138504dbc9 rdma: add terminal notification callback to the RC server ABI
RC sessions that never reach a completion (expired, abandoned, or canceled before READY) currently vanish inside the reaper without any trace on the operational surface. Add a terminal notification callback to the C ABI so the server reports the final outcome of every session exactly once, fired from the reaper with no server lock held.
2026-09-09 13:16:52 +09:00
Ben McClellandandGitHub 7c49bb4513 Merge pull request #2371 from versity/dependabot/go_modules/dev-dependencies-5f4730b719
chore(deps): bump the dev-dependencies group with 21 updates
2026-09-08 15:56:46 -07:00
Ben McClelland c36696620a fix: close connections with unread chunked bodies
A streamed chunked request can leave bytes queued after the handler returns.
Reusing that connection lets fasthttp parse those bytes as the next request,
allowing a shared upstream proxy connection to mix requests across tenants.
Mark chunked requests Connection: close when the middleware cannot safely
drain them, preventing leftover bytes from crossing the request boundary.

Draining is intentionally skipped because fasthttp's request stream reads past
the terminating chunk when probing for EOF and can block waiting for another
chunk header. The connection-reuse sacrifice is therefore required to avoid both
request desynchronization and delaying the response. Content-Length bodies
retain the existing bounded drain behavior.
2026-09-08 15:36:01 -07:00
Ben McClellandandGitHub a1a1137efc Merge pull request #2375 from RaduBerinde/integration-ignore-aws-config
tests: build the integration SDK config without the host's AWS setup
2026-09-08 15:28:33 -07:00
Ben McClelland 293d9f50d8 fix: deprecations in JWK and IPA RSA handling
Go 1.26 marks PKCS#1 v1.5 RSA encryption and direct ECDSA public-key coordinate access
as deprecated. The IPA code path uses rsa.EncryptPKCS1v15 to wrap an AES session key for
vault retrieval, and the OIDC JWKS parser rebuilt EC public keys by setting ecdsa.PublicKey.X
and Y directly.

This change replaces the deprecated RSA wrap with rsa.EncryptOAEP using SHA-256, which is the
standard safe replacement for PKCS#1 v1.5 encryption and preserves the same protocol semantics
for the IPA vault exchange. For EC JWKs, it reconstructs the raw uncompressed public point and
parses it through ecdsa.ParseUncompressedPublicKey, which is the supported Go API for EC public
keys and avoids mutating deprecated fields while preserving the exact mathematical key value.

These changes do not alter the wire protocol or trust decisions; they only migrate to the
supported stdlib APIs for equivalent behavior.
2026-09-08 15:25:08 -07:00
dependabot[bot]andBen McClelland 0e61bd69a1 chore(deps): bump the dev-dependencies group with 21 updates
Bumps the dev-dependencies group with 21 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.45.1` | `1.46.0` |
| [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.33.1` | `1.33.3` |
| [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.20.1` | `1.20.3` |
| [github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager](https://github.com/aws/aws-sdk-go-v2) | `0.4.1` | `0.4.3` |
| [github.com/aws/aws-sdk-go-v2/service/iam](https://github.com/aws/aws-sdk-go-v2) | `1.61.1` | `1.63.0` |
| [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.109.1` | `1.111.0` |
| [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) | `1.47.1` | `1.49.0` |
| [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://github.com/aws/aws-sdk-go-v2) | `1.19.1` | `1.19.2` |
| [github.com/aws/aws-sdk-go-v2/internal/configsources](https://github.com/aws/aws-sdk-go-v2) | `1.5.1` | `1.5.2` |
| [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://github.com/aws/aws-sdk-go-v2) | `2.8.1` | `2.8.2` |
| [github.com/aws/aws-sdk-go-v2/internal/v4a](https://github.com/aws/aws-sdk-go-v2) | `1.5.1` | `1.5.2` |
| [github.com/aws/aws-sdk-go-v2/service/internal/checksum](https://github.com/aws/aws-sdk-go-v2) | `1.11.1` | `1.11.2` |
| [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://github.com/aws/aws-sdk-go-v2) | `1.14.1` | `1.14.2` |
| [github.com/aws/aws-sdk-go-v2/service/internal/s3shared](https://github.com/aws/aws-sdk-go-v2) | `1.20.1` | `1.20.2` |
| [github.com/aws/aws-sdk-go-v2/service/signin](https://github.com/aws/aws-sdk-go-v2) | `1.7.1` | `1.9.0` |
| [github.com/aws/aws-sdk-go-v2/service/sso](https://github.com/aws/aws-sdk-go-v2) | `1.35.1` | `1.37.0` |
| [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://github.com/aws/aws-sdk-go-v2) | `1.40.1` | `1.42.0` |
| [github.com/gofiber/schema](https://github.com/gofiber/schema) | `1.8.4` | `1.8.5` |
| [github.com/gofiber/utils/v2](https://github.com/gofiber/utils) | `2.4.2` | `2.4.3` |
| [github.com/klauspost/compress](https://github.com/klauspost/compress) | `1.19.2` | `1.20.0` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.55.0` | `0.56.0` |


Updates `github.com/aws/aws-sdk-go-v2` from 1.45.1 to 1.46.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.45.1...v1.46.0)

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.33.1 to 1.33.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.33.1...config/v1.33.3)

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.20.1 to 1.20.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.20.1...v1.20.3)

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager` from 0.4.1 to 0.4.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/feature/s3/transfermanager/v0.4.1...feature/s3/transfermanager/v0.4.3)

Updates `github.com/aws/aws-sdk-go-v2/service/iam` from 1.61.1 to 1.63.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.61.1...service/s3/v1.63.0)

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.109.1 to 1.111.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.109.1...service/s3/v1.111.0)

Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.47.1 to 1.49.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.47.1...service/s3/v1.49.0)

Updates `github.com/aws/aws-sdk-go-v2/feature/ec2/imds` from 1.19.1 to 1.19.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.19.1...service/m2/v1.19.2)

Updates `github.com/aws/aws-sdk-go-v2/internal/configsources` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/service/m2/v1.5.2/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.5.1...service/m2/v1.5.2)

Updates `github.com/aws/aws-sdk-go-v2/internal/endpoints/v2` from 2.8.1 to 2.8.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/endpoints/v2.8.1...internal/endpoints/v2.8.2)

Updates `github.com/aws/aws-sdk-go-v2/internal/v4a` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/service/m2/v1.5.2/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.5.1...service/m2/v1.5.2)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/checksum` from 1.11.1 to 1.11.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.11.1...v1.11.2)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/presigned-url` from 1.14.1 to 1.14.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/pi/v1.14.1...service/pi/v1.14.2)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/s3shared` from 1.20.1 to 1.20.2
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.20.1...v1.20.2)

Updates `github.com/aws/aws-sdk-go-v2/service/signin` from 1.7.1 to 1.9.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/v1.9.0/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.7.1...v1.9.0)

Updates `github.com/aws/aws-sdk-go-v2/service/sso` from 1.35.1 to 1.37.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/pi/v1.35.1...v1.37.0)

Updates `github.com/aws/aws-sdk-go-v2/service/ssooidc` from 1.40.1 to 1.42.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.40.1...v1.42.0)

Updates `github.com/gofiber/schema` from 1.8.4 to 1.8.5
- [Release notes](https://github.com/gofiber/schema/releases)
- [Commits](https://github.com/gofiber/schema/compare/v1.8.4...v1.8.5)

Updates `github.com/gofiber/utils/v2` from 2.4.2 to 2.4.3
- [Release notes](https://github.com/gofiber/utils/releases)
- [Commits](https://github.com/gofiber/utils/compare/v2.4.2...v2.4.3)

Updates `github.com/klauspost/compress` from 1.19.2 to 1.20.0
- [Release notes](https://github.com/klauspost/compress/releases)
- [Commits](https://github.com/klauspost/compress/compare/v1.19.2...v1.20.0)

Updates `golang.org/x/crypto` from 0.55.0 to 0.56.0
- [Commits](https://github.com/golang/crypto/compare/v0.55.0...v0.56.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-version: 1.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/credentials
  dependency-version: 1.20.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager
  dependency-version: 0.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/iam
  dependency-version: 1.63.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/s3
  dependency-version: 1.111.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sts
  dependency-version: 1.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/ec2/imds
  dependency-version: 1.19.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/configsources
  dependency-version: 1.5.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/endpoints/v2
  dependency-version: 2.8.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/v4a
  dependency-version: 1.5.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/checksum
  dependency-version: 1.11.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/presigned-url
  dependency-version: 1.14.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/s3shared
  dependency-version: 1.20.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/signin
  dependency-version: 1.9.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sso
  dependency-version: 1.37.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/ssooidc
  dependency-version: 1.42.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/gofiber/schema
  dependency-version: 1.8.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/gofiber/utils/v2
  dependency-version: 2.4.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.20.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/crypto
  dependency-version: 0.56.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-08 15:14:57 -07:00