diff --git a/.github/workflows/bridge-ci.yml b/.github/workflows/bridge-ci.yml index 36137e19..4f3aaa5c 100644 --- a/.github/workflows/bridge-ci.yml +++ b/.github/workflows/bridge-ci.yml @@ -20,7 +20,7 @@ concurrency: jobs: bridge-required-gates: name: Bridge component acceptance - needs: [addon, bff, dependencies, lockfiles, rust-dependencies, secrets, security, web] + needs: [addon, bff, dependencies, idp, lockfiles, rust-dependencies, secrets, security, web] if: always() runs-on: ubuntu-22.04 env: @@ -222,6 +222,180 @@ jobs: docker rm --force "$WEB_CONTAINER_ID" fi + idp: + name: Dex IdP runtime qualification + runs-on: ubuntu-24.04 + timeout-minutes: 60 + permissions: + contents: read + env: + PYTHONDONTWRITEBYTECODE: '1' + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Initialize native Dex qualification evidence + run: | + set -euo pipefail + export IDP_EVIDENCE_DIR="$RUNNER_TEMP/bridge-idp-evidence" + printf 'IDP_EVIDENCE_DIR=%s\n' "$IDP_EVIDENCE_DIR" >> "$GITHUB_ENV" + mkdir -p "$IDP_EVIDENCE_DIR" + printf 'commit=%s\nrun_id=%s\nrun_attempt=%s\n' \ + "$GITHUB_SHA" "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" \ + > "$IDP_EVIDENCE_DIR/provenance.txt" + test "$(uname -m)" = x86_64 + docker info --format '{{.OSType}}/{{.Architecture}}' \ + | tee "$IDP_EVIDENCE_DIR/docker-platform.txt" + df -h "$RUNNER_TEMP" | tee "$IDP_EVIDENCE_DIR/disk-before.txt" + - name: Check Dex source contracts and actual reviewed module locks + id: idp_source + run: | + set -euo pipefail + KARS_DEX_PATCH_NETWORK=1 python3 -m unittest discover \ + -s bridge/idp/tests -p 'test_*.py' \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/source-contracts.log" + PYTHONPATH=bridge/idp/tests python3 -c \ + 'from contracts import check_modules; check_modules("bridge/idp"); print("Reviewed Go module locks verified")' \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/module-locks.log" + PYTHONPATH=ci/tests python3 -m unittest bridge_contracts_test.ContractAggregateTests \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/component-aggregate-contracts.log" + git diff --exit-code -- bridge/idp/locks + - name: Build and run upstream Dex root and API race suites + id: idp_upstream + run: | + set -euo pipefail + docker build --platform linux/amd64 --progress=plain \ + --target upstream-tests --tag kars-bridge-idp-upstream-tests:latest \ + --file bridge/idp/Dockerfile bridge/idp \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/upstream-build.log" + - name: Collect actual upstream JSON reports and disclose skips + id: idp_reports + run: | + set -euo pipefail + container=$(docker create kars-bridge-idp-upstream-tests:latest) + trap 'docker rm "$container"' EXIT + docker cp "$container:/out/doc/upstream-tests.json" "$IDP_EVIDENCE_DIR/upstream-tests.json" + docker cp "$container:/out/doc/api-tests.json" "$IDP_EVIDENCE_DIR/api-tests.json" + docker image inspect kars-bridge-idp-upstream-tests:latest \ + > "$IDP_EVIDENCE_DIR/upstream-image.json" + python3 - <<'PY' + import collections + import json + import os + from pathlib import Path + + evidence = Path(os.environ["IDP_EVIDENCE_DIR"]) + summary = {} + for label, filename in (("root", "upstream-tests.json"), ("api", "api-tests.json")): + tests = collections.Counter() + packages = collections.Counter() + started, finished = set(), set() + skips = [] + for number, line in enumerate((evidence / filename).read_text().splitlines(), 1): + event = json.loads(line) + if not isinstance(event, dict) or not isinstance(event.get("Action"), str): + raise SystemExit(f"Invalid Go event in {filename}:{number}") + action = event["Action"] + if action in ("fail", "build-fail"): + raise SystemExit(f"Upstream failure recorded in {filename}:{number}") + package = event.get("Package") + if package and not event.get("Test"): + if action == "start": + started.add(package) + elif action in ("pass", "skip"): + finished.add(package) + packages[action] += 1 + if event.get("Test") and action in ("pass", "skip"): + tests[action] += 1 + if action == "skip": + skips.append({"package": package, "test": event.get("Test")}) + if not started or started != finished: + raise SystemExit(f"Incomplete package results in {filename}") + if label == "root" and not tests["pass"]: + raise SystemExit("The root report contains no passing upstream tests") + summary[label] = { + "testActions": dict(tests), "packageActions": dict(packages), "skipped": skips, + } + summary["coverageLimit"] = ( + "Skipped service integrations and unconfigured LDAP/cloud connectors are not " + "runtime-qualified. Memory, SQLite and static OIDC require the separate runtime harness." + ) + (evidence / "upstream-summary.json").write_text(json.dumps(summary, indent=2) + "\n") + with Path(os.environ["GITHUB_STEP_SUMMARY"]).open("a") as output: + output.write("### Dex upstream reports (not final runtime qualification)\n") + for label in ("root", "api"): + counts = summary[label] + output.write(f"- {label}: test actions {counts['testActions']}; " + f"package actions {counts['packageActions']}. See retained JSON for every skip.\n") + output.write(summary["coverageLimit"] + "\n") + PY + - name: Build Dex tools and run signing-key continuity race regressions + id: idp_tools + run: | + set -euo pipefail + docker build --platform linux/amd64 --progress=plain \ + --target test-tools --tag kars-bridge-idp-tools:latest \ + --file bridge/idp/Dockerfile bridge/idp \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/probe-build.log" + docker image inspect kars-bridge-idp-tools:latest > "$IDP_EVIDENCE_DIR/tools-image.json" + - name: Build the actual Azure Linux distroless Dex runtime without publishing + id: idp_runtime + run: | + set -euo pipefail + docker build --platform linux/amd64 --progress=plain \ + --target runtime --tag kars-bridge-idp-qualification:latest \ + --file bridge/idp/Dockerfile bridge/idp \ + 2>&1 | tee "$IDP_EVIDENCE_DIR/runtime-build.log" + - name: Install pinned Trivy and scan the actual Dex runtime + id: idp_scan + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + version: v0.70.0 + cache: 'false' + scan-type: image + image-ref: kars-bridge-idp-qualification:latest + scanners: vuln + severity: HIGH,CRITICAL + ignore-unfixed: false + list-all-pkgs: 'true' + exit-code: '1' + format: json + output: ${{ runner.temp }}/bridge-idp-evidence/initial-image-scan.json + - name: Require real memory SQLite OIDC linkage inventory and fresh-cache scans + id: idp_qualification + if: ${{ !cancelled() && steps.idp_runtime.outcome == 'success' }} + run: | + set -euo pipefail + { + trivy_path="$(command -v trivy)" + test -x "$trivy_path" + printf '%s\n' "$trivy_path" > "$IDP_EVIDENCE_DIR/trivy-cli-path.txt" + "$trivy_path" --version | tee "$IDP_EVIDENCE_DIR/trivy-cli-version.txt" + grep -Eq '^Version: 0[.]70[.]0([[:space:]]|$)' "$IDP_EVIDENCE_DIR/trivy-cli-version.txt" + python3 bridge/idp/tests/qualify.py \ + --image kars-bridge-idp-qualification:latest \ + --tools-image kars-bridge-idp-tools:latest \ + --trivy "$trivy_path" --evidence "$IDP_EVIDENCE_DIR/runtime" + } 2>&1 | tee "$IDP_EVIDENCE_DIR/runtime-qualification.log" + - name: Record Dex step outcomes without overriding failures + if: always() + env: + IDP_STEP_RESULTS: ${{ toJSON(steps) }} + run: | + set -euo pipefail + mkdir -p "$IDP_EVIDENCE_DIR" + printf '%s\n' "$IDP_STEP_RESULTS" > "$IDP_EVIDENCE_DIR/step-outcomes.json" + - name: Retain actual Dex qualification evidence including failures + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 + with: + name: bridge-idp-qualification-${{ github.sha }}-${{ github.run_attempt }} + path: ${{ runner.temp }}/bridge-idp-evidence/ + if-no-files-found: error + addon: name: Add-on install and uninstall runs-on: ubuntu-latest diff --git a/NOTICE b/NOTICE index 8edfa1d0..1bd003a7 100644 --- a/NOTICE +++ b/NOTICE @@ -85,6 +85,20 @@ The separately built aggregator downloads the official, checksum-verified remain with redistributed images; other bundled components retain their respective licenses. +## Optional curated Dex identity provider + +`bridge/idp` builds Dex v2.45.1 from upstream commit +`11d2eeb52b42e1980e14cb91e69dd9e3faab2076` under Apache License 2.0. +It preserves upstream attribution and explicitly discloses Kars packaging, +dependency updates, two literal-format fixes and a test-only historical +certificate clock adjustment. It is not an unmodified upstream Dex image. + +The original upstream license, source/module snapshots, reviewed patches and +linked dependency notices accompany the built image. `bridge/idp/NOTICE` +describes their installed locations. Generated module/checksum files and +patch inputs retain their exact verified bytes; Kars headers must not rewrite +them or imply ownership of upstream source. New Kars wrapper code is MIT. + ## Vendored TypeScript SDK build `vendor/agt/microsoft-agent-governance-sdk-4.0.0-agt-bdea1097.tgz` diff --git a/bridge/docs/governed-credentials.md b/bridge/docs/governed-credentials.md index 55bdc48c..bd8fd156 100644 --- a/bridge/docs/governed-credentials.md +++ b/bridge/docs/governed-credentials.md @@ -272,6 +272,21 @@ are never written to this evidence. Collection cannot qualify any assertion. TLS negatives, 9447/9448 paths, CNI peer denial, and credential rotation remain required unchanged. +`routerRollout` separately captures an unready router's bounded container state, +restart count, previous exit reason/code/signal, fixed startup-log markers and +classified kubelet probe events. It checks the target namespace/Deployment and +ReplicaSet/Pod UID chain, then rechecks all snapshot resource versions and Pod +process state. Old observer versions are reported as comparison booleans, not +accepted as current capability authority. This does not relax the existing +readiness collector or the network experiment's ready-process requirement. +Current and previous process log tails remain separate; failed log/event reads +are explicit without discarding otherwise stable process-state evidence. +Events must reference the exact Pod UID and `spec.containers{inference-router}`; +their coverage is the Pod lifetime, not proof of the current process's failure. +Unknown text, probe URLs/bodies, container IDs and raw errors are not retained. +A logged listener-start intention is not a successful bind or reachability +proof. The original failed result and three dependent blocked cases remain. + An operator template-drift or writer-restoration refusal also records `enrollmentTemplateDrift`. It compares the fixture's pre-preview runtime, controller and BFF Deployment snapshots with the existing CLI review and current objects, using the shipped diff --git a/bridge/docs/public-beta-helm.md b/bridge/docs/public-beta-helm.md index 230bfe24..f021f103 100644 --- a/bridge/docs/public-beta-helm.md +++ b/bridge/docs/public-beta-helm.md @@ -44,6 +44,15 @@ its label is not a rebuild. Do not overwrite normal release repositories with beta images or assume historical chart image defaults are publicly available. See [Bridge image builds and deployment](deployment.md#install). +If enabling bundled Dex, separately build and qualify the +[curated IdP runtime](../idp/README.md), then set `idp.dex.image` to its approved +immutable registry reference. The historical upstream chart default is not +an approved image merely because it is a default: the September 16 scan of +upstream v2.45.1 found High/Critical issues and blocked its use. Do not deploy +it, suppress those findings, or use the dev-role preview as authentication. +The curated source recipe is not itself a published or runtime-qualified image. +External OIDC remains an alternative when genuinely configured by the operator. + Before changing an existing installation, inventory Helm ownership, CRD/schema compatibility, workload placement and external credentials. Back up sensitive configuration privately with restricted file permissions, outside the checkout. diff --git a/bridge/idp/.dockerignore b/bridge/idp/.dockerignore new file mode 100644 index 00000000..9e2e3154 --- /dev/null +++ b/bridge/idp/.dockerignore @@ -0,0 +1,18 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +* +!Dockerfile +!Dockerfile.locks +!locks +!locks/** +!patches +!patches/** +!scripts +!scripts/** +!tests +!tests/probe.go +!tests/probe_test.go +!NOTICE +!LICENSE +!README.md diff --git a/bridge/idp/Dockerfile b/bridge/idp/Dockerfile new file mode 100644 index 00000000..c6a91f0c --- /dev/null +++ b/bridge/idp/Dockerfile @@ -0,0 +1,68 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# Context: bridge/idp. Native builds only: build each architecture on its own +# hosted worker. Bookworm's glibc baseline is older than Azure Linux 3's. +FROM golang:1.26.8-bookworm@sha256:9fdc884aacc3bec89b20ffc69f4bb369c78210e3e4f600387b5128b12c199f81 AS source +ENV GOTOOLCHAIN=local GOWORK=off GOPROXY=https://proxy.golang.org \ + GOSUMDB=sum.golang.org GOMODCACHE=/work/mod GOCACHE=/work/cache \ + GOFLAGS=-mod=readonly CGO_ENABLED=1 +WORKDIR /src/dex +COPY locks/inputs.lock /packaging/locks/inputs.lock +COPY scripts/fetch-source.sh scripts/source-inventory.sh scripts/apply-source-patches.sh /packaging/scripts/ +COPY patches/ /packaging/patches/ +RUN sh /packaging/scripts/fetch-source.sh + +FROM source AS dependencies +# Deliberately absent until a hosted Go resolver's output has been reviewed. +# A runtime build MUST fail rather than resolve new versions implicitly. +COPY locks/generated/ /locks/ +COPY locks/requests.txt /packaging/locks/requests.txt +COPY scripts/verify-locks.sh /packaging/scripts/verify-locks.sh +RUN sh /packaging/scripts/verify-locks.sh \ + && go mod download && go mod verify \ + && cmp go.mod /locks/go.mod && cmp go.sum /locks/go.sum \ + && cd api/v2 && go mod download && go mod verify \ + && cmp go.mod /locks/api/v2/go.mod && cmp go.sum /locks/api/v2/go.sum + +FROM dependencies AS build +COPY scripts/build.sh /packaging/scripts/build.sh +COPY scripts/notices.go scripts/notices_test.go /packaging/scripts/ +COPY NOTICE LICENSE README.md /packaging/ +RUN go test -count=1 /packaging/scripts/notices.go /packaging/scripts/notices_test.go \ + && sh /packaging/scripts/build.sh + +FROM build AS compatibility-tests +RUN go test -race -count=1 -v \ + -run '^(TestKarsAuthorizationErrorDescriptionsLiteral|TestVerifyUnsignedMessageAndSignedAssertionWithRootXmlNs|TestKarsSAMLFixtureCertificateValidity)$' \ + ./server ./connector/saml + +# Kept separate from shipping layers. Full upstream package suites; external +# service integration tests still require the upstream documented services. +FROM compatibility-tests AS upstream-tests +COPY scripts/upstream-tests.sh /packaging/scripts/upstream-tests.sh +RUN sh /packaging/scripts/upstream-tests.sh + +FROM build AS test-tools +COPY tests/probe.go tests/probe_test.go /packaging/tests/ +# Only the external HTTP probe is pure Go. Dex itself always uses real CGO. +RUN go test -race -count=1 -v /packaging/tests/probe.go /packaging/tests/probe_test.go \ + && CGO_ENABLED=0 go build -trimpath -buildvcs=false -o /out/probe /packaging/tests/probe.go +ENTRYPOINT ["/out/probe"] + +FROM mcr.microsoft.com/azurelinux/distroless/base:3.0@sha256:4377af4aa7a810b7d59f691eae5066895a71aa3eee4cfb4eba527bbebff16479 AS runtime +LABEL org.opencontainers.image.title="Kars Dex security rebuild" \ + org.opencontainers.image.description="Dex v2.45.1 with disclosed Kars source, dependency and packaging patches; not an unmodified upstream image" \ + org.opencontainers.image.version="v2.45.1-kars.1" \ + org.opencontainers.image.source="https://github.com/Azure/kars" \ + org.opencontainers.image.licenses="Apache-2.0 AND MIT" \ + io.kars.dex.upstream.revision="11d2eeb52b42e1980e14cb91e69dd9e3faab2076" +COPY --from=build /out/dex /usr/local/bin/dex +COPY --from=build /src/dex/web /srv/dex/web +COPY --from=build /out/doc/ /usr/share/doc/dex/ +COPY --from=build --chown=1001:1001 /out/etc/ /etc/dex/ +COPY --from=build --chown=1001:1001 /out/data/ /var/dex/ +USER 1001:1001 +EXPOSE 5556 5557 5558 +ENTRYPOINT ["/usr/local/bin/dex"] +CMD ["serve", "/etc/dex/config.yaml"] diff --git a/bridge/idp/Dockerfile.locks b/bridge/idp/Dockerfile.locks new file mode 100644 index 00000000..7b38db38 --- /dev/null +++ b/bridge/idp/Dockerfile.locks @@ -0,0 +1,33 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# Separate from the image recipe: even legacy builders must never resolve +# dependency versions as an incidental step in a normal runtime image build. +FROM golang:1.26.8-bookworm@sha256:9fdc884aacc3bec89b20ffc69f4bb369c78210e3e4f600387b5128b12c199f81 AS source +ENV GOTOOLCHAIN=local GOWORK=off GOPROXY=https://proxy.golang.org \ + GOSUMDB=sum.golang.org GOMODCACHE=/work/mod GOCACHE=/work/cache \ + GOFLAGS=-mod=readonly CGO_ENABLED=1 +WORKDIR /src/dex +COPY locks/inputs.lock /packaging/locks/inputs.lock +COPY scripts/fetch-source.sh scripts/source-inventory.sh scripts/apply-source-patches.sh /packaging/scripts/ +COPY patches/ /packaging/patches/ +RUN sh /packaging/scripts/fetch-source.sh + +FROM source AS lock-generation +COPY locks/requests.txt /packaging/locks/requests.txt +COPY scripts/generate-locks.sh /packaging/scripts/generate-locks.sh +RUN sh /packaging/scripts/generate-locks.sh + +FROM scratch AS lock-artifact +COPY --from=lock-generation --chown=1001:1001 /out/ / +USER 1001:1001 + +FROM source AS lock-replay +COPY --from=lock-generation --chown=1001:1001 /out/ /out/ +COPY --chown=1001:1001 locks/generated/ /reviewed/ +USER 1001:1001 +RUN test "$(id -u)" = 1001 && test "$(id -g)" = 1001 \ + && cd /reviewed && sha256sum --check --strict SHA256SUMS \ + && cmp SHA256SUMS /out/SHA256SUMS \ + && cd /out && sha256sum --check --strict /reviewed/SHA256SUMS \ + && printf 'KARS_DEX_LOCK_REPLAY_PASSED\n' diff --git a/bridge/idp/LICENSE b/bridge/idp/LICENSE new file mode 100644 index 00000000..22aed37e --- /dev/null +++ b/bridge/idp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bridge/idp/NOTICE b/bridge/idp/NOTICE new file mode 100644 index 00000000..412b6090 --- /dev/null +++ b/bridge/idp/NOTICE @@ -0,0 +1,54 @@ +Kars Dex security rebuild + +Dex is an OpenID Connect identity provider originally developed by CoreOS, +maintained by the Dex project and its contributors: +https://github.com/dexidp/dex + +This package uses Dex v2.45.1 application source at commit +11d2eeb52b42e1980e14cb91e69dd9e3faab2076 under the Apache License, Version 2.0. +The unchanged upstream LICENSE is fetched from the verified source archive +and installed as /usr/share/doc/dex/DEX-LICENSE. + +This is NOT the official or unmodified upstream Dex image. Kars changes the +Go toolchain, module dependency manifests and container packaging, and marks +the binary version v2.45.1-kars.1. Two production calls in server/oauth2.go +now use a constant "%s" format to preserve preformatted error descriptions +literally and satisfy Go vet. These are the only production-source changes. +Production certificate validation, connectors, embedded web assets and real +CGO SQLite storage remain unchanged upstream implementations. + +A test-only patch validates the historical OAM SAML signature fixture at its +signed IssueInstant, using goxmldsig's supported test clock. Other signature +tests retain their real-clock default. The certificate and signed XML are not +changed. Added Go regressions exercise literal OAuth errors and enforce +certificate validity before/after the fixture certificate's lifetime. +The reviewed patches, regression sources and pinned before/after file hashes +are distributed in /usr/share/doc/dex/source-patches. Complete original and +expected patched source inventories are distributed as source.upstream.sha256 +and source.sha256 in /usr/share/doc/dex. + +The generated dependency diff, active patched module files, and byte-for-byte +original module baselines are distributed in /usr/share/doc/dex/locks. +The four archival baselines under locks/upstream use go.mod.snapshot and +go.sum.snapshot filenames, including the api/v2 subdirectory. They are +comparison/attribution data, never compiler inputs. This path-only distinction +preserves every original byte and SHA-256 while the active patched go.mod and +go.sum retain their normal filenames and full dependency/security scanning. +Linked dependency license and notice files are distributed in +/usr/share/doc/dex/third-party. + +The requested dependency graph now includes github.com/Azure/go-ntlmssp +v0.1.1 for CVE-2026-32952; the updated graph must be generated and verified +before a new image can be accepted. No other toolchain/base/crypto pin is +changed for this correction. The build retains the actual compiled-package +inventory as /usr/share/doc/dex/runtime-packages.json and fails if +golang.org/x/crypto/openpgp or a subpackage is linked (GO-2026-5932). +This does not suppress scanning of golang.org/x/crypto or any runtime module. + +The official image's gomplate and docker-entrypoint programs are intentionally +not distributed. The supported invocation is /usr/local/bin/dex serve with an +explicit configuration file, not upstream entrypoint template expansion. + +Kars packaging code: Copyright (c) Microsoft Corporation. +Licensed under the MIT License in the Kars repository root. +Azure Linux base contents and attribution remain unchanged. diff --git a/bridge/idp/README.md b/bridge/idp/README.md new file mode 100644 index 00000000..e34109d3 --- /dev/null +++ b/bridge/idp/README.md @@ -0,0 +1,511 @@ + + +# Kars Dex security rebuild + +**Status: NTLM security update pending hosted Go locks and full requalification.** +The exact request now includes `github.com/Azure/go-ntlmssp@v0.1.1` for +CVE-2026-32952. Existing previously qualified files under `locks/generated/` +remain byte-for-byte unchanged until a new hosted artifact is verified. +Consequently, their old request stamp does not satisfy the new request: +normal image/qualification builds must fail closed until reviewed new locks +are installed. No module checksums were edited by hand. +The successful hosted attempt on September 16, 2026 compiled Dex with CGO, +completed license collection, passed the compatibility cases, completed the +upstream root/API race-suite commands with exit code zero, passed all nine +signing-key-continuity regression subcases under the race detector, and compiled +the probe. Environment-dependent suite skips do not establish external +connector runtime coverage. + +That earlier result applies only to the old dependency graph. Its binary +digest `c4b5f8017cffb5e9853788a66cc1a1ce21104b9e4b4ba04901947d7510d5e4f9` +and publication payload expectations must **not** be reused for a rebuilt +NTLM-fixed image. Frozen operations artifacts remain unsubmitted and require +a new approved reference after fresh qualification. + +The required `idp` job in public Bridge CI builds the checked-in inputs +and executes the actual final distroless memory/SQLite/OIDC, linkage, inventory +and scan gates. That CI execution is still required; the earlier build/test +success is **not** final-image qualification or permission to deploy. This +wiring does not enable the optional IdP or change chart/default/installation +behavior. + +This is a packaging/dependency correction for the existing optional Dex IdP, +not another IdP or authentication framework. It starts from **Dex v2.45.1** +application source at +[`11d2eeb52b42e1980e14cb91e69dd9e3faab2076`](https://github.com/dexidp/dex/tree/11d2eeb52b42e1980e14cb91e69dd9e3faab2076). +The [stable release](https://github.com/dexidp/dex/releases/tag/v2.45.1) was +published March 3, 2026. The binary identifies itself as **v2.45.1-kars.1**, +and image labels and installed notices disclose both the dependency rebuild +and the bounded source changes. + +## Pinned inputs and security changes + +Public metadata was checked September 16, 2026. Pins are not a substitute for +a fresh final-image scan; a new advisory can block acceptance. + +| Input | Selected pin / reason | +| --- | --- | +| Dex source | `https://codeload.github.com/dexidp/dex/tar.gz/11d2eeb52b42e1980e14cb91e69dd9e3faab2076`, SHA-256 `18bf92e8ccbf53e86814c2beb39b7d59f28fb07c84639e9f47a9bb5ea764e0b9` (863,553 bytes when checked) | +| Compiler/builder | `golang:1.26.8-bookworm@sha256:9fdc884aacc3bec89b20ffc69f4bb369c78210e3e4f600387b5128b12c199f81` | +| Builder amd64 manifest | `sha256:bc6beb46032d45f421cf400036bf031cdc64f683ba9cdc124e31d063e71670bd` | +| Runtime | `mcr.microsoft.com/azurelinux/distroless/base:3.0@sha256:4377af4aa7a810b7d59f691eae5066895a71aa3eee4cfb4eba527bbebff16479` | +| Runtime amd64 manifest | `sha256:0198b6345e0aeffd6c2e455ebc4c74b1d644ac1dfcb5aa5236972f17fd281f27` | + +[Official Go download metadata](https://go.dev/dl/?mode=json&include=all) +selects **go1.26.8**, the latest stable 1.26 patch when checked. +[Release notes](https://go.dev/doc/devel/release#go1.26.8) date it September 1. +The official linux-amd64 Go archive SHA-256 is +`d0f743b33e8d8945e6b1f432edd15785c70507121d6e2a723b21285eddf8b57b`; +the Docker build uses the pinned official builder, not an unchecked download. +`GOTOOLCHAIN=local` forbids automatic replacement of the selected compiler. + +`locks/requests.txt` is a **resolution request, not a fake go.sum**: + +| Module | Upstream | Requested selection | Authoritative fix / dependency reason | +| --- | --- | --- | --- | +| `github.com/Azure/go-ntlmssp` | `v0.0.0-20221128193559-754e69321358` | 0.1.1 | [CVE-2026-32952 / GHSA-pjcq-xvwq-hhpj](https://github.com/advisories/GHSA-pjcq-xvwq-hhpj): malformed NTLM challenges can panic before 0.1.1 | +| `github.com/go-jose/go-jose/v4` | 4.1.3 | 4.1.4 | [GO-2026-4945](https://vuln.go.dev/ID/GO-2026-4945.json) | +| `github.com/russellhaering/goxmldsig` | 1.5.0 | 1.6.0 | [GO-2026-4753](https://vuln.go.dev/ID/GO-2026-4753.json) | +| `go.opentelemetry.io/otel`, `/metric`, `/trace` | 1.39.0 | 1.44.0 | [GO-2026-5506](https://vuln.go.dev/ID/GO-2026-5506.json) fixes 1.41; [GO-2026-5158](https://vuln.go.dev/ID/GO-2026-5158.json) and gRPC require 1.44 | +| `golang.org/x/crypto` | 0.48.0 | 0.56.0 | 0.55 fixes [GO-2026-6303](https://vuln.go.dev/ID/GO-2026-6303.json), but September advisories [GO-2026-6354](https://vuln.go.dev/ID/GO-2026-6354.json) / [6355](https://vuln.go.dev/ID/GO-2026-6355.json) require 0.56 | +| `golang.org/x/mod` | 0.32.0 | 0.40.0 | [GO-2026-6179](https://vuln.go.dev/ID/GO-2026-6179.json), [6180](https://vuln.go.dev/ID/GO-2026-6180.json) | +| `golang.org/x/net` | 0.50.0 | 0.58.0 | 0.56 fixes [GO-2026-5942](https://vuln.go.dev/ID/GO-2026-5942.json); gRPC requires 0.58 | +| `golang.org/x/text` | 0.34.0 | 0.41.0 | 0.39 fixes [GO-2026-5970](https://vuln.go.dev/ID/GO-2026-5970.json); gRPC/crypto require 0.41 | +| `google.golang.org/grpc` | 1.79.1 | 1.83.2 | [Stable security release](https://github.com/grpc/grpc-go/releases/tag/v1.83.2), [GO-2026-6443](https://vuln.go.dev/ID/GO-2026-6443.json) explicitly fixes the 1.83 branch in 1.83.2 | + +The exact module manifests are public at +`https://proxy.golang.org//@v/.mod`; their `.info` siblings +record upstream commit and publication metadata. +[gRPC 1.83.2](https://proxy.golang.org/google.golang.org/grpc/@v/v1.83.2.mod) +requires Go 1.25 and raises OTel/net/text. +[crypto 0.56.0](https://proxy.golang.org/golang.org/x/crypto/@v/v0.56.0.mod) +requires **Go 1.26.0**, so both root and nested API module directives are +deliberately raised from upstream's 1.25.0 / 1.24.0 to 1.26.0. The root's +`replace github.com/dexidp/dex/api/v2 => ./api/v2` is retained. +`x/mod` also requires `x/tools` 0.49.0; let Go resolve the full graph rather +than hand-editing transitive versions or checksums. + +Only the separate **`Dockerfile.locks`** maintenance recipe runs `go get` with exact +versions, followed by real `go mod tidy`, `download`, `verify` and `list`. +It uses the public checksum database and proxy without private configuration. +The image build only consumes the reviewed artifact with `-mod=readonly`; +it never runs `go get latest`, `tidy`, version selection or source generation. +The recipes are separate files, not just unrelated stages: legacy Docker +builders execute preceding stages even when the selected target does not +depend on them. Their pinned source/compiler stage is checked for consistency. +An unexpectedly higher MVS selection fails validation and needs review, not +a forced downgrade or a scanner waiver. + +### NTLM update and package-scoped OpenPGP evidence + +The exact NTLM release is +[`bd8579c18d41bf5d91a5f74b1117c958f635b866`](https://github.com/Azure/go-ntlmssp/tree/bd8579c18d41bf5d91a5f74b1117c958f635b866). +Its [module metadata](https://proxy.golang.org/github.com/!azure/go-ntlmssp/@v/v0.1.1.mod) +requires Go 1.24 and declares no module dependencies, compatible with the +unchanged Go 1.26.8 builder. The hosted upstream-tests stage requires the +actual `TestNewAuthenticateMessage_ChallengeTargetInfoOffsetOverflowNoPanics` +regression to be registered, then runs `go test -json -count=1 -race +github.com/Azure/go-ntlmssp/...`. The actual JSON is retained as +`/out/doc/ntlm-tests.json` in the test image and printed into the existing +upstream build log. Standard IIS E2E cases retain their upstream +environment-dependent skips; no IIS credentials or new provider prerequisite +is introduced. + +[GO-2026-5932](https://vuln.go.dev/ID/GO-2026-5932.json) concerns +`golang.org/x/crypto/openpgp` and its subpackages, not every package in +`golang.org/x/crypto`. The crypto pin remains **v0.56.0**, with no module +suppression, exclusion or waiver. + +Each build now retains the actual +`go list -deps -json=ImportPath,Module ./cmd/dex` result as +`/usr/share/doc/dex/runtime-packages.json`. It records runtime package paths +and their selected modules without test-only or tool-only packages. The +build-time notice collector rejects an empty/wrong-target inventory and +fatally rejects `golang.org/x/crypto/openpgp` or any descendant import path +before completing the image. Other crypto packages remain allowed and +scanned. The same inventory supplies license collection; existing `LICENCE` +handling is preserved. This is package-inclusion evidence and a future +introduction guard, **not** a scanner filter or proof that a pending build +has already passed. + +## Disclosed source compatibility patches + +The original upstream commit and archive SHA-256 have **not** changed. +No new dependency versions, module locks, compiler pins or base images are +introduced by these compatibility corrections. + +| Reviewed input | Scope and reason | +| --- | --- | +| `patches/0001-literal-oauth-error-descriptions.patch` | Exactly two production calls in `server/oauth2.go`, originally lines 477 and 561, pass already-built descriptions as `"%s", description` / `"%s", err`. This satisfies Go vet and preserves literal percent characters instead of formatting the text twice. Error type, state, redirect URI and authorization decisions are unchanged. | +| `patches/0002-saml-fixture-validation-clock.patch` | Test-only change to `connector/saml/saml_test.go`. Only `TestVerifyUnsignedMessageAndSignedAssertionWithRootXmlNs` opts into a validation clock at the signed XML's `2016-12-12T16:54:35Z` IssueInstant. Existing helper callers keep a nil clock, which means the real clock. | +| `patches/server_compat_test.go` | Installed into the fetched source as `server/kars_compat_test.go`; exercises the real authorization parser, including literal `%s%[1]s%%` input and the out-of-band redirect error. | +| `patches/saml_compat_test.go` | Installed as `connector/saml/kars_compat_test.go`; the real signature verifier must accept the unchanged signed assertion at fixture time and reject it before certificate validity and after expiry. | + +The OAM fixture certificate is valid from **2016-06-30T04:54:16Z** through +**2026-06-28T04:54:16Z**. Its signed XML's IssueInstant is inside that interval. +This is an XML namespace/signature fixture, not a wall-clock expiry test. +The supported test-clock API is +[`NewFakeClockAt`](https://github.com/russellhaering/goxmldsig/blob/878c8c615feb628064040115d00e105a137fcfa7/clock.go); +[production validation](https://github.com/russellhaering/goxmldsig/blob/878c8c615feb628064040115d00e105a137fcfa7/validate.go) +still enforces the trusted certificate's `NotBefore` and `NotAfter`. +No certificate, signed XML, production SAML code, trust setting or vet setting +is weakened or replaced. + +`patches/SHA256SUMS` pins the patch order, both patches, regression sources and +the before/after file-hash manifests. The source stage first verifies the +original archive, inventories and verifies the **original** source, then +applies the reviewed patches with `git apply`. It verifies the reviewed post-patch hashes and +derives the expected `source.sha256` from the original inventory plus only +the four declared changed/added files. It compares that expected inventory +against the entire actual source inventory, rejecting additional files, +missing files, tampered patches, drift and double application. +Only the four dependency manifests are excluded from source inventory, as +before; they are independently checked against the generated Go locks. +The changed source files are **not** excluded or accepted by recomputing +their expected hashes from whatever a patch happens to produce. + +Original and patched source inventories and the complete disclosed patch +bundle are included in `/usr/share/doc/dex/`. The British-spelled `LICENCE` +handling in the dependency-notice collector is preserved. + +Source-only integrity checks (no Go compilation, bounded public download): + +```sh +PYTHONDONTWRITEBYTECODE=1 KARS_DEX_PATCH_NETWORK=1 \ + python3 -m unittest discover -s bridge/idp/tests -p 'test_*.py' +``` + +Without that opt-in, offline source contracts still run; actual patch-application +tests are reported as skipped. Neither mode is a replacement for the hosted +Go behavior regressions or runtime qualification. + +## Compatibility and shipping boundary + +The entrypoint is `/usr/local/bin/dex`; default arguments are +`serve /etc/dex/config.yaml`, matching the existing chart's direct command. +No config, client secret, test password, unsafe issuer or auth defaults ship. +The operator must mount an explicit configuration. `secretEnv`, bcrypt +`staticPasswords`, memory storage, Authorization Code + PKCE, nonce and JWKS +are unchanged upstream implementations. + +**CGO remains enabled for Dex.** No SQLite stub, `CGO_ENABLED=0`, custom +exclusion tags, static-glibc shortcut or connector removal is used to make a +scan pass. The Bookworm builder has an older glibc baseline than Azure Linux 3; +this is a compatibility premise, not proof of the actual native closure. +The shipping image copies **no Debian shared libraries**, compiler, shell, +package manager or build cache. Its loader and libraries must come from the +pinned Azure Linux base; hosted tests verify this and run real SQLite. +Build each platform on a native worker. Initial qualification is linux/amd64; +the multi-arch input indexes do not imply an arm64 qualification. + +The complete upstream `web/` tree remains at `/srv/dex/web`, in addition to +the normal compiled web assets. Upstream connectors and storage source remain +unchanged. Only the official image's unused `docker-entrypoint` and `gomplate` +programs are omitted: template expansion through that wrapper is **not** +supported by this package. Direct Dex features are not replaced or removed. + +Azure Linux's **14 RPM inventory records**, base files and CA trust are +retained rather than reconstructed. The final image installs the upstream +Apache-2.0 license, this package's MIT license, attribution, original module +snapshots, active patched module files, dependency diff, Go build metadata and ELF metadata under +`/usr/share/doc/dex/`. A build-time collector retains license/notice files +from linked modules (including bundled notices), and fails for missing root +licenses rather than silently shipping incomplete attribution. License review +of the generated graph and bundled native code is still an acceptance gate. + +## Active locks versus archival baseline data + +The verified hosted artifact's four historical module baselines are now +explicit **data snapshots**, not active Go manifests. The change is a +deterministic path-only migration of the already-verified artifact: all four +file contents and SHA-256 values are unchanged, and only their four paths +change in `locks/generated/SHA256SUMS`. No Go resolution, dependency update, +compiler/base change, exclusion, waiver or vulnerability suppression is involved. + +Under `bridge/idp/locks/generated/upstream/`: + +| Original archival path | Current data path | +| --- | --- | +| `go.mod` | `go.mod.snapshot` | +| `go.sum` | `go.sum.snapshot` | +| `api/v2/go.mod` | `api/v2/go.mod.snapshot` | +| `api/v2/go.sum` | `api/v2/go.sum.snapshot` | + +The active patched `locks/generated/go.mod`, `go.sum`, `api/v2/go.mod` and +`api/v2/go.sum` retain their normal filenames, original patched bytes and full +dependency/security scanning. Module inventories, graph, dependency diff, +inputs, toolchain record and all other generated artifact contents are +unchanged. The saved historical baselines are used only for byte comparison, +diffing and attribution; the build still copies **only active locks** into +the Go source tree. + +This distinction prevents dependency discovery from mistaking archived +upstream dependencies for new active dependencies. Actual runtime dependencies +and their final-image vulnerability scans remain fully enforced. The runtime +metadata copy preserves the same data suffixes under +`/usr/share/doc/dex/locks/upstream/`. + +The original raw hosted-generation log remains unchanged outside the repository +as provenance, with its original transport hash and original archive member +names. `dependencies.patch` also keeps its logical `upstream/go.mod` and +`upstream/api/v2/go.mod` source labels; those labels are not stored manifest +files or compile inputs. Future generation emits the new snapshot layout +directly. The importer and validator require that layout and reject legacy or +mixed active-looking baseline names; do not overwrite the migrated files by +reimporting an old-layout log or re-resolving dependencies. + +Representation contracts compare every generated file digest with the +pre-migration verified artifact, require exactly four normally named active +Go locks, and exercise archive import/rejection. With the verified-archive +source tests enabled, each baseline snapshot is also compared byte-for-byte +with its original file from the pinned upstream tarball. + +## Hosted lock generation + +Local Docker and Go were unavailable and disk was below the 8.5 GiB floor. +Do not install Go, compile, populate a global cache or run these builds locally. +The following task uses an operator-approved ACR's compute but **does not push +an image**, deploy, or touch cluster state. +The context is this public-only directory, not private repository config. + +For the current NTLM change, use the concrete staged-review procedure below; +do not remove or overwrite the currently qualified generated locks merely +to make the default importer run. + +From the public Kars worktree root, set `SUBSCRIPTION_ID`, `ACR_NAME` and +`ARTIFACT_DIR` to approved operator values. Keep the artifact directory private. + +```sh +( + cd bridge/idp + az acr build \ + --subscription "$SUBSCRIPTION_ID" --registry "$ACR_NAME" \ + --platform linux/amd64 --no-push --timeout 3600 \ + --target lock-generation --file Dockerfile.locks . +) > "$ARTIFACT_DIR/dex-lock-generation.log" 2>&1 +``` + +`Dockerfile.locks` pins all public execution/source inputs above. This target +does **module metadata/source resolution only**, not Dex compilation or tests. +It uses only worker-owned `/work/mod` and `/work/cache`. Do not add registry +push credentials, Azure credentials, build secrets or private Go settings. +The log contains one public tar.gz artifact between +`KARS_DEX_LOCKS_BASE64_BEGIN` / `KARS_DEX_LOCKS_BASE64_END`, followed by its +transport SHA-256. Retain the ACR run ID and original log as provenance. + +```sh +python3 bridge/idp/scripts/import-locks.py "$ARTIFACT_DIR/dex-lock-generation.log" +PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s bridge/idp/tests -p 'test_*.py' +``` + +The importer checks the logged transport SHA-256 as well as the member +checksums. It rejects unsafe members, duplicate/incomplete files, oversized +archives, checksum/input drift, module resolver errors, duplicate module records, +unexpected toolchains and unreviewed module selections; it does not +overwrite existing locks. If ACR log delivery prefixes/truncates the artifact, +retrieve the **raw run log** rather than repairing checksums or guessing files. +Alternatively, on an approved hosted BuildKit worker: + +```sh +docker buildx build --platform linux/amd64 --target lock-artifact \ + --output "type=local,dest=$ARTIFACT_DIR/dex-locks" \ + --file bridge/idp/Dockerfile.locks bridge/idp +``` + +Artifact contents are the generated root/API `go.mod` and `go.sum`, +`modules.json`, `api-modules.json`, `graph.txt`, `toolchain.txt`, +`inputs.lock`, `requests.txt`, `dependencies.patch`, the four byte-unchanged +`upstream/` baseline data files (`go.mod.snapshot` / `go.sum.snapshot` at the +root and under `api/v2`), and `SHA256SUMS`. Review and persist these under +`bridge/idp/locks/generated/` before any runtime build. Generated module +checksums are Go's, not fabricated or transcribed from vulnerability reports. +On a second clean **native worker of the same architecture**, replay the +resolver without its cache and compare the entire reviewed artifact: + +```sh +docker build --no-cache --target lock-replay \ + --file bridge/idp/Dockerfile.locks bridge/idp +``` + +The non-shipping artifact and replay stages default to `1001:1001`. Both sets +of replay inputs are copied with that ownership, without changing lock bytes +or applying `chmod` to upstream data. Replay asserts its actual UID/GID before +running the read-only checksum comparisons. In `Dockerfile.locks`, root is +retained only in the source/resolution stages that need build-directory writes. + +The replay target verifies both checksum inventories and requires exact +agreement for the root/API locks, selected module graphs, source snapshots, +dependency diff, inputs and toolchain record. Retain the build log with +`KARS_DEX_LOCK_REPLAY_PASSED`. A replay failure is a real reproducibility +blocker, not permission to overwrite the reviewed locks. Use a native Docker worker or an ACR task exposing Docker's `--no-cache` +option for this independent replay; do not assume the quick-build CLI exposes +that option. Neither replay nor generation is reachable from the normal +`Dockerfile`. + +### Parent-only no-push NTLM lock-generation and review + +Set `SUBSCRIPTION_ID`, `ACR_NAME` and an existing `ARTIFACT_DIR` **outside the +source checkout** to approved operator values. The task below only resolves +the exact requested Go graph on the pinned worker image; it does not build or +push a Dex image. Only the parent submits it. + +```sh +( + cd bridge/idp + az acr build \ + --subscription "$SUBSCRIPTION_ID" --registry "$ACR_NAME" \ + --platform linux/amd64 --no-push --timeout 3600 \ + --target lock-generation --file Dockerfile.locks . +) > "$ARTIFACT_DIR/ntlm-lock-generation.log" 2>&1 + +PYTHONDONTWRITEBYTECODE=1 python3 bridge/idp/scripts/import-locks.py \ + "$ARTIFACT_DIR/ntlm-lock-generation.log" \ + --output "$ARTIFACT_DIR/ntlm-reviewed-locks" +``` + +`--output` validates the complete archive, current request stamp and exact +selected versions in a temporary sibling, then creates a new review +directory. It refuses any existing output and any alternate location inside +the source checkout. Failed/stale artifacts leave both the proposed output +and existing qualified locks untouched. + +Before promotion, review the generated root/API manifests, sums, module +inventories, graph and `dependencies.patch`. Confirm NTLM is exactly v0.1.1, +the crypto/toolchain/base/source pins are unchanged, and original `.snapshot` +baselines still match their pinned upstream bytes. Keep the old artifact and +raw generation logs outside the repository as historical provenance. Only +after that review may the parent replace `locks/generated/` with the verified +new artifact; this source change does not perform that replacement. + +Then rerun source contracts, the hosted notice-guard Go tests, NTLM package +regressions, compatibility/root/API/probe race suites, the full actual +distroless runtime qualifier and fresh scans. Require zero HIGH/CRITICAL +findings **and** confirmed resolution of the current NTLM advisory. Retain +the new package inventory and establish a new binary/payload reference. +The prior green checks and old binary hash do not qualify this update. + +## Required Bridge CI qualification + +[Bridge CI](../../.github/workflows/bridge-ci.yml) adds **Dex IdP runtime +qualification** (`idp`) to the existing **Bridge component acceptance** +aggregate. Missing, failed, cancelled or skipped IdP results fail that +aggregate; existing component checks remain required. The job has only +`contents: read`, builds on native amd64 Ubuntu Docker compute, and does not +log in to a registry, push an image or deploy cloud/cluster resources. + +The job runs source contracts with the verified-archive checks enabled and +explicitly validates the actual generated module locks. It builds +`upstream-tests`, `test-tools` and `runtime` from this directory. An owned +temporary container supplies the upstream root/API JSON reports; each report +must be complete and contain no failures. The summary records actual passing +test counts, package results and every skip, including packages with no test +files, without claiming that unconfigured LDAP/cloud integrations ran. + +The existing SHA-pinned Trivy action installs **0.70.0** and performs an initial +actual-image scan. The job discovers its executable using `command -v trivy`, +checks its version, and passes that path to `tests/qualify.py`. The harness +executes the real memory/SQLite/static-OIDC and key-continuity checks plus +native linkage, all base inventory/CA checks, and a separate strict scan with +a fresh cache and current DB. It still runs after an initial scan finding to +retain useful diagnostics; **both scan failures remain fatal**, with no +`continue-on-error` or alternate success path. + +The always-uploaded `bridge-idp-qualification--` artifact +contains source/build/probe/harness logs, upstream/API JSON and skip summary, +image provenance, discovered Trivy version/path, per-step outcomes, initial +scan JSON and all runtime evidence produced before success or failure. A failed +build retains its failure log instead of fabricating a completed test report. +Partial artifacts and upstream test success are not runtime qualification; +the harness's `runtime/runtime-passed.json` covers only its named gates, and +the overall job and aggregate must also succeed. + +## Hosted acceptance gates + +First run the focused compatibility target on approved hosted compute. The +subscription/registry/artifact values remain operator parameters; this example +does not push an image: + +```sh +( + cd bridge/idp + az acr build \ + --subscription "$SUBSCRIPTION_ID" --registry "$ACR_NAME" \ + --platform linux/amd64 --no-push --timeout 3600 \ + --target compatibility-tests --file Dockerfile . +) > "$ARTIFACT_DIR/dex-compatibility.log" 2>&1 +``` + +That target runs the real server/SAML regressions with race detection and vet +enabled. The earlier hosted attempt already passed those build/test stages; +the commands remain available to reproduce them before running the actual +runtime harness. The narrower target alone is not acceptance. Legacy ACR builders execute +preceding stages on the way to `test-tools`; the compatibility/upstream stages +are intentionally retained rather than reordered to conceal failures. + +On a **native Linux Docker worker with sufficient disk**, build the reviewed +context; examples below are local worker tags, never a publication: + +```sh +docker build --target compatibility-tests -t kars-dex-compat:latest bridge/idp +docker build --target upstream-tests -t kars-dex-tests:latest bridge/idp +docker build --target test-tools -t kars-dex-tools:latest bridge/idp +docker build --target runtime -t kars-dex:latest bridge/idp +trivy_path="$(command -v trivy)" +test -x "$trivy_path" +"$trivy_path" --version +python3 bridge/idp/tests/qualify.py \ + --image kars-dex:latest --tools-image kars-dex-tools:latest \ + --trivy "$trivy_path" \ + --evidence "$ARTIFACT_DIR/dex-runtime" +``` + +The runtime harness uses image IDs after resolving tags, private ephemeral +Docker networks/volumes, randomly generated test-only credentials, nonroot +read-only Dex containers, no capabilities and no-new-privileges. It cleans up +only its own uniquely named containers, networks, volumes and temporary files. +Test config and the external probe **never** enter the shipping image. + +Required evidence before parent acceptance: + +1. **Full upstream root/API suites** with race detection, retained JSON reports + (`/out/doc/upstream-tests.json`, `/out/doc/api-tests.json` in the test image). + Review and report every skip and remaining integration limit. Execute the + configured memory/SQLite/OIDC paths and relevant configured connector + integrations. Unconfigured external services do not become additional beta + prerequisites, but a skipped integration is not evidence of runtime + compatibility. Real code and compile/unit coverage remain; no production + service implementation is stubbed by this packaging. +2. **Real final-image runtime checks:** discovery, HTML password login, bcrypt, + `secretEnv` client authentication, S256 PKCE, JWKS RSA signature and + issuer/audience/nonce/expiry claims, userinfo, incorrect password/client + secret/verifier rejection, authorization-code replay rejection. Run all + against memory and SQLite. After SQLite restart, verify the old unexpired + ID token against restarted JWKS and the saved verified signing-key identity + before using the earlier refresh token. Retained old keys across legitimate + rotation must pass; missing/replaced keys must fail even if refresh works. +3. **Native closure and runtime contents:** ELF interpreter from the Azure Linux + base, its real `--list` output, successful native execution, unchanged base + file hashes/links and CA trust, all 14 RPM records, and no copied library + closure or extra tools. Docker's injected hosts/hostname/resolv.conf are the + only per-container export exclusions. +4. **Trivy 0.70.0, latest DB, zero HIGH/CRITICAL** across the final OS and Dex + binary. The harness uses a fresh cache, empty ignore/config files, explicit + vulnerability scanning, no ignored/unfixed exemptions, and requires + recognized Azure Linux inventory plus Go binary inventory. Persist JSON, + scanner/DB metadata, immutable image ID and ELF reports. Unknown/unscanned + payload is failure, not a clean report. +5. **Independent reproducibility and licenses:** rebuild without cache on a + second clean native worker and compare `/usr/local/bin/dex` SHA-256 plus + web/license/dependency payloads. Container export timestamps/image IDs alone + are not the reproducibility criterion. Review all dependency changes, + licenses and bundled SQLite attribution. +6. **Configured connector and beta integration checks** belong to the parent, + including genuine auth/native enrollment. Packaging probes do not diagnose + that flow and do not authorize shared chart/default/workflow changes. + +`runtime-passed.json` covers only the runtime harness's named gates, not full +qualification. No acceptance/publication/deployment status is implied by +source contracts, a generated lockfile, a successful compiler exit or a +scanner version floor. Any new vulnerability or compatibility failure blocks +acceptance and needs a real, disclosed correction. diff --git a/bridge/idp/locks/generated/SHA256SUMS b/bridge/idp/locks/generated/SHA256SUMS new file mode 100644 index 00000000..5efc481b --- /dev/null +++ b/bridge/idp/locks/generated/SHA256SUMS @@ -0,0 +1,15 @@ +4a7bed6907c8f8918791e69539597405d6ad18f3f386788a81ed28f024113ac8 ./api-modules.json +e304bf72c1bf687cf777af1ca1c70d96e928a86bfb40bc6d5aeb8239baac24f6 ./api/v2/go.mod +3410f76108a083dc3a603327c354639a078ee8d917146aa7bf769e37cce0f208 ./api/v2/go.sum +dd23e549cea30d69b362925e0253d6da392ba9cc0eb507816885c431aa7fb307 ./dependencies.patch +62b200f67cd9692cdd5bb7f568adeb5a3c8997bd004f835df519eeb466cb2b07 ./go.mod +c7ff038490b371cae3f016e749214f05366638234e705c7e13f527cb25710f64 ./go.sum +c0f24094a89a13e270701ce531bf3b4d4225d70da78243915a2c772fcb470c25 ./graph.txt +d5a430f8c8fea443ebc134cff29ddc0914bdc7acc1220fce9073c439e1a780d6 ./inputs.lock +db04d9e4cbbd669a29040abfe5f04e9f8c3b08bc6e9e68e6c2cbc473ca632216 ./modules.json +e5fe468d767406cd3cfcbd6f3063240e1e51bba644f3c0ae75f657a319083008 ./requests.txt +7e35a947feee25f89c2649aa041942db786be35c3d6c484ab2ba2da849e3dc00 ./toolchain.txt +181fc42a509297fe685e3470388d378a229e6efd36dd874eef809b6e06fe41e8 ./upstream/api/v2/go.mod.snapshot +ccf35830330ac8058a4f009babbb417039aec728cf92625572abc53474c5dfca ./upstream/api/v2/go.sum.snapshot +3390a3a2aa213fa80b7cb857ae52eb031e0f1941292f3536951092acb1db1501 ./upstream/go.mod.snapshot +09fab6a9bedf5e220ee82f75f8fc7db4f52854012875082f24ba629020980d13 ./upstream/go.sum.snapshot diff --git a/bridge/idp/locks/generated/api-modules.json b/bridge/idp/locks/generated/api-modules.json new file mode 100644 index 00000000..f72cc83a --- /dev/null +++ b/bridge/idp/locks/generated/api-modules.json @@ -0,0 +1,421 @@ +{ + "Path": "github.com/dexidp/dex/api/v2", + "Main": true, + "Dir": "/src/dex/api/v2", + "GoMod": "/src/dex/api/v2/go.mod", + "GoVersion": "1.26.0" +} +{ + "Path": "cel.dev/expr", + "Version": "v0.25.2", + "Time": "2026-03-12T16:46:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cel.dev/expr/@v/v0.25.2.mod", + "GoVersion": "1.23.0" +} +{ + "Path": "cloud.google.com/go/auth", + "Version": "v0.18.2", + "Time": "2026-02-13T17:14:27Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cloud.google.com/go/auth/@v/v0.18.2.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "cloud.google.com/go/compute/metadata", + "Version": "v0.9.0", + "Time": "2025-09-24T19:41:55Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cloud.google.com/go/compute/metadata/@v/v0.9.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp", + "Version": "v1.33.0", + "Time": "2026-06-04T20:21:43Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/!google!cloud!platform/opentelemetry-operations-go/detectors/gcp/@v/v1.33.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "github.com/cespare/xxhash/v2", + "Version": "v2.3.0", + "Time": "2024-04-04T20:00:10Z", + "Indirect": true, + "Dir": "/work/mod/github.com/cespare/xxhash/v2@v2.3.0", + "GoMod": "/work/mod/cache/download/github.com/cespare/xxhash/v2/@v/v2.3.0.mod", + "GoVersion": "1.11", + "Sum": "h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=", + "GoModSum": "h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=" +} +{ + "Path": "github.com/cncf/xds/go", + "Version": "v0.0.0-20260202195803-dba9d589def2", + "Time": "2026-02-02T19:58:03Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/cncf/xds/go/@v/v0.0.0-20260202195803-dba9d589def2.mod", + "GoVersion": "1.24.6" +} +{ + "Path": "github.com/envoyproxy/go-control-plane", + "Version": "v0.14.0", + "Time": "2025-11-04T22:01:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/@v/v0.14.0.mod", + "GoVersion": "1.23.0" +} +{ + "Path": "github.com/envoyproxy/go-control-plane/envoy", + "Version": "v1.37.0", + "Time": "2026-01-13T06:26:49Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/envoy/@v/v1.37.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/envoyproxy/go-control-plane/ratelimit", + "Version": "v0.1.0", + "Time": "2024-12-23T15:25:59Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/ratelimit/@v/v0.1.0.mod", + "GoVersion": "1.21" +} +{ + "Path": "github.com/envoyproxy/protoc-gen-validate", + "Version": "v1.3.3", + "Time": "2026-02-18T16:13:16Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/protoc-gen-validate/@v/v1.3.3.mod", + "GoVersion": "1.24.1" +} +{ + "Path": "github.com/felixge/httpsnoop", + "Version": "v1.0.4", + "Time": "2023-03-12T10:31:09Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/felixge/httpsnoop/@v/v1.0.4.mod", + "GoVersion": "1.13" +} +{ + "Path": "github.com/go-jose/go-jose/v4", + "Version": "v4.1.4", + "Time": "2026-03-31T23:33:50Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/go-jose/go-jose/v4/@v/v4.1.4.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/go-logr/logr", + "Version": "v1.4.3", + "Time": "2025-05-19T04:56:57Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-logr/logr@v1.4.3", + "GoMod": "/work/mod/cache/download/github.com/go-logr/logr/@v/v1.4.3.mod", + "GoVersion": "1.18", + "Sum": "h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=", + "GoModSum": "h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=" +} +{ + "Path": "github.com/go-logr/stdr", + "Version": "v1.2.2", + "Time": "2021-12-14T08:00:35Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-logr/stdr@v1.2.2", + "GoMod": "/work/mod/cache/download/github.com/go-logr/stdr/@v/v1.2.2.mod", + "GoVersion": "1.16", + "Sum": "h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=", + "GoModSum": "h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=" +} +{ + "Path": "github.com/golang/glog", + "Version": "v1.2.5", + "Time": "2025-04-29T08:43:26Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/golang/glog/@v/v1.2.5.mod", + "GoVersion": "1.19" +} +{ + "Path": "github.com/golang/protobuf", + "Version": "v1.5.4", + "Time": "2024-03-06T06:45:40Z", + "Indirect": true, + "Dir": "/work/mod/github.com/golang/protobuf@v1.5.4", + "GoMod": "/work/mod/cache/download/github.com/golang/protobuf/@v/v1.5.4.mod", + "GoVersion": "1.17", + "Sum": "h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=", + "GoModSum": "h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=" +} +{ + "Path": "github.com/google/go-cmp", + "Version": "v0.7.0", + "Time": "2025-01-14T18:15:44Z", + "Indirect": true, + "Dir": "/work/mod/github.com/google/go-cmp@v0.7.0", + "GoMod": "/work/mod/cache/download/github.com/google/go-cmp/@v/v0.7.0.mod", + "GoVersion": "1.21", + "Sum": "h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=", + "GoModSum": "h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=" +} +{ + "Path": "github.com/google/s2a-go", + "Version": "v0.1.9", + "Time": "2025-01-06T17:53:46Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/google/s2a-go/@v/v0.1.9.mod", + "GoVersion": "1.20" +} +{ + "Path": "github.com/google/uuid", + "Version": "v1.6.0", + "Time": "2024-01-23T18:54:04Z", + "Indirect": true, + "Dir": "/work/mod/github.com/google/uuid@v1.6.0", + "GoMod": "/work/mod/cache/download/github.com/google/uuid/@v/v1.6.0.mod", + "Sum": "h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=", + "GoModSum": "h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=" +} +{ + "Path": "github.com/googleapis/enterprise-certificate-proxy", + "Version": "v0.3.11", + "Time": "2026-01-13T07:11:36Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/googleapis/enterprise-certificate-proxy/@v/v0.3.11.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/googleapis/gax-go/v2", + "Version": "v2.17.0", + "Time": "2026-02-03T18:41:38Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/googleapis/gax-go/v2/@v/v2.17.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/planetscale/vtprotobuf", + "Version": "v0.6.1-0.20240319094008-0393e58bdf10", + "Time": "2024-03-19T09:40:08Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/planetscale/vtprotobuf/@v/v0.6.1-0.20240319094008-0393e58bdf10.mod", + "GoVersion": "1.20" +} +{ + "Path": "github.com/spiffe/go-spiffe/v2", + "Version": "v2.7.0", + "Time": "2026-06-03T20:07:47Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/spiffe/go-spiffe/v2/@v/v2.7.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "go.opentelemetry.io/auto/sdk", + "Version": "v1.2.1", + "Time": "2025-09-15T16:53:44Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/auto/sdk@v1.2.1", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/auto/sdk/@v/v1.2.1.mod", + "GoVersion": "1.24.0", + "Sum": "h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=", + "GoModSum": "h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=" +} +{ + "Path": "go.opentelemetry.io/contrib/detectors/gcp", + "Version": "v1.44.0", + "Time": "2026-05-28T05:28:14Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/contrib/detectors/gcp/@v/v1.44.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", + "Version": "v0.61.0", + "Time": "2025-05-22T14:29:43Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/@v/v0.61.0.mod", + "GoVersion": "1.23.0" +} +{ + "Path": "go.opentelemetry.io/otel", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=", + "GoModSum": "h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=" +} +{ + "Path": "go.opentelemetry.io/otel/metric", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/metric@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/metric/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=", + "GoModSum": "h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=" +} +{ + "Path": "go.opentelemetry.io/otel/sdk", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/sdk@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/sdk/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=", + "GoModSum": "h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=" +} +{ + "Path": "go.opentelemetry.io/otel/sdk/metric", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/sdk/metric@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/sdk/metric/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=", + "GoModSum": "h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=" +} +{ + "Path": "go.opentelemetry.io/otel/trace", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/trace@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/trace/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=", + "GoModSum": "h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=" +} +{ + "Path": "golang.org/x/crypto", + "Version": "v0.55.0", + "Time": "2026-08-11T17:56:31Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/crypto/@v/v0.55.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/mod", + "Version": "v0.38.0", + "Time": "2026-07-08T15:41:22Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/mod/@v/v0.38.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/net", + "Version": "v0.58.0", + "Time": "2026-08-12T17:41:32Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/net@v0.58.0", + "GoMod": "/work/mod/cache/download/golang.org/x/net/@v/v0.58.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=", + "GoModSum": "h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=" +} +{ + "Path": "golang.org/x/oauth2", + "Version": "v0.36.0", + "Time": "2026-02-11T19:14:10Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/oauth2/@v/v0.36.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/sync", + "Version": "v0.22.0", + "Time": "2026-07-01T17:29:34Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/sync/@v/v0.22.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/sys", + "Version": "v0.47.0", + "Time": "2026-06-30T17:07:31Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/sys@v0.47.0", + "GoMod": "/work/mod/cache/download/golang.org/x/sys/@v/v0.47.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=", + "GoModSum": "h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=" +} +{ + "Path": "golang.org/x/term", + "Version": "v0.45.0", + "Time": "2026-07-08T15:40:56Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/term/@v/v0.45.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/text", + "Version": "v0.41.0", + "Time": "2026-08-11T15:22:47Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/text@v0.41.0", + "GoMod": "/work/mod/cache/download/golang.org/x/text/@v/v0.41.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=", + "GoModSum": "h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=" +} +{ + "Path": "golang.org/x/tools", + "Version": "v0.48.0", + "Time": "2026-07-09T02:42:41Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/tools/@v/v0.48.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "gonum.org/v1/gonum", + "Version": "v0.17.0", + "Time": "2025-12-29T19:16:44Z", + "Indirect": true, + "Dir": "/work/mod/gonum.org/v1/gonum@v0.17.0", + "GoMod": "/work/mod/cache/download/gonum.org/v1/gonum/@v/v0.17.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=", + "GoModSum": "h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=" +} +{ + "Path": "google.golang.org/genproto/googleapis/api", + "Version": "v0.0.0-20260526163538-3dc84a4a5aaa", + "Time": "2026-05-26T16:35:38Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/googleapis/api/@v/v0.0.0-20260526163538-3dc84a4a5aaa.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "google.golang.org/genproto/googleapis/rpc", + "Version": "v0.0.0-20260526163538-3dc84a4a5aaa", + "Time": "2026-05-26T16:35:38Z", + "Indirect": true, + "Dir": "/work/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa", + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/googleapis/rpc/@v/v0.0.0-20260526163538-3dc84a4a5aaa.mod", + "GoVersion": "1.25.0", + "Sum": "h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=", + "GoModSum": "h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=" +} +{ + "Path": "google.golang.org/grpc", + "Version": "v1.83.2", + "Time": "2026-08-25T15:47:16Z", + "Dir": "/work/mod/google.golang.org/grpc@v1.83.2", + "GoMod": "/work/mod/cache/download/google.golang.org/grpc/@v/v1.83.2.mod", + "GoVersion": "1.25.0", + "Sum": "h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=", + "GoModSum": "h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=" +} +{ + "Path": "google.golang.org/protobuf", + "Version": "v1.36.11", + "Time": "2025-12-12T08:48:31Z", + "Dir": "/work/mod/google.golang.org/protobuf@v1.36.11", + "GoMod": "/work/mod/cache/download/google.golang.org/protobuf/@v/v1.36.11.mod", + "GoVersion": "1.23", + "Sum": "h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=", + "GoModSum": "h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=" +} diff --git a/bridge/idp/locks/generated/api/v2/go.mod b/bridge/idp/locks/generated/api/v2/go.mod new file mode 100644 index 00000000..a48b6ec0 --- /dev/null +++ b/bridge/idp/locks/generated/api/v2/go.mod @@ -0,0 +1,17 @@ +module github.com/dexidp/dex/api/v2 + +go 1.26.0 + +toolchain go1.26.8 + +require ( + google.golang.org/grpc v1.83.2 + google.golang.org/protobuf v1.36.11 +) + +require ( + golang.org/x/net v0.58.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.41.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect +) diff --git a/bridge/idp/locks/generated/api/v2/go.sum b/bridge/idp/locks/generated/api/v2/go.sum new file mode 100644 index 00000000..c8fe8eee --- /dev/null +++ b/bridge/idp/locks/generated/api/v2/go.sum @@ -0,0 +1,64 @@ +cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/bridge/idp/locks/generated/dependencies.patch b/bridge/idp/locks/generated/dependencies.patch new file mode 100644 index 00000000..477605ce --- /dev/null +++ b/bridge/idp/locks/generated/dependencies.patch @@ -0,0 +1,539 @@ +--- upstream/go.mod ++++ kars/go.mod +@@ -1,6 +1,8 @@ + module github.com/dexidp/dex + +-go 1.25.0 ++go 1.26.0 ++ ++toolchain go1.26.8 + + require ( + cloud.google.com/go/compute/metadata v0.9.0 +@@ -13,7 +15,7 @@ + github.com/dexidp/dex/api/v2 v2.4.0 + github.com/fsnotify/fsnotify v1.9.0 + github.com/ghodss/yaml v1.0.0 +- github.com/go-jose/go-jose/v4 v4.1.3 ++ github.com/go-jose/go-jose/v4 v4.1.4 + github.com/go-ldap/ldap/v3 v3.4.12 + github.com/go-sql-driver/mysql v1.9.3 + github.com/google/uuid v1.6.0 +@@ -28,27 +30,27 @@ + github.com/openbao/openbao/api/v2 v2.5.1 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.23.2 +- github.com/russellhaering/goxmldsig v1.5.0 ++ github.com/russellhaering/goxmldsig v1.6.0 + github.com/spf13/cobra v1.10.2 + github.com/stretchr/testify v1.11.1 + go.etcd.io/etcd/client/pkg/v3 v3.6.8 + go.etcd.io/etcd/client/v3 v3.6.8 +- golang.org/x/crypto v0.48.0 ++ golang.org/x/crypto v0.56.0 + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 +- golang.org/x/net v0.50.0 +- golang.org/x/oauth2 v0.35.0 ++ golang.org/x/net v0.58.0 ++ golang.org/x/oauth2 v0.36.0 + google.golang.org/api v0.267.0 +- google.golang.org/grpc v1.79.1 ++ google.golang.org/grpc v1.83.2 + google.golang.org/protobuf v1.36.11 + ) + + require ( + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect +- cloud.google.com/go/auth v0.18.1 // indirect ++ cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + dario.cat/mergo v1.0.1 // indirect + filippo.io/edwards25519 v1.1.1 // indirect +- github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect ++ github.com/Azure/go-ntlmssp v0.1.1 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect +@@ -105,21 +107,21 @@ + go.etcd.io/etcd/api/v3 v3.6.8 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect +- go.opentelemetry.io/otel v1.39.0 // indirect +- go.opentelemetry.io/otel/metric v1.39.0 // indirect +- go.opentelemetry.io/otel/trace v1.39.0 // indirect ++ go.opentelemetry.io/otel v1.44.0 // indirect ++ go.opentelemetry.io/otel/metric v1.44.0 // indirect ++ go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect +- golang.org/x/mod v0.32.0 // indirect +- golang.org/x/sync v0.19.0 // indirect +- golang.org/x/sys v0.41.0 // indirect +- golang.org/x/text v0.34.0 // indirect ++ golang.org/x/mod v0.40.0 // indirect ++ golang.org/x/sync v0.22.0 // indirect ++ golang.org/x/sys v0.47.0 // indirect ++ golang.org/x/text v0.41.0 // indirect + golang.org/x/time v0.14.0 // indirect +- golang.org/x/tools v0.41.0 // indirect ++ golang.org/x/tools v0.49.0 // indirect + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect +- google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect +- google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect ++ google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect ++ google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + ) +--- upstream/go.sum ++++ kars/go.sum +@@ -1,11 +1,15 @@ + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc= + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w= +-cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +-cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= ++cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= ++cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= ++cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= ++cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= + cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= + cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= + cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= + cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= ++cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= ++cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= + dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= + dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= + entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4= +@@ -14,10 +18,11 @@ + filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= + github.com/AppsFlyer/go-sundheit v0.6.0 h1:d2hBvCjBSb2lUsEWGfPigr4MCOt04sxB+Rppl0yUMSk= + github.com/AppsFlyer/go-sundheit v0.6.0/go.mod h1:LDdBHD6tQBtmHsdW+i1GwdTt6Wqc0qazf5ZEJVTbTME= +-github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +-github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= ++github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw= ++github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk= + github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= + github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= ++github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM= + github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= + github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= + github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +@@ -28,20 +33,28 @@ + github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= + github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= + github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= ++github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= ++github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= + github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= + github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= ++github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= ++github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= ++github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= + github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= + github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= ++github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= + github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= + github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= + github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= + github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= ++github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= + github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= + github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= + github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= + github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= + github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= + github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= ++github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= + github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= + github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= + github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +@@ -53,6 +66,11 @@ + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= ++github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= ++github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= ++github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= ++github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= ++github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= + github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= + github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= + github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +@@ -67,8 +85,8 @@ + github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +-github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +-github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= ++github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= ++github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= + github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4= + github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo= + github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +@@ -87,10 +105,13 @@ + github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= + github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= + github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= ++github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= ++github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= + github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= + github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= ++github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= + github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= + github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= + github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +@@ -103,6 +124,9 @@ + github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= + github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= + github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= ++github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= ++github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= ++github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +@@ -132,6 +156,7 @@ + github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= + github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= + github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= ++github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= + github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= + github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= + github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +@@ -146,8 +171,12 @@ + github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= + github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= + github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= ++github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= + github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= + github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= ++github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= ++github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= ++github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= + github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= + github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= + github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +@@ -173,6 +202,7 @@ + github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= + github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= + github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= ++github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= + github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= + github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= + github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +@@ -181,8 +211,12 @@ + github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= + github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= + github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= ++github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= ++github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= ++github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= ++github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= + github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= + github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= + github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +@@ -192,9 +226,11 @@ + github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= + github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= + github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= ++github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= ++github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= + github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= + github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= + github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +@@ -203,11 +239,13 @@ + github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= + github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= + github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= ++github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= + github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= + github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +-github.com/russellhaering/goxmldsig v1.5.0 h1:AU2UkkYIUOTyZRbe08XMThaOCelArgvNfYapcmSjBNw= +-github.com/russellhaering/goxmldsig v1.5.0/go.mod h1:x98CjQNFJcWfMxeOrMnMKg70lvDP6tE0nTaeUnjXDmk= ++github.com/russellhaering/goxmldsig v1.6.0 h1:8fdWXEPh2k/NZNQBPFNoVfS3JmzS4ZprY/sAOpKQLks= ++github.com/russellhaering/goxmldsig v1.6.0/go.mod h1:TrnaquDcYxWXfJrOjeMBTX4mLBeYAqaHEyUeWPxZlBM= + github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= ++github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= + github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= + github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= + github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +@@ -220,6 +258,7 @@ + github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= + github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= + github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= ++github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= + github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= + github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +@@ -228,10 +267,15 @@ + github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= + github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= + github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= ++github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= ++github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= ++github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= + github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= + github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= ++github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= + github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= + github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= ++github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= + github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= + github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= + go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= +@@ -240,22 +284,24 @@ + go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= + go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= + go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= ++go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= + go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= + go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= ++go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +-go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +-go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +-go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +-go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +-go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +-go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +-go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +-go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +-go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +-go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= ++go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= ++go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= ++go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= ++go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= ++go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= ++go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= ++go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= ++go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= ++go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= ++go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= + go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= + go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= + go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +@@ -268,44 +314,46 @@ + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +-golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +-golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= ++golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= ++golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY= + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= + golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= + golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +-golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +-golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= ++golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= ++golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= + golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= + golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= + golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= + golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +-golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +-golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +-golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +-golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= ++golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= ++golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= ++golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= ++golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= + golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= + golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +-golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +-golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= ++golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= ++golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= + golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= + golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +-golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +-golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= ++golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= ++golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= ++golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ= ++golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= + golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= + golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +-golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +-golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= ++golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= ++golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= + golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= + golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= + golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= + golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= + golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= + golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +-golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +-golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= ++golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= ++golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= + golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= + golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +@@ -314,18 +362,20 @@ + golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +-gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +-gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= ++gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= ++gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= + google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE= + google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0= ++google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= + google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= + google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= +-google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= +-google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +-google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +-google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +-google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +-google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= ++google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= ++google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= ++google.golang.org/genproto/googleapis/bytestream v0.0.0-20260203192932-546029d2fa20/go.mod h1:Tej9lWiwVvQJP+b43pjJIsr/3mZycXWCIyoiXmbFf40= ++google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= ++google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= ++google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= ++google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= + google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= + google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +@@ -337,3 +387,4 @@ + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= + gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= + gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ++sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +--- upstream/api/v2/go.mod ++++ kars/api/v2/go.mod +@@ -1,15 +1,17 @@ + module github.com/dexidp/dex/api/v2 + +-go 1.24.0 ++go 1.26.0 ++ ++toolchain go1.26.8 + + require ( +- google.golang.org/grpc v1.79.1 ++ google.golang.org/grpc v1.83.2 + google.golang.org/protobuf v1.36.11 + ) + + require ( +- golang.org/x/net v0.50.0 // indirect +- golang.org/x/sys v0.41.0 // indirect +- golang.org/x/text v0.34.0 // indirect +- google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect ++ golang.org/x/net v0.58.0 // indirect ++ golang.org/x/sys v0.47.0 // indirect ++ golang.org/x/text v0.41.0 // indirect ++ google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + ) +--- upstream/api/v2/go.sum ++++ kars/api/v2/go.sum +@@ -1,38 +1,64 @@ ++cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= ++cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= ++cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= ++github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM= + github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= + github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= ++github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= ++github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= ++github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= ++github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= ++github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= ++github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= ++github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= + github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= + github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= + github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= + github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= ++github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= + github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= + github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= ++github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= + github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= + github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= ++github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= ++github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= ++github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= ++github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= + go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= + go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +-go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +-go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +-go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +-go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +-go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +-go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +-go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +-go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +-go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +-go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +-golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +-golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +-golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +-golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +-golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +-golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +-gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +-gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +-google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +-google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +-google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +-google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= ++go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= ++go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= ++go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= ++go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= ++go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= ++go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= ++go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= ++go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= ++go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= ++go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= ++go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= ++go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= ++golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= ++golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= ++golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= ++golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= ++golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= ++golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= ++golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= ++golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= ++golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= ++golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= ++golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= ++golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= ++gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= ++gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= ++google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= ++google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= ++google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= ++google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= ++google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= + google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= + google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/bridge/idp/locks/generated/go.mod b/bridge/idp/locks/generated/go.mod new file mode 100644 index 00000000..6de46909 --- /dev/null +++ b/bridge/idp/locks/generated/go.mod @@ -0,0 +1,131 @@ +module github.com/dexidp/dex + +go 1.26.0 + +toolchain go1.26.8 + +require ( + cloud.google.com/go/compute/metadata v0.9.0 + entgo.io/ent v0.14.5 + github.com/AppsFlyer/go-sundheit v0.6.0 + github.com/Masterminds/semver v1.5.0 + github.com/Masterminds/sprig/v3 v3.3.0 + github.com/beevik/etree v1.6.0 + github.com/coreos/go-oidc/v3 v3.17.0 + github.com/dexidp/dex/api/v2 v2.4.0 + github.com/fsnotify/fsnotify v1.9.0 + github.com/ghodss/yaml v1.0.0 + github.com/go-jose/go-jose/v4 v4.1.4 + github.com/go-ldap/ldap/v3 v3.4.12 + github.com/go-sql-driver/mysql v1.9.3 + github.com/google/uuid v1.6.0 + github.com/gorilla/handlers v1.5.2 + github.com/gorilla/mux v1.8.1 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/kylelemons/godebug v1.1.0 + github.com/lib/pq v1.11.2 + github.com/mattermost/xml-roundtrip-validator v0.1.0 + github.com/mattn/go-sqlite3 v1.14.34 + github.com/oklog/run v1.2.0 + github.com/openbao/openbao/api/v2 v2.5.1 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.23.2 + github.com/russellhaering/goxmldsig v1.6.0 + github.com/spf13/cobra v1.10.2 + github.com/stretchr/testify v1.11.1 + go.etcd.io/etcd/client/pkg/v3 v3.6.8 + go.etcd.io/etcd/client/v3 v3.6.8 + golang.org/x/crypto v0.56.0 + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 + golang.org/x/net v0.58.0 + golang.org/x/oauth2 v0.36.0 + google.golang.org/api v0.267.0 + google.golang.org/grpc v1.83.2 + google.golang.org/protobuf v1.36.11 +) + +require ( + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect + cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + dario.cat/mergo v1.0.1 // indirect + filippo.io/edwards25519 v1.1.1 // indirect + github.com/Azure/go-ntlmssp v0.1.1 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bmatcuk/doublestar v1.3.4 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/inflect v0.19.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect + github.com/googleapis/gax-go/v2 v2.17.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty-yaml v1.1.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.8 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/mod v0.40.0 // indirect + golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.41.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.49.0 // indirect + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/dexidp/dex/api/v2 => ./api/v2 + +tool entgo.io/ent/cmd/ent diff --git a/bridge/idp/locks/generated/go.sum b/bridge/idp/locks/generated/go.sum new file mode 100644 index 00000000..cd39f32d --- /dev/null +++ b/bridge/idp/locks/generated/go.sum @@ -0,0 +1,390 @@ +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc= +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w= +cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= +cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4= +entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AppsFlyer/go-sundheit v0.6.0 h1:d2hBvCjBSb2lUsEWGfPigr4MCOt04sxB+Rppl0yUMSk= +github.com/AppsFlyer/go-sundheit v0.6.0/go.mod h1:LDdBHD6tQBtmHsdW+i1GwdTt6Wqc0qazf5ZEJVTbTME= +github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw= +github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= +github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= +github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= +github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4= +github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= +github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= +github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= +github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/openbao/openbao/api/v2 v2.5.1 h1:Br79D6L20SbAa5P7xqENxmvv8LyI4HoKosPy7klhn4o= +github.com/openbao/openbao/api/v2 v2.5.1/go.mod h1:Dh5un77tqGgMbmlVEqjqN+8/dMyUohnkaQVg/wXW0Ig= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russellhaering/goxmldsig v1.6.0 h1:8fdWXEPh2k/NZNQBPFNoVfS3JmzS4ZprY/sAOpKQLks= +github.com/russellhaering/goxmldsig v1.6.0/go.mod h1:TrnaquDcYxWXfJrOjeMBTX4mLBeYAqaHEyUeWPxZlBM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= +github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= +go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= +go.etcd.io/etcd/api/v3 v3.6.8/go.mod h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q= +go.etcd.io/etcd/client/pkg/v3 v3.6.8 h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50= +go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= +go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= +go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= +golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= +golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= +golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= +golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE= +google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20260203192932-546029d2fa20/go.mod h1:Tej9lWiwVvQJP+b43pjJIsr/3mZycXWCIyoiXmbFf40= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/bridge/idp/locks/generated/graph.txt b/bridge/idp/locks/generated/graph.txt new file mode 100644 index 00000000..21affc67 --- /dev/null +++ b/bridge/idp/locks/generated/graph.txt @@ -0,0 +1,841 @@ +github.com/dexidp/dex ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 +github.com/dexidp/dex cloud.google.com/go/auth@v0.18.2 +github.com/dexidp/dex cloud.google.com/go/auth/oauth2adapt@v0.2.8 +github.com/dexidp/dex cloud.google.com/go/compute/metadata@v0.9.0 +github.com/dexidp/dex dario.cat/mergo@v1.0.1 +github.com/dexidp/dex entgo.io/ent@v0.14.5 +github.com/dexidp/dex filippo.io/edwards25519@v1.1.1 +github.com/dexidp/dex github.com/AppsFlyer/go-sundheit@v0.6.0 +github.com/dexidp/dex github.com/Azure/go-ntlmssp@v0.1.1 +github.com/dexidp/dex github.com/Masterminds/goutils@v1.1.1 +github.com/dexidp/dex github.com/Masterminds/semver@v1.5.0 +github.com/dexidp/dex github.com/Masterminds/semver/v3@v3.3.0 +github.com/dexidp/dex github.com/Masterminds/sprig/v3@v3.3.0 +github.com/dexidp/dex github.com/agext/levenshtein@v1.2.3 +github.com/dexidp/dex github.com/apparentlymart/go-textseg/v15@v15.0.0 +github.com/dexidp/dex github.com/beevik/etree@v1.6.0 +github.com/dexidp/dex github.com/beorn7/perks@v1.0.1 +github.com/dexidp/dex github.com/bmatcuk/doublestar@v1.3.4 +github.com/dexidp/dex github.com/cenkalti/backoff/v4@v4.3.0 +github.com/dexidp/dex github.com/cespare/xxhash/v2@v2.3.0 +github.com/dexidp/dex github.com/coreos/go-oidc/v3@v3.17.0 +github.com/dexidp/dex github.com/coreos/go-semver@v0.3.1 +github.com/dexidp/dex github.com/coreos/go-systemd/v22@v22.5.0 +github.com/dexidp/dex github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc +github.com/dexidp/dex github.com/dexidp/dex/api/v2@v2.4.0 +github.com/dexidp/dex github.com/felixge/httpsnoop@v1.0.4 +github.com/dexidp/dex github.com/fsnotify/fsnotify@v1.9.0 +github.com/dexidp/dex github.com/ghodss/yaml@v1.0.0 +github.com/dexidp/dex github.com/go-asn1-ber/asn1-ber@v1.5.8-0.20250403174932-29230038a667 +github.com/dexidp/dex github.com/go-jose/go-jose/v4@v4.1.4 +github.com/dexidp/dex github.com/go-ldap/ldap/v3@v3.4.12 +github.com/dexidp/dex github.com/go-logr/logr@v1.4.3 +github.com/dexidp/dex github.com/go-logr/stdr@v1.2.2 +github.com/dexidp/dex github.com/go-openapi/inflect@v0.19.0 +github.com/dexidp/dex github.com/go-sql-driver/mysql@v1.9.3 +github.com/dexidp/dex github.com/go-viper/mapstructure/v2@v2.4.0 +github.com/dexidp/dex github.com/gogo/protobuf@v1.3.2 +github.com/dexidp/dex github.com/golang/protobuf@v1.5.4 +github.com/dexidp/dex github.com/google/go-cmp@v0.7.0 +github.com/dexidp/dex github.com/google/s2a-go@v0.1.9 +github.com/dexidp/dex github.com/google/uuid@v1.6.0 +github.com/dexidp/dex github.com/googleapis/enterprise-certificate-proxy@v0.3.11 +github.com/dexidp/dex github.com/googleapis/gax-go/v2@v2.17.0 +github.com/dexidp/dex github.com/gorilla/handlers@v1.5.2 +github.com/dexidp/dex github.com/gorilla/mux@v1.8.1 +github.com/dexidp/dex github.com/grpc-ecosystem/go-grpc-prometheus@v1.2.0 +github.com/dexidp/dex github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 +github.com/dexidp/dex github.com/hashicorp/errwrap@v1.1.0 +github.com/dexidp/dex github.com/hashicorp/go-cleanhttp@v0.5.2 +github.com/dexidp/dex github.com/hashicorp/go-multierror@v1.1.1 +github.com/dexidp/dex github.com/hashicorp/go-retryablehttp@v0.7.8 +github.com/dexidp/dex github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 +github.com/dexidp/dex github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 +github.com/dexidp/dex github.com/hashicorp/go-sockaddr@v1.0.7 +github.com/dexidp/dex github.com/hashicorp/hcl@v1.0.1-vault-7 +github.com/dexidp/dex github.com/hashicorp/hcl/v2@v2.18.1 +github.com/dexidp/dex github.com/huandu/xstrings@v1.5.0 +github.com/dexidp/dex github.com/inconshreveable/mousetrap@v1.1.0 +github.com/dexidp/dex github.com/jonboulle/clockwork@v0.5.0 +github.com/dexidp/dex github.com/kylelemons/godebug@v1.1.0 +github.com/dexidp/dex github.com/lib/pq@v1.11.2 +github.com/dexidp/dex github.com/mattermost/xml-roundtrip-validator@v0.1.0 +github.com/dexidp/dex github.com/mattn/go-runewidth@v0.0.9 +github.com/dexidp/dex github.com/mattn/go-sqlite3@v1.14.34 +github.com/dexidp/dex github.com/mitchellh/copystructure@v1.2.0 +github.com/dexidp/dex github.com/mitchellh/go-wordwrap@v1.0.1 +github.com/dexidp/dex github.com/mitchellh/mapstructure@v1.5.0 +github.com/dexidp/dex github.com/mitchellh/reflectwalk@v1.0.2 +github.com/dexidp/dex github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822 +github.com/dexidp/dex github.com/oklog/run@v1.2.0 +github.com/dexidp/dex github.com/olekukonko/tablewriter@v0.0.5 +github.com/dexidp/dex github.com/openbao/openbao/api/v2@v2.5.1 +github.com/dexidp/dex github.com/pkg/errors@v0.9.1 +github.com/dexidp/dex github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2 +github.com/dexidp/dex github.com/prometheus/client_golang@v1.23.2 +github.com/dexidp/dex github.com/prometheus/client_model@v0.6.2 +github.com/dexidp/dex github.com/prometheus/common@v0.66.1 +github.com/dexidp/dex github.com/prometheus/procfs@v0.16.1 +github.com/dexidp/dex github.com/russellhaering/goxmldsig@v1.6.0 +github.com/dexidp/dex github.com/ryanuber/go-glob@v1.0.0 +github.com/dexidp/dex github.com/shopspring/decimal@v1.4.0 +github.com/dexidp/dex github.com/spf13/cast@v1.7.0 +github.com/dexidp/dex github.com/spf13/cobra@v1.10.2 +github.com/dexidp/dex github.com/spf13/pflag@v1.0.9 +github.com/dexidp/dex github.com/stretchr/testify@v1.11.1 +github.com/dexidp/dex github.com/zclconf/go-cty@v1.14.4 +github.com/dexidp/dex github.com/zclconf/go-cty-yaml@v1.1.0 +github.com/dexidp/dex go@1.26.0 +github.com/dexidp/dex go.etcd.io/etcd/api/v3@v3.6.8 +github.com/dexidp/dex go.etcd.io/etcd/client/pkg/v3@v3.6.8 +github.com/dexidp/dex go.etcd.io/etcd/client/v3@v3.6.8 +github.com/dexidp/dex go.opentelemetry.io/auto/sdk@v1.2.1 +github.com/dexidp/dex go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 +github.com/dexidp/dex go.opentelemetry.io/otel@v1.44.0 +github.com/dexidp/dex go.opentelemetry.io/otel/metric@v1.44.0 +github.com/dexidp/dex go.opentelemetry.io/otel/trace@v1.44.0 +github.com/dexidp/dex go.uber.org/multierr@v1.11.0 +github.com/dexidp/dex go.uber.org/zap@v1.27.0 +github.com/dexidp/dex go.yaml.in/yaml/v2@v2.4.2 +github.com/dexidp/dex golang.org/x/crypto@v0.56.0 +github.com/dexidp/dex golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741 +github.com/dexidp/dex golang.org/x/mod@v0.40.0 +github.com/dexidp/dex golang.org/x/net@v0.58.0 +github.com/dexidp/dex golang.org/x/oauth2@v0.36.0 +github.com/dexidp/dex golang.org/x/sync@v0.22.0 +github.com/dexidp/dex golang.org/x/sys@v0.47.0 +github.com/dexidp/dex golang.org/x/text@v0.41.0 +github.com/dexidp/dex golang.org/x/time@v0.14.0 +github.com/dexidp/dex golang.org/x/tools@v0.49.0 +github.com/dexidp/dex golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated +github.com/dexidp/dex google.golang.org/api@v0.267.0 +github.com/dexidp/dex google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa +github.com/dexidp/dex google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa +github.com/dexidp/dex google.golang.org/grpc@v1.83.2 +github.com/dexidp/dex google.golang.org/protobuf@v1.36.11 +github.com/dexidp/dex gopkg.in/yaml.v2@v2.4.0 +github.com/dexidp/dex gopkg.in/yaml.v3@v3.0.1 +github.com/dexidp/dex toolchain@go1.26.8 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/DATA-DOG/go-sqlmock@v1.5.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/bmatcuk/doublestar@v1.3.4 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/go-openapi/inflect@v0.19.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/hashicorp/hcl/v2@v2.13.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/stretchr/testify@v1.8.2 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/zclconf/go-cty@v1.14.4 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/zclconf/go-cty-yaml@v1.1.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 golang.org/x/mod@v0.17.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/agext/levenshtein@v1.2.1 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/apparentlymart/go-textseg/v13@v13.0.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/apparentlymart/go-textseg/v15@v15.0.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/davecgh/go-spew@v1.1.1 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/google/go-cmp@v0.6.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/kr/text@v0.2.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/kylelemons/godebug@v1.1.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/mitchellh/go-wordwrap@v0.0.0-20150314170334-ad45545899c7 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 github.com/pmezard/go-difflib@v1.0.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 golang.org/x/text@v0.21.0 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 gopkg.in/yaml.v3@v3.0.1 +ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 go@1.22.12 +cloud.google.com/go/auth@v0.18.2 cloud.google.com/go/compute/metadata@v0.9.0 +cloud.google.com/go/auth@v0.18.2 github.com/google/go-cmp@v0.7.0 +cloud.google.com/go/auth@v0.18.2 github.com/google/s2a-go@v0.1.9 +cloud.google.com/go/auth@v0.18.2 github.com/googleapis/enterprise-certificate-proxy@v0.3.11 +cloud.google.com/go/auth@v0.18.2 github.com/googleapis/gax-go/v2@v2.17.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.61.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/otel@v1.39.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/otel/sdk@v1.39.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/otel/trace@v1.39.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/net@v0.49.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/time@v0.14.0 +cloud.google.com/go/auth@v0.18.2 google.golang.org/grpc@v1.78.0 +cloud.google.com/go/auth@v0.18.2 google.golang.org/protobuf@v1.36.11 +cloud.google.com/go/auth@v0.18.2 github.com/cespare/xxhash/v2@v2.3.0 +cloud.google.com/go/auth@v0.18.2 github.com/felixge/httpsnoop@v1.0.4 +cloud.google.com/go/auth@v0.18.2 github.com/go-logr/logr@v1.4.3 +cloud.google.com/go/auth@v0.18.2 github.com/go-logr/stdr@v1.2.2 +cloud.google.com/go/auth@v0.18.2 github.com/google/uuid@v1.6.0 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/auto/sdk@v1.2.1 +cloud.google.com/go/auth@v0.18.2 go.opentelemetry.io/otel/metric@v1.39.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/crypto@v0.47.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/oauth2@v0.32.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/sync@v0.19.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/sys@v0.40.0 +cloud.google.com/go/auth@v0.18.2 golang.org/x/text@v0.33.0 +cloud.google.com/go/auth@v0.18.2 google.golang.org/genproto/googleapis/rpc@v0.0.0-20260128011058-8636f8732409 +cloud.google.com/go/auth@v0.18.2 go@1.24.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 cloud.google.com/go/auth@v0.15.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 github.com/google/go-cmp@v0.7.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 golang.org/x/oauth2@v0.28.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 cloud.google.com/go/compute/metadata@v0.6.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 github.com/googleapis/enterprise-certificate-proxy@v0.3.5 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 github.com/googleapis/gax-go/v2@v2.14.1 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 golang.org/x/net@v0.37.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 golang.org/x/sys@v0.31.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 google.golang.org/genproto/googleapis/rpc@v0.0.0-20250227231956-55c901821b1e +cloud.google.com/go/auth/oauth2adapt@v0.2.8 google.golang.org/grpc@v1.71.0 +cloud.google.com/go/auth/oauth2adapt@v0.2.8 go@1.23.0 +cloud.google.com/go/compute/metadata@v0.9.0 github.com/google/go-cmp@v0.7.0 +cloud.google.com/go/compute/metadata@v0.9.0 golang.org/x/sys@v0.35.0 +cloud.google.com/go/compute/metadata@v0.9.0 go@1.24.0 +dario.cat/mergo@v1.0.1 gopkg.in/yaml.v3@v3.0.1 +entgo.io/ent@v0.14.5 ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9 +entgo.io/ent@v0.14.5 github.com/DATA-DOG/go-sqlmock@v1.5.0 +entgo.io/ent@v0.14.5 github.com/go-openapi/inflect@v0.19.0 +entgo.io/ent@v0.14.5 github.com/google/uuid@v1.3.0 +entgo.io/ent@v0.14.5 github.com/gorilla/websocket@v1.5.0 +entgo.io/ent@v0.14.5 github.com/jessevdk/go-flags@v1.5.0 +entgo.io/ent@v0.14.5 github.com/json-iterator/go@v1.1.12 +entgo.io/ent@v0.14.5 github.com/mattn/go-sqlite3@v1.14.17 +entgo.io/ent@v0.14.5 github.com/mitchellh/mapstructure@v1.5.0 +entgo.io/ent@v0.14.5 github.com/modern-go/reflect2@v1.0.2 +entgo.io/ent@v0.14.5 github.com/olekukonko/tablewriter@v0.0.5 +entgo.io/ent@v0.14.5 github.com/spf13/cobra@v1.7.0 +entgo.io/ent@v0.14.5 github.com/stretchr/testify@v1.8.4 +entgo.io/ent@v0.14.5 go.opencensus.io@v0.24.0 +entgo.io/ent@v0.14.5 golang.org/x/sync@v0.11.0 +entgo.io/ent@v0.14.5 golang.org/x/tools@v0.30.0 +entgo.io/ent@v0.14.5 github.com/agext/levenshtein@v1.2.3 +entgo.io/ent@v0.14.5 github.com/apparentlymart/go-textseg/v15@v15.0.0 +entgo.io/ent@v0.14.5 github.com/bmatcuk/doublestar@v1.3.4 +entgo.io/ent@v0.14.5 github.com/davecgh/go-spew@v1.1.1 +entgo.io/ent@v0.14.5 github.com/golang/groupcache@v0.0.0-20210331224755-41bb18bfe9da +entgo.io/ent@v0.14.5 github.com/google/go-cmp@v0.6.0 +entgo.io/ent@v0.14.5 github.com/hashicorp/hcl/v2@v2.18.1 +entgo.io/ent@v0.14.5 github.com/inconshreveable/mousetrap@v1.1.0 +entgo.io/ent@v0.14.5 github.com/kr/pretty@v0.3.0 +entgo.io/ent@v0.14.5 github.com/mattn/go-runewidth@v0.0.9 +entgo.io/ent@v0.14.5 github.com/mitchellh/go-wordwrap@v1.0.1 +entgo.io/ent@v0.14.5 github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd +entgo.io/ent@v0.14.5 github.com/niemeyer/pretty@v0.0.0-20200227124842-a10e7caefd8e +entgo.io/ent@v0.14.5 github.com/pmezard/go-difflib@v1.0.0 +entgo.io/ent@v0.14.5 github.com/sergi/go-diff@v1.3.1 +entgo.io/ent@v0.14.5 github.com/spf13/pflag@v1.0.5 +entgo.io/ent@v0.14.5 github.com/stretchr/objx@v0.5.0 +entgo.io/ent@v0.14.5 github.com/zclconf/go-cty@v1.14.4 +entgo.io/ent@v0.14.5 github.com/zclconf/go-cty-yaml@v1.1.0 +entgo.io/ent@v0.14.5 golang.org/x/mod@v0.23.0 +entgo.io/ent@v0.14.5 golang.org/x/sys@v0.30.0 +entgo.io/ent@v0.14.5 golang.org/x/text@v0.21.0 +entgo.io/ent@v0.14.5 gopkg.in/check.v1@v1.0.0-20200227125254-8fa46927fb4f +entgo.io/ent@v0.14.5 gopkg.in/yaml.v3@v3.0.1 +entgo.io/ent@v0.14.5 go@1.23 +github.com/AppsFlyer/go-sundheit@v0.6.0 github.com/fortytw2/leaktest@v1.3.0 +github.com/AppsFlyer/go-sundheit@v0.6.0 github.com/kr/pretty@v0.1.0 +github.com/AppsFlyer/go-sundheit@v0.6.0 github.com/pkg/errors@v0.8.1 +github.com/AppsFlyer/go-sundheit@v0.6.0 github.com/stretchr/objx@v0.2.0 +github.com/AppsFlyer/go-sundheit@v0.6.0 github.com/stretchr/testify@v1.6.1 +github.com/AppsFlyer/go-sundheit@v0.6.0 gopkg.in/check.v1@v1.0.0-20190902080502-41f04d3bba15 +github.com/Azure/go-ntlmssp@v0.1.1 go@1.24 +github.com/Masterminds/semver/v3@v3.3.0 go@1.21 +github.com/Masterminds/sprig/v3@v3.3.0 dario.cat/mergo@v1.0.1 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/Masterminds/goutils@v1.1.1 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/Masterminds/semver/v3@v3.3.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/google/uuid@v1.6.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/huandu/xstrings@v1.5.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/mitchellh/copystructure@v1.2.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/shopspring/decimal@v1.4.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/spf13/cast@v1.7.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/stretchr/testify@v1.5.1 +github.com/Masterminds/sprig/v3@v3.3.0 golang.org/x/crypto@v0.26.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/davecgh/go-spew@v1.1.1 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/google/go-cmp@v0.6.0 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/mitchellh/reflectwalk@v1.0.2 +github.com/Masterminds/sprig/v3@v3.3.0 github.com/pmezard/go-difflib@v1.0.0 +github.com/Masterminds/sprig/v3@v3.3.0 gopkg.in/yaml.v2@v2.3.0 +github.com/Masterminds/sprig/v3@v3.3.0 go@1.21 +github.com/beevik/etree@v1.6.0 go@1.23.0 +github.com/coreos/go-oidc/v3@v3.17.0 github.com/go-jose/go-jose/v4@v4.1.3 +github.com/coreos/go-oidc/v3@v3.17.0 golang.org/x/oauth2@v0.28.0 +github.com/coreos/go-oidc/v3@v3.17.0 go@1.24.0 +github.com/coreos/go-semver@v0.3.1 gopkg.in/yaml.v3@v3.0.1 +github.com/coreos/go-systemd/v22@v22.5.0 github.com/godbus/dbus/v5@v5.0.4 +github.com/dexidp/dex/api/v2@v2.4.0 google.golang.org/grpc@v1.83.2 +github.com/dexidp/dex/api/v2@v2.4.0 google.golang.org/protobuf@v1.36.11 +github.com/dexidp/dex/api/v2@v2.4.0 golang.org/x/net@v0.58.0 +github.com/dexidp/dex/api/v2@v2.4.0 golang.org/x/sys@v0.47.0 +github.com/dexidp/dex/api/v2@v2.4.0 golang.org/x/text@v0.41.0 +github.com/dexidp/dex/api/v2@v2.4.0 google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa +github.com/dexidp/dex/api/v2@v2.4.0 go@1.26.0 +github.com/fsnotify/fsnotify@v1.9.0 golang.org/x/sys@v0.13.0 +github.com/go-jose/go-jose/v4@v4.1.4 go@1.24.0 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/Azure/go-ntlmssp@v0.0.0-20221128193559-754e69321358 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/alexbrainman/sspi@v0.0.0-20250919150558-7d374ff0d59e +github.com/go-ldap/ldap/v3@v3.4.12 github.com/go-asn1-ber/asn1-ber@v1.5.8-0.20250403174932-29230038a667 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/google/uuid@v1.6.0 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/gokrb5/v8@v8.4.4 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/stretchr/testify@v1.8.1 +github.com/go-ldap/ldap/v3@v3.4.12 golang.org/x/crypto@v0.36.0 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/davecgh/go-spew@v1.1.1 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/hashicorp/go-uuid@v1.0.3 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/aescts/v2@v2.0.0 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/dnsutils/v2@v2.0.0 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/gofork@v1.7.6 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/goidentity/v6@v6.0.1 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/jcmturner/rpc/v2@v2.0.3 +github.com/go-ldap/ldap/v3@v3.4.12 github.com/pmezard/go-difflib@v1.0.0 +github.com/go-ldap/ldap/v3@v3.4.12 golang.org/x/net@v0.38.0 +github.com/go-ldap/ldap/v3@v3.4.12 gopkg.in/yaml.v3@v3.0.1 +github.com/go-ldap/ldap/v3@v3.4.12 go@1.23.0 +github.com/go-logr/stdr@v1.2.2 github.com/go-logr/logr@v1.2.2 +github.com/go-sql-driver/mysql@v1.9.3 filippo.io/edwards25519@v1.1.0 +github.com/go-sql-driver/mysql@v1.9.3 go@1.21.0 +github.com/gogo/protobuf@v1.3.2 github.com/kisielk/errcheck@v1.5.0 +github.com/gogo/protobuf@v1.3.2 github.com/kisielk/gotool@v1.0.0 +github.com/gogo/protobuf@v1.3.2 golang.org/x/tools@v0.0.0-20210106214847-113979e3529a +github.com/golang/protobuf@v1.5.4 github.com/google/go-cmp@v0.5.5 +github.com/golang/protobuf@v1.5.4 google.golang.org/protobuf@v1.33.0 +github.com/google/go-cmp@v0.7.0 go@1.21 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go/translate@v1.10.3 +github.com/google/s2a-go@v0.1.9 github.com/google/go-cmp@v0.6.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/crypto@v0.31.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/sync@v0.10.0 +github.com/google/s2a-go@v0.1.9 google.golang.org/api@v0.177.0 +github.com/google/s2a-go@v0.1.9 google.golang.org/appengine@v1.6.8 +github.com/google/s2a-go@v0.1.9 google.golang.org/grpc@v1.63.2 +github.com/google/s2a-go@v0.1.9 google.golang.org/protobuf@v1.34.2 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go@v0.112.2 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go/auth@v0.3.0 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go/auth/oauth2adapt@v0.2.2 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go/compute/metadata@v0.3.0 +github.com/google/s2a-go@v0.1.9 cloud.google.com/go/longrunning@v0.5.6 +github.com/google/s2a-go@v0.1.9 github.com/felixge/httpsnoop@v1.0.4 +github.com/google/s2a-go@v0.1.9 github.com/go-logr/logr@v1.4.1 +github.com/google/s2a-go@v0.1.9 github.com/go-logr/stdr@v1.2.2 +github.com/google/s2a-go@v0.1.9 github.com/golang/groupcache@v0.0.0-20210331224755-41bb18bfe9da +github.com/google/s2a-go@v0.1.9 github.com/golang/protobuf@v1.5.4 +github.com/google/s2a-go@v0.1.9 github.com/googleapis/enterprise-certificate-proxy@v0.3.2 +github.com/google/s2a-go@v0.1.9 github.com/googleapis/gax-go/v2@v2.12.3 +github.com/google/s2a-go@v0.1.9 go.opencensus.io@v0.24.0 +github.com/google/s2a-go@v0.1.9 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.49.0 +github.com/google/s2a-go@v0.1.9 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.49.0 +github.com/google/s2a-go@v0.1.9 go.opentelemetry.io/otel@v1.24.0 +github.com/google/s2a-go@v0.1.9 go.opentelemetry.io/otel/metric@v1.24.0 +github.com/google/s2a-go@v0.1.9 go.opentelemetry.io/otel/trace@v1.24.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/net@v0.33.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/oauth2@v0.19.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/sys@v0.28.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/text@v0.21.0 +github.com/google/s2a-go@v0.1.9 golang.org/x/time@v0.5.0 +github.com/google/s2a-go@v0.1.9 google.golang.org/genproto/googleapis/api@v0.0.0-20240429193739-8cf5692501f6 +github.com/google/s2a-go@v0.1.9 google.golang.org/genproto/googleapis/rpc@v0.0.0-20240429193739-8cf5692501f6 +github.com/googleapis/enterprise-certificate-proxy@v0.3.11 github.com/google/go-pkcs11@v0.3.0 +github.com/googleapis/enterprise-certificate-proxy@v0.3.11 golang.org/x/crypto@v0.47.0 +github.com/googleapis/enterprise-certificate-proxy@v0.3.11 golang.org/x/sys@v0.40.0 +github.com/googleapis/enterprise-certificate-proxy@v0.3.11 go@1.24.0 +github.com/googleapis/gax-go/v2@v2.17.0 github.com/google/go-cmp@v0.7.0 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/api@v0.264.0 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/genproto@v0.0.0-20260128011058-8636f8732409 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/genproto/googleapis/api@v0.0.0-20260128011058-8636f8732409 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/genproto/googleapis/rpc@v0.0.0-20260128011058-8636f8732409 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/grpc@v1.78.0 +github.com/googleapis/gax-go/v2@v2.17.0 google.golang.org/protobuf@v1.36.11 +github.com/googleapis/gax-go/v2@v2.17.0 golang.org/x/net@v0.49.0 +github.com/googleapis/gax-go/v2@v2.17.0 golang.org/x/sys@v0.40.0 +github.com/googleapis/gax-go/v2@v2.17.0 golang.org/x/text@v0.33.0 +github.com/googleapis/gax-go/v2@v2.17.0 go@1.24.0 +github.com/gorilla/handlers@v1.5.2 github.com/felixge/httpsnoop@v1.0.3 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 github.com/antihax/optional@v1.0.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 github.com/google/go-cmp@v0.7.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 github.com/rogpeppe/fastuuid@v1.2.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 golang.org/x/oauth2@v0.27.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 golang.org/x/text@v0.22.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 google.golang.org/grpc@v1.70.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 google.golang.org/protobuf@v1.36.5 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 gopkg.in/yaml.v3@v3.0.1 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 github.com/kr/pretty@v0.3.1 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 golang.org/x/net@v0.35.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 golang.org/x/sys@v0.30.0 +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c +github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 go@1.23.0 +github.com/hashicorp/go-multierror@v1.1.1 github.com/hashicorp/errwrap@v1.0.0 +github.com/hashicorp/go-retryablehttp@v0.7.8 github.com/hashicorp/go-cleanhttp@v0.5.2 +github.com/hashicorp/go-retryablehttp@v0.7.8 github.com/hashicorp/go-hclog@v1.6.3 +github.com/hashicorp/go-retryablehttp@v0.7.8 github.com/fatih/color@v1.16.0 +github.com/hashicorp/go-retryablehttp@v0.7.8 github.com/mattn/go-colorable@v0.1.13 +github.com/hashicorp/go-retryablehttp@v0.7.8 github.com/mattn/go-isatty@v0.0.20 +github.com/hashicorp/go-retryablehttp@v0.7.8 golang.org/x/sys@v0.20.0 +github.com/hashicorp/go-retryablehttp@v0.7.8 go@1.23 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/hashicorp/go-sockaddr@v1.0.6 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/mitchellh/mapstructure@v1.5.0 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/stretchr/testify@v1.8.4 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/davecgh/go-spew@v1.1.1 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/pmezard/go-difflib@v1.0.0 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 github.com/ryanuber/go-glob@v1.0.0 +github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 gopkg.in/yaml.v3@v3.0.1 +github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 github.com/ryanuber/go-glob@v1.0.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/hashicorp/errwrap@v1.1.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mitchellh/cli@v1.1.5 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mitchellh/go-wordwrap@v1.0.1 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/ryanuber/columnize@v2.1.2+incompatible +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/Masterminds/goutils@v1.1.1 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/Masterminds/semver/v3@v3.1.1 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/Masterminds/sprig/v3@v3.2.1 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/armon/go-radix@v0.0.0-20180808171621-7fddfc383310 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/bgentry/speakeasy@v0.1.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/fatih/color@v1.7.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/google/uuid@v1.1.2 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/hashicorp/go-multierror@v1.0.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/huandu/xstrings@v1.3.2 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/imdario/mergo@v0.3.11 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mattn/go-colorable@v0.0.9 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mattn/go-isatty@v0.0.3 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mitchellh/copystructure@v1.0.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/mitchellh/reflectwalk@v1.0.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/posener/complete@v1.1.1 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/shopspring/decimal@v1.2.0 +github.com/hashicorp/go-sockaddr@v1.0.7 github.com/spf13/cast@v1.3.1 +github.com/hashicorp/go-sockaddr@v1.0.7 golang.org/x/crypto@v0.17.0 +github.com/hashicorp/go-sockaddr@v1.0.7 golang.org/x/sys@v0.15.0 +github.com/hashicorp/hcl@v1.0.1-vault-7 github.com/davecgh/go-spew@v1.1.1 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/agext/levenshtein@v1.2.1 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/apparentlymart/go-dump@v0.0.0-20180507223929-23540a00eaa3 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/apparentlymart/go-textseg/v15@v15.0.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/davecgh/go-spew@v1.1.1 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/go-test/deep@v1.0.3 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/google/go-cmp@v0.3.1 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/kr/pretty@v0.1.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/kylelemons/godebug@v0.0.0-20170820004349-d65d576e9348 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/mitchellh/go-wordwrap@v0.0.0-20150314170334-ad45545899c7 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/sergi/go-diff@v1.0.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/spf13/pflag@v1.0.2 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/zclconf/go-cty@v1.13.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/zclconf/go-cty-debug@v0.0.0-20191215020915-b22d67c1ba0b +github.com/hashicorp/hcl/v2@v2.18.1 golang.org/x/crypto@v0.0.0-20220517005047-85d78b3ac167 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/apparentlymart/go-textseg/v13@v13.0.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/kr/text@v0.1.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/pmezard/go-difflib@v1.0.0 +github.com/hashicorp/hcl/v2@v2.18.1 github.com/stretchr/testify@v1.2.2 +github.com/hashicorp/hcl/v2@v2.18.1 golang.org/x/sys@v0.5.0 +github.com/hashicorp/hcl/v2@v2.18.1 golang.org/x/term@v0.0.0-20201126162022-7de9c90e9dd1 +github.com/hashicorp/hcl/v2@v2.18.1 golang.org/x/text@v0.11.0 +github.com/jonboulle/clockwork@v0.5.0 go@1.21 +github.com/lib/pq@v1.11.2 go@1.21 +github.com/mattermost/xml-roundtrip-validator@v0.1.0 github.com/stretchr/testify@v1.6.1 +github.com/mitchellh/copystructure@v1.2.0 github.com/mitchellh/reflectwalk@v1.0.2 +github.com/olekukonko/tablewriter@v0.0.5 github.com/mattn/go-runewidth@v0.0.9 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/cenkalti/backoff/v4@v4.3.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/go-jose/go-jose/v4@v4.1.3 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/go-test/deep@v1.1.1 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/go-viper/mapstructure/v2@v2.4.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-cleanhttp@v0.5.2 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-hclog@v1.6.3 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-multierror@v1.1.1 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-retryablehttp@v0.7.8 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/hcl@v1.0.1-vault-7 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/stretchr/testify@v1.11.1 +github.com/openbao/openbao/api/v2@v2.5.1 golang.org/x/net@v0.49.0 +github.com/openbao/openbao/api/v2@v2.5.1 golang.org/x/time@v0.14.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc +github.com/openbao/openbao/api/v2@v2.5.1 github.com/fatih/color@v1.18.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/errwrap@v1.1.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/hashicorp/go-sockaddr@v1.0.7 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/mattn/go-colorable@v0.1.14 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/mattn/go-isatty@v0.0.20 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/mitchellh/mapstructure@v1.5.0 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2 +github.com/openbao/openbao/api/v2@v2.5.1 github.com/ryanuber/go-glob@v1.0.0 +github.com/openbao/openbao/api/v2@v2.5.1 golang.org/x/sys@v0.40.0 +github.com/openbao/openbao/api/v2@v2.5.1 golang.org/x/text@v0.33.0 +github.com/openbao/openbao/api/v2@v2.5.1 gopkg.in/yaml.v3@v3.0.1 +github.com/openbao/openbao/api/v2@v2.5.1 go@1.24.0 +github.com/prometheus/client_golang@v1.23.2 github.com/beorn7/perks@v1.0.1 +github.com/prometheus/client_golang@v1.23.2 github.com/cespare/xxhash/v2@v2.3.0 +github.com/prometheus/client_golang@v1.23.2 github.com/google/go-cmp@v0.7.0 +github.com/prometheus/client_golang@v1.23.2 github.com/json-iterator/go@v1.1.12 +github.com/prometheus/client_golang@v1.23.2 github.com/klauspost/compress@v1.18.0 +github.com/prometheus/client_golang@v1.23.2 github.com/kylelemons/godebug@v1.1.0 +github.com/prometheus/client_golang@v1.23.2 github.com/prometheus/client_model@v0.6.2 +github.com/prometheus/client_golang@v1.23.2 github.com/prometheus/common@v0.66.1 +github.com/prometheus/client_golang@v1.23.2 github.com/prometheus/procfs@v0.16.1 +github.com/prometheus/client_golang@v1.23.2 go.uber.org/goleak@v1.3.0 +github.com/prometheus/client_golang@v1.23.2 golang.org/x/sys@v0.35.0 +github.com/prometheus/client_golang@v1.23.2 google.golang.org/protobuf@v1.36.8 +github.com/prometheus/client_golang@v1.23.2 github.com/jpillora/backoff@v1.0.0 +github.com/prometheus/client_golang@v1.23.2 github.com/kr/pretty@v0.3.1 +github.com/prometheus/client_golang@v1.23.2 github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd +github.com/prometheus/client_golang@v1.23.2 github.com/modern-go/reflect2@v1.0.2 +github.com/prometheus/client_golang@v1.23.2 github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822 +github.com/prometheus/client_golang@v1.23.2 github.com/mwitkow/go-conntrack@v0.0.0-20190716064945-2f068394615f +github.com/prometheus/client_golang@v1.23.2 go.yaml.in/yaml/v2@v2.4.2 +github.com/prometheus/client_golang@v1.23.2 golang.org/x/net@v0.43.0 +github.com/prometheus/client_golang@v1.23.2 golang.org/x/oauth2@v0.30.0 +github.com/prometheus/client_golang@v1.23.2 golang.org/x/text@v0.28.0 +github.com/prometheus/client_golang@v1.23.2 go@1.23.0 +github.com/prometheus/client_model@v0.6.2 google.golang.org/protobuf@v1.36.6 +github.com/prometheus/client_model@v0.6.2 go@1.22.0 +github.com/prometheus/common@v0.66.1 github.com/alecthomas/kingpin/v2@v2.4.0 +github.com/prometheus/common@v0.66.1 github.com/google/go-cmp@v0.7.0 +github.com/prometheus/common@v0.66.1 github.com/julienschmidt/httprouter@v1.3.0 +github.com/prometheus/common@v0.66.1 github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822 +github.com/prometheus/common@v0.66.1 github.com/mwitkow/go-conntrack@v0.0.0-20190716064945-2f068394615f +github.com/prometheus/common@v0.66.1 github.com/prometheus/client_model@v0.6.2 +github.com/prometheus/common@v0.66.1 github.com/stretchr/testify@v1.11.1 +github.com/prometheus/common@v0.66.1 go.yaml.in/yaml/v2@v2.4.2 +github.com/prometheus/common@v0.66.1 golang.org/x/net@v0.43.0 +github.com/prometheus/common@v0.66.1 golang.org/x/oauth2@v0.30.0 +github.com/prometheus/common@v0.66.1 google.golang.org/protobuf@v1.36.8 +github.com/prometheus/common@v0.66.1 github.com/alecthomas/units@v0.0.0-20211218093645-b94a6e3cc137 +github.com/prometheus/common@v0.66.1 github.com/beorn7/perks@v1.0.1 +github.com/prometheus/common@v0.66.1 github.com/cespare/xxhash/v2@v2.3.0 +github.com/prometheus/common@v0.66.1 github.com/davecgh/go-spew@v1.1.1 +github.com/prometheus/common@v0.66.1 github.com/jpillora/backoff@v1.0.0 +github.com/prometheus/common@v0.66.1 github.com/pmezard/go-difflib@v1.0.0 +github.com/prometheus/common@v0.66.1 github.com/prometheus/client_golang@v1.20.4 +github.com/prometheus/common@v0.66.1 github.com/prometheus/procfs@v0.15.1 +github.com/prometheus/common@v0.66.1 github.com/rogpeppe/go-internal@v1.10.0 +github.com/prometheus/common@v0.66.1 github.com/xhit/go-str2duration/v2@v2.1.0 +github.com/prometheus/common@v0.66.1 golang.org/x/sys@v0.35.0 +github.com/prometheus/common@v0.66.1 golang.org/x/text@v0.28.0 +github.com/prometheus/common@v0.66.1 gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c +github.com/prometheus/common@v0.66.1 gopkg.in/yaml.v3@v3.0.1 +github.com/prometheus/common@v0.66.1 go@1.23.0 +github.com/prometheus/procfs@v0.16.1 github.com/google/go-cmp@v0.7.0 +github.com/prometheus/procfs@v0.16.1 golang.org/x/sync@v0.13.0 +github.com/prometheus/procfs@v0.16.1 golang.org/x/sys@v0.32.0 +github.com/prometheus/procfs@v0.16.1 go@1.23.0 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/beevik/etree@v1.6.0 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/jonboulle/clockwork@v0.5.0 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/stretchr/testify@v1.8.4 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/davecgh/go-spew@v1.1.1 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/kr/pretty@v0.3.0 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/pmezard/go-difflib@v1.0.0 +github.com/russellhaering/goxmldsig@v1.6.0 github.com/rogpeppe/go-internal@v1.8.0 +github.com/russellhaering/goxmldsig@v1.6.0 gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c +github.com/russellhaering/goxmldsig@v1.6.0 gopkg.in/yaml.v3@v3.0.1 +github.com/russellhaering/goxmldsig@v1.6.0 go@1.23.0 +github.com/spf13/cast@v1.7.0 github.com/frankban/quicktest@v1.14.6 +github.com/spf13/cast@v1.7.0 github.com/google/go-cmp@v0.5.9 +github.com/spf13/cast@v1.7.0 github.com/kr/pretty@v0.3.1 +github.com/spf13/cast@v1.7.0 github.com/kr/text@v0.2.0 +github.com/spf13/cast@v1.7.0 github.com/rogpeppe/go-internal@v1.9.0 +github.com/spf13/cobra@v1.10.2 github.com/cpuguy83/go-md2man/v2@v2.0.6 +github.com/spf13/cobra@v1.10.2 github.com/inconshreveable/mousetrap@v1.1.0 +github.com/spf13/cobra@v1.10.2 github.com/spf13/pflag@v1.0.9 +github.com/spf13/cobra@v1.10.2 go.yaml.in/yaml/v3@v3.0.4 +github.com/stretchr/testify@v1.11.1 github.com/davecgh/go-spew@v1.1.1 +github.com/stretchr/testify@v1.11.1 github.com/pmezard/go-difflib@v1.0.0 +github.com/stretchr/testify@v1.11.1 github.com/stretchr/objx@v0.5.2 +github.com/stretchr/testify@v1.11.1 gopkg.in/yaml.v3@v3.0.1 +github.com/zclconf/go-cty@v1.14.4 github.com/apparentlymart/go-textseg/v15@v15.0.0 +github.com/zclconf/go-cty@v1.14.4 github.com/google/go-cmp@v0.3.1 +github.com/zclconf/go-cty@v1.14.4 github.com/vmihailenco/msgpack/v5@v5.3.5 +github.com/zclconf/go-cty@v1.14.4 golang.org/x/text@v0.11.0 +github.com/zclconf/go-cty@v1.14.4 github.com/davecgh/go-spew@v1.1.1 +github.com/zclconf/go-cty@v1.14.4 github.com/vmihailenco/tagparser/v2@v2.0.0 +github.com/zclconf/go-cty-yaml@v1.1.0 github.com/zclconf/go-cty@v1.0.0 +github.com/zclconf/go-cty-yaml@v1.1.0 golang.org/x/text@v0.3.0 +go@1.26.0 toolchain@go1.26.0 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/coreos/go-semver@v0.3.1 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/gogo/protobuf@v1.3.2 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/golang/protobuf@v1.5.4 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/stretchr/testify@v1.10.0 +go.etcd.io/etcd/api/v3@v3.6.8 google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb +go.etcd.io/etcd/api/v3@v3.6.8 google.golang.org/grpc@v1.71.1 +go.etcd.io/etcd/api/v3@v3.6.8 google.golang.org/protobuf@v1.36.5 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/davecgh/go-spew@v1.1.1 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/kr/text@v0.2.0 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/pmezard/go-difflib@v1.0.0 +go.etcd.io/etcd/api/v3@v3.6.8 github.com/rogpeppe/go-internal@v1.14.1 +go.etcd.io/etcd/api/v3@v3.6.8 golang.org/x/net@v0.47.0 +go.etcd.io/etcd/api/v3@v3.6.8 golang.org/x/sys@v0.38.0 +go.etcd.io/etcd/api/v3@v3.6.8 golang.org/x/text@v0.31.0 +go.etcd.io/etcd/api/v3@v3.6.8 google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb +go.etcd.io/etcd/api/v3@v3.6.8 gopkg.in/yaml.v3@v3.0.1 +go.etcd.io/etcd/api/v3@v3.6.8 go@1.24.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/coreos/go-systemd/v22@v22.5.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/stretchr/testify@v1.10.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 go.uber.org/zap@v1.27.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 golang.org/x/sys@v0.38.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/davecgh/go-spew@v1.1.1 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/kr/pretty@v0.3.1 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/pmezard/go-difflib@v1.0.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 github.com/rogpeppe/go-internal@v1.14.1 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 go.uber.org/multierr@v1.11.0 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c +go.etcd.io/etcd/client/pkg/v3@v3.6.8 gopkg.in/yaml.v3@v3.0.1 +go.etcd.io/etcd/client/pkg/v3@v3.6.8 go@1.24.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/coreos/go-semver@v0.3.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/dustin/go-humanize@v1.0.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus@v1.0.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/prometheus/client_golang@v1.20.5 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/stretchr/testify@v1.10.0 +go.etcd.io/etcd/client/v3@v3.6.8 go.etcd.io/etcd/api/v3@v3.6.8 +go.etcd.io/etcd/client/v3@v3.6.8 go.etcd.io/etcd/client/pkg/v3@v3.6.8 +go.etcd.io/etcd/client/v3@v3.6.8 go.uber.org/zap@v1.27.0 +go.etcd.io/etcd/client/v3@v3.6.8 google.golang.org/grpc@v1.71.1 +go.etcd.io/etcd/client/v3@v3.6.8 sigs.k8s.io/yaml@v1.4.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/beorn7/perks@v1.0.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/cespare/xxhash/v2@v2.3.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/coreos/go-systemd/v22@v22.5.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/davecgh/go-spew@v1.1.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/gogo/protobuf@v1.3.2 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/golang/protobuf@v1.5.4 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/grpc-ecosystem/go-grpc-middleware/v2@v2.1.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/klauspost/compress@v1.17.9 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/pmezard/go-difflib@v1.0.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/prometheus/client_model@v0.6.1 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/prometheus/common@v0.62.0 +go.etcd.io/etcd/client/v3@v3.6.8 github.com/prometheus/procfs@v0.15.1 +go.etcd.io/etcd/client/v3@v3.6.8 go.uber.org/multierr@v1.11.0 +go.etcd.io/etcd/client/v3@v3.6.8 golang.org/x/net@v0.47.0 +go.etcd.io/etcd/client/v3@v3.6.8 golang.org/x/sys@v0.38.0 +go.etcd.io/etcd/client/v3@v3.6.8 golang.org/x/text@v0.31.0 +go.etcd.io/etcd/client/v3@v3.6.8 google.golang.org/genproto/googleapis/api@v0.0.0-20250303144028-a0af3efb3deb +go.etcd.io/etcd/client/v3@v3.6.8 google.golang.org/genproto/googleapis/rpc@v0.0.0-20250303144028-a0af3efb3deb +go.etcd.io/etcd/client/v3@v3.6.8 google.golang.org/protobuf@v1.36.5 +go.etcd.io/etcd/client/v3@v3.6.8 gopkg.in/yaml.v3@v3.0.1 +go.etcd.io/etcd/client/v3@v3.6.8 go@1.24.0 +go.opentelemetry.io/auto/sdk@v1.2.1 github.com/stretchr/testify@v1.11.1 +go.opentelemetry.io/auto/sdk@v1.2.1 go.opentelemetry.io/otel@v1.38.0 +go.opentelemetry.io/auto/sdk@v1.2.1 go.opentelemetry.io/otel/trace@v1.38.0 +go.opentelemetry.io/auto/sdk@v1.2.1 github.com/davecgh/go-spew@v1.1.1 +go.opentelemetry.io/auto/sdk@v1.2.1 github.com/kr/pretty@v0.3.1 +go.opentelemetry.io/auto/sdk@v1.2.1 github.com/pmezard/go-difflib@v1.0.0 +go.opentelemetry.io/auto/sdk@v1.2.1 github.com/rogpeppe/go-internal@v1.14.1 +go.opentelemetry.io/auto/sdk@v1.2.1 gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c +go.opentelemetry.io/auto/sdk@v1.2.1 gopkg.in/yaml.v3@v3.0.1 +go.opentelemetry.io/auto/sdk@v1.2.1 go@1.24.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/felixge/httpsnoop@v1.0.4 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/stretchr/testify@v1.10.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/otel@v1.36.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/otel/metric@v1.36.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/otel/sdk@v1.36.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/otel/sdk/metric@v1.36.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/otel/trace@v1.36.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/davecgh/go-spew@v1.1.1 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/go-logr/logr@v1.4.2 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/go-logr/stdr@v1.2.2 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/google/uuid@v1.6.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 github.com/pmezard/go-difflib@v1.0.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go.opentelemetry.io/auto/sdk@v1.1.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 golang.org/x/sys@v0.33.0 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 gopkg.in/yaml.v3@v3.0.1 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 go@1.23.0 +go.opentelemetry.io/otel@v1.44.0 github.com/cespare/xxhash/v2@v2.3.0 +go.opentelemetry.io/otel@v1.44.0 github.com/go-logr/logr@v1.4.3 +go.opentelemetry.io/otel@v1.44.0 github.com/go-logr/stdr@v1.2.2 +go.opentelemetry.io/otel@v1.44.0 github.com/google/go-cmp@v0.7.0 +go.opentelemetry.io/otel@v1.44.0 github.com/stretchr/testify@v1.11.1 +go.opentelemetry.io/otel@v1.44.0 go.opentelemetry.io/auto/sdk@v1.2.1 +go.opentelemetry.io/otel@v1.44.0 go.opentelemetry.io/otel/metric@v1.44.0 +go.opentelemetry.io/otel@v1.44.0 go.opentelemetry.io/otel/trace@v1.44.0 +go.opentelemetry.io/otel@v1.44.0 github.com/davecgh/go-spew@v1.1.1 +go.opentelemetry.io/otel@v1.44.0 github.com/kr/text@v0.2.0 +go.opentelemetry.io/otel@v1.44.0 github.com/pmezard/go-difflib@v1.0.0 +go.opentelemetry.io/otel@v1.44.0 gopkg.in/yaml.v3@v3.0.1 +go.opentelemetry.io/otel@v1.44.0 go@1.25.0 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/stretchr/testify@v1.11.1 +go.opentelemetry.io/otel/metric@v1.44.0 go.opentelemetry.io/otel@v1.44.0 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/cespare/xxhash/v2@v2.3.0 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/davecgh/go-spew@v1.1.1 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/go-logr/logr@v1.4.3 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/go-logr/stdr@v1.2.2 +go.opentelemetry.io/otel/metric@v1.44.0 github.com/pmezard/go-difflib@v1.0.0 +go.opentelemetry.io/otel/metric@v1.44.0 go.opentelemetry.io/auto/sdk@v1.2.1 +go.opentelemetry.io/otel/metric@v1.44.0 go.opentelemetry.io/otel/trace@v1.44.0 +go.opentelemetry.io/otel/metric@v1.44.0 gopkg.in/yaml.v3@v3.0.1 +go.opentelemetry.io/otel/metric@v1.44.0 go@1.25.0 +go.opentelemetry.io/otel/trace@v1.44.0 github.com/google/go-cmp@v0.7.0 +go.opentelemetry.io/otel/trace@v1.44.0 github.com/stretchr/testify@v1.11.1 +go.opentelemetry.io/otel/trace@v1.44.0 go.opentelemetry.io/otel@v1.44.0 +go.opentelemetry.io/otel/trace@v1.44.0 github.com/cespare/xxhash/v2@v2.3.0 +go.opentelemetry.io/otel/trace@v1.44.0 github.com/davecgh/go-spew@v1.1.1 +go.opentelemetry.io/otel/trace@v1.44.0 github.com/pmezard/go-difflib@v1.0.0 +go.opentelemetry.io/otel/trace@v1.44.0 gopkg.in/yaml.v3@v3.0.1 +go.opentelemetry.io/otel/trace@v1.44.0 go@1.25.0 +go.uber.org/multierr@v1.11.0 github.com/stretchr/testify@v1.7.0 +go.uber.org/multierr@v1.11.0 github.com/davecgh/go-spew@v1.1.1 +go.uber.org/multierr@v1.11.0 github.com/pmezard/go-difflib@v1.0.0 +go.uber.org/multierr@v1.11.0 gopkg.in/yaml.v3@v3.0.1 +go.uber.org/zap@v1.27.0 github.com/stretchr/testify@v1.8.1 +go.uber.org/zap@v1.27.0 go.uber.org/goleak@v1.3.0 +go.uber.org/zap@v1.27.0 go.uber.org/multierr@v1.10.0 +go.uber.org/zap@v1.27.0 gopkg.in/yaml.v3@v3.0.1 +go.uber.org/zap@v1.27.0 github.com/davecgh/go-spew@v1.1.1 +go.uber.org/zap@v1.27.0 github.com/kr/text@v0.2.0 +go.uber.org/zap@v1.27.0 github.com/pmezard/go-difflib@v1.0.0 +go.yaml.in/yaml/v2@v2.4.2 gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405 +golang.org/x/crypto@v0.56.0 golang.org/x/net@v0.57.0 +golang.org/x/crypto@v0.56.0 golang.org/x/sys@v0.47.0 +golang.org/x/crypto@v0.56.0 golang.org/x/term@v0.45.0 +golang.org/x/crypto@v0.56.0 golang.org/x/text@v0.41.0 +golang.org/x/crypto@v0.56.0 go@1.26.0 +golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741 github.com/google/go-cmp@v0.5.8 +golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741 golang.org/x/mod@v0.6.0-dev.0.20220419223038-86c51ed26bb4 +golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741 golang.org/x/tools@v0.1.12 +golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741 golang.org/x/sys@v0.0.0-20220722155257-8c9f86f7a55f +golang.org/x/mod@v0.40.0 golang.org/x/tools@v0.49.0 +golang.org/x/mod@v0.40.0 go@1.25.0 +golang.org/x/net@v0.58.0 golang.org/x/crypto@v0.55.0 +golang.org/x/net@v0.58.0 golang.org/x/sys@v0.47.0 +golang.org/x/net@v0.58.0 golang.org/x/term@v0.45.0 +golang.org/x/net@v0.58.0 golang.org/x/text@v0.41.0 +golang.org/x/net@v0.58.0 go@1.25.0 +golang.org/x/oauth2@v0.36.0 cloud.google.com/go/compute/metadata@v0.3.0 +golang.org/x/oauth2@v0.36.0 go@1.25.0 +golang.org/x/sync@v0.22.0 go@1.25.0 +golang.org/x/sys@v0.47.0 go@1.25.0 +golang.org/x/text@v0.41.0 golang.org/x/tools@v0.48.0 +golang.org/x/text@v0.41.0 golang.org/x/mod@v0.38.0 +golang.org/x/text@v0.41.0 golang.org/x/sync@v0.22.0 +golang.org/x/text@v0.41.0 go@1.25.0 +golang.org/x/time@v0.14.0 go@1.24.0 +golang.org/x/tools@v0.49.0 github.com/google/go-cmp@v0.6.0 +golang.org/x/tools@v0.49.0 github.com/yuin/goldmark@v1.4.13 +golang.org/x/tools@v0.49.0 golang.org/x/mod@v0.39.0 +golang.org/x/tools@v0.49.0 golang.org/x/net@v0.58.0 +golang.org/x/tools@v0.49.0 golang.org/x/sync@v0.22.0 +golang.org/x/tools@v0.49.0 golang.org/x/telemetry@v0.0.0-20260811182544-a038080d80e5 +golang.org/x/tools@v0.49.0 golang.org/x/sys@v0.47.0 +golang.org/x/tools@v0.49.0 go@1.25.0 +golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated golang.org/x/tools@v0.34.1-0.20250613162507-3f93fece84c7 +golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated golang.org/x/tools/go/expect@v0.1.0-deprecated +golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated golang.org/x/mod@v0.25.0 +golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated golang.org/x/sync@v0.15.0 +golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated go@1.23.0 +google.golang.org/api@v0.267.0 cloud.google.com/go/auth@v0.18.1 +google.golang.org/api@v0.267.0 cloud.google.com/go/auth/oauth2adapt@v0.2.8 +google.golang.org/api@v0.267.0 cloud.google.com/go/compute/metadata@v0.9.0 +google.golang.org/api@v0.267.0 github.com/google/go-cmp@v0.7.0 +google.golang.org/api@v0.267.0 github.com/google/s2a-go@v0.1.9 +google.golang.org/api@v0.267.0 github.com/google/uuid@v1.6.0 +google.golang.org/api@v0.267.0 github.com/googleapis/enterprise-certificate-proxy@v0.3.11 +google.golang.org/api@v0.267.0 github.com/googleapis/gax-go/v2@v2.17.0 +google.golang.org/api@v0.267.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.61.0 +google.golang.org/api@v0.267.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 +google.golang.org/api@v0.267.0 golang.org/x/net@v0.49.0 +google.golang.org/api@v0.267.0 golang.org/x/oauth2@v0.35.0 +google.golang.org/api@v0.267.0 golang.org/x/sync@v0.19.0 +google.golang.org/api@v0.267.0 golang.org/x/time@v0.14.0 +google.golang.org/api@v0.267.0 google.golang.org/genproto/googleapis/bytestream@v0.0.0-20260203192932-546029d2fa20 +google.golang.org/api@v0.267.0 google.golang.org/genproto/googleapis/rpc@v0.0.0-20260203192932-546029d2fa20 +google.golang.org/api@v0.267.0 google.golang.org/grpc@v1.78.0 +google.golang.org/api@v0.267.0 google.golang.org/protobuf@v1.36.11 +google.golang.org/api@v0.267.0 github.com/cespare/xxhash/v2@v2.3.0 +google.golang.org/api@v0.267.0 github.com/felixge/httpsnoop@v1.0.4 +google.golang.org/api@v0.267.0 github.com/go-logr/logr@v1.4.3 +google.golang.org/api@v0.267.0 github.com/go-logr/stdr@v1.2.2 +google.golang.org/api@v0.267.0 go.opentelemetry.io/auto/sdk@v1.2.1 +google.golang.org/api@v0.267.0 go.opentelemetry.io/otel@v1.39.0 +google.golang.org/api@v0.267.0 go.opentelemetry.io/otel/metric@v1.39.0 +google.golang.org/api@v0.267.0 go.opentelemetry.io/otel/trace@v1.39.0 +google.golang.org/api@v0.267.0 golang.org/x/crypto@v0.47.0 +google.golang.org/api@v0.267.0 golang.org/x/sys@v0.40.0 +google.golang.org/api@v0.267.0 golang.org/x/text@v0.33.0 +google.golang.org/api@v0.267.0 go@1.24.0 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa google.golang.org/genproto/googleapis/rpc@v0.0.0-20260523011958-0a33c5d7ca68 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa google.golang.org/grpc@v1.79.3 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa google.golang.org/protobuf@v1.36.11 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa golang.org/x/net@v0.48.0 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa golang.org/x/sys@v0.39.0 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa golang.org/x/text@v0.32.0 +google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa go@1.25.0 +google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa google.golang.org/protobuf@v1.36.11 +google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa go@1.25.0 +google.golang.org/grpc@v1.83.2 cloud.google.com/go/auth@v0.18.2 +google.golang.org/grpc@v1.83.2 cloud.google.com/go/compute/metadata@v0.9.0 +google.golang.org/grpc@v1.83.2 github.com/cespare/xxhash/v2@v2.3.0 +google.golang.org/grpc@v1.83.2 github.com/cncf/xds/go@v0.0.0-20260202195803-dba9d589def2 +google.golang.org/grpc@v1.83.2 github.com/envoyproxy/go-control-plane@v0.14.0 +google.golang.org/grpc@v1.83.2 github.com/envoyproxy/go-control-plane/envoy@v1.37.0 +google.golang.org/grpc@v1.83.2 github.com/golang/glog@v1.2.5 +google.golang.org/grpc@v1.83.2 github.com/golang/protobuf@v1.5.4 +google.golang.org/grpc@v1.83.2 github.com/google/go-cmp@v0.7.0 +google.golang.org/grpc@v1.83.2 github.com/google/uuid@v1.6.0 +google.golang.org/grpc@v1.83.2 github.com/spiffe/go-spiffe/v2@v2.7.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/contrib/detectors/gcp@v1.44.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/otel@v1.44.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/otel/metric@v1.44.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/otel/sdk@v1.44.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/otel/sdk/metric@v1.44.0 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/otel/trace@v1.44.0 +google.golang.org/grpc@v1.83.2 golang.org/x/net@v0.58.0 +google.golang.org/grpc@v1.83.2 golang.org/x/oauth2@v0.36.0 +google.golang.org/grpc@v1.83.2 golang.org/x/sync@v0.22.0 +google.golang.org/grpc@v1.83.2 golang.org/x/sys@v0.47.0 +google.golang.org/grpc@v1.83.2 gonum.org/v1/gonum@v0.17.0 +google.golang.org/grpc@v1.83.2 google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa +google.golang.org/grpc@v1.83.2 google.golang.org/protobuf@v1.36.11 +google.golang.org/grpc@v1.83.2 cel.dev/expr@v0.25.2 +google.golang.org/grpc@v1.83.2 github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp@v1.33.0 +google.golang.org/grpc@v1.83.2 github.com/envoyproxy/go-control-plane/ratelimit@v0.1.0 +google.golang.org/grpc@v1.83.2 github.com/envoyproxy/protoc-gen-validate@v1.3.3 +google.golang.org/grpc@v1.83.2 github.com/felixge/httpsnoop@v1.0.4 +google.golang.org/grpc@v1.83.2 github.com/go-jose/go-jose/v4@v4.1.4 +google.golang.org/grpc@v1.83.2 github.com/go-logr/logr@v1.4.3 +google.golang.org/grpc@v1.83.2 github.com/go-logr/stdr@v1.2.2 +google.golang.org/grpc@v1.83.2 github.com/google/s2a-go@v0.1.9 +google.golang.org/grpc@v1.83.2 github.com/googleapis/enterprise-certificate-proxy@v0.3.11 +google.golang.org/grpc@v1.83.2 github.com/googleapis/gax-go/v2@v2.17.0 +google.golang.org/grpc@v1.83.2 github.com/planetscale/vtprotobuf@v0.6.1-0.20240319094008-0393e58bdf10 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/auto/sdk@v1.2.1 +google.golang.org/grpc@v1.83.2 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0 +google.golang.org/grpc@v1.83.2 golang.org/x/crypto@v0.55.0 +google.golang.org/grpc@v1.83.2 golang.org/x/text@v0.41.0 +google.golang.org/grpc@v1.83.2 google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa +google.golang.org/grpc@v1.83.2 go@1.25.0 +google.golang.org/protobuf@v1.36.11 github.com/golang/protobuf@v1.5.0 +google.golang.org/protobuf@v1.36.11 github.com/google/go-cmp@v0.7.0 +google.golang.org/protobuf@v1.36.11 go@1.23 +gopkg.in/yaml.v2@v2.4.0 gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405 +gopkg.in/yaml.v3@v3.0.1 gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405 +github.com/kr/pretty@v0.1.0 github.com/kr/text@v0.1.0 +github.com/stretchr/objx@v0.2.0 github.com/davecgh/go-spew@v1.1.1 +github.com/stretchr/objx@v0.2.0 github.com/stretchr/testify@v1.3.0 +github.com/stretchr/testify@v1.6.1 github.com/davecgh/go-spew@v1.1.0 +github.com/stretchr/testify@v1.6.1 github.com/pmezard/go-difflib@v1.0.0 +github.com/stretchr/testify@v1.6.1 github.com/stretchr/objx@v0.1.0 +github.com/stretchr/testify@v1.6.1 gopkg.in/yaml.v3@v3.0.0-20200313102051-9f266ea9e77c +github.com/kisielk/errcheck@v1.5.0 golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f +golang.org/x/tools@v0.0.0-20210106214847-113979e3529a github.com/yuin/goldmark@v1.2.1 +golang.org/x/tools@v0.0.0-20210106214847-113979e3529a golang.org/x/mod@v0.3.0 +golang.org/x/tools@v0.0.0-20210106214847-113979e3529a golang.org/x/net@v0.0.0-20201021035429-f5854403a974 +golang.org/x/tools@v0.0.0-20210106214847-113979e3529a golang.org/x/sync@v0.0.0-20201020160332-67f06af15bc9 +golang.org/x/tools@v0.0.0-20210106214847-113979e3529a golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1 +github.com/kr/text@v0.1.0 github.com/kr/pty@v1.1.1 +github.com/cpuguy83/go-md2man/v2@v2.0.6 github.com/russross/blackfriday/v2@v2.1.0 +go.yaml.in/yaml/v3@v3.0.4 gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405 +github.com/stretchr/testify@v1.3.0 github.com/davecgh/go-spew@v1.1.0 +github.com/stretchr/testify@v1.3.0 github.com/pmezard/go-difflib@v1.0.0 +github.com/stretchr/testify@v1.3.0 github.com/stretchr/objx@v0.1.0 +gopkg.in/yaml.v3@v3.0.0-20200313102051-9f266ea9e77c gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405 +golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f github.com/yuin/goldmark@v1.1.27 +golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f golang.org/x/mod@v0.2.0 +golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f golang.org/x/net@v0.0.0-20200226121028-0de0cce0169b +golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f golang.org/x/sync@v0.0.0-20190911185100-cd5d95a43a6e +golang.org/x/tools@v0.0.0-20200619180055-7c47624df98f golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543 +golang.org/x/mod@v0.3.0 golang.org/x/crypto@v0.0.0-20191011191535-87dc89f01550 +golang.org/x/mod@v0.3.0 golang.org/x/tools@v0.0.0-20191119224855-298f0cb1881e +golang.org/x/mod@v0.3.0 golang.org/x/xerrors@v0.0.0-20191011141410-1b5146add898 +golang.org/x/net@v0.0.0-20201021035429-f5854403a974 golang.org/x/crypto@v0.0.0-20200622213623-75b288015ac9 +golang.org/x/net@v0.0.0-20201021035429-f5854403a974 golang.org/x/sys@v0.0.0-20200930185726-fdedc70b468f +golang.org/x/net@v0.0.0-20201021035429-f5854403a974 golang.org/x/text@v0.3.3 +golang.org/x/mod@v0.2.0 golang.org/x/crypto@v0.0.0-20191011191535-87dc89f01550 +golang.org/x/mod@v0.2.0 golang.org/x/tools@v0.0.0-20191119224855-298f0cb1881e +golang.org/x/mod@v0.2.0 golang.org/x/xerrors@v0.0.0-20191011141410-1b5146add898 +golang.org/x/net@v0.0.0-20200226121028-0de0cce0169b golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2 +golang.org/x/net@v0.0.0-20200226121028-0de0cce0169b golang.org/x/sys@v0.0.0-20190215142949-d0b11bdaac8a +golang.org/x/net@v0.0.0-20200226121028-0de0cce0169b golang.org/x/text@v0.3.0 +golang.org/x/crypto@v0.0.0-20191011191535-87dc89f01550 golang.org/x/net@v0.0.0-20190404232315-eb5bcb51f2a3 +golang.org/x/crypto@v0.0.0-20191011191535-87dc89f01550 golang.org/x/sys@v0.0.0-20190412213103-97732733099d +golang.org/x/tools@v0.0.0-20191119224855-298f0cb1881e golang.org/x/net@v0.0.0-20190620200207-3b0461eec859 +golang.org/x/tools@v0.0.0-20191119224855-298f0cb1881e golang.org/x/sync@v0.0.0-20190423024810-112230192c58 +golang.org/x/tools@v0.0.0-20191119224855-298f0cb1881e golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7 +golang.org/x/crypto@v0.0.0-20200622213623-75b288015ac9 golang.org/x/net@v0.0.0-20190404232315-eb5bcb51f2a3 +golang.org/x/crypto@v0.0.0-20200622213623-75b288015ac9 golang.org/x/sys@v0.0.0-20190412213103-97732733099d +golang.org/x/text@v0.3.3 golang.org/x/tools@v0.0.0-20180917221912-90fa682c2a6e +golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/sys@v0.0.0-20190215142949-d0b11bdaac8a +golang.org/x/net@v0.0.0-20190404232315-eb5bcb51f2a3 golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2 +golang.org/x/net@v0.0.0-20190404232315-eb5bcb51f2a3 golang.org/x/text@v0.3.0 +golang.org/x/net@v0.0.0-20190620200207-3b0461eec859 golang.org/x/crypto@v0.0.0-20190308221718-c2843e01d9a2 +golang.org/x/net@v0.0.0-20190620200207-3b0461eec859 golang.org/x/sys@v0.0.0-20190215142949-d0b11bdaac8a +golang.org/x/net@v0.0.0-20190620200207-3b0461eec859 golang.org/x/text@v0.3.0 diff --git a/bridge/idp/locks/generated/inputs.lock b/bridge/idp/locks/generated/inputs.lock new file mode 100644 index 00000000..8f0a8db2 --- /dev/null +++ b/bridge/idp/locks/generated/inputs.lock @@ -0,0 +1,6 @@ +# Public, immutable shell assignments; never source an unreviewed generated file. +DEX_COMMIT=11d2eeb52b42e1980e14cb91e69dd9e3faab2076 +DEX_ARCHIVE_SHA256=18bf92e8ccbf53e86814c2beb39b7d59f28fb07c84639e9f47a9bb5ea764e0b9 +DEX_VERSION=v2.45.1-kars.1 +GO_VERSION=go1.26.8 +SOURCE_DATE_EPOCH=0 diff --git a/bridge/idp/locks/generated/modules.json b/bridge/idp/locks/generated/modules.json new file mode 100644 index 00000000..07dbc55e --- /dev/null +++ b/bridge/idp/locks/generated/modules.json @@ -0,0 +1,2029 @@ +{ + "Path": "github.com/dexidp/dex", + "Main": true, + "Dir": "/src/dex", + "GoMod": "/src/dex/go.mod", + "GoVersion": "1.26.0" +} +{ + "Path": "ariga.io/atlas", + "Version": "v0.32.1-0.20250325101103-175b25e1c1b9", + "Time": "2025-03-25T10:11:03Z", + "Indirect": true, + "Dir": "/work/mod/ariga.io/atlas@v0.32.1-0.20250325101103-175b25e1c1b9", + "GoMod": "/work/mod/cache/download/ariga.io/atlas/@v/v0.32.1-0.20250325101103-175b25e1c1b9.mod", + "GoVersion": "1.22.12", + "Sum": "h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc=", + "GoModSum": "h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w=" +} +{ + "Path": "cel.dev/expr", + "Version": "v0.25.2", + "Time": "2026-03-12T16:46:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cel.dev/expr/@v/v0.25.2.mod", + "GoVersion": "1.23.0" +} +{ + "Path": "cloud.google.com/go", + "Version": "v0.112.2", + "Time": "2024-03-27T20:20:16Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cloud.google.com/go/@v/v0.112.2.mod", + "GoVersion": "1.19" +} +{ + "Path": "cloud.google.com/go/auth", + "Version": "v0.18.2", + "Time": "2026-02-13T17:14:27Z", + "Indirect": true, + "Dir": "/work/mod/cloud.google.com/go/auth@v0.18.2", + "GoMod": "/work/mod/cache/download/cloud.google.com/go/auth/@v/v0.18.2.mod", + "GoVersion": "1.24.0", + "Sum": "h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=", + "GoModSum": "h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M=" +} +{ + "Path": "cloud.google.com/go/auth/oauth2adapt", + "Version": "v0.2.8", + "Time": "2025-03-20T15:18:21Z", + "Indirect": true, + "Dir": "/work/mod/cloud.google.com/go/auth/oauth2adapt@v0.2.8", + "GoMod": "/work/mod/cache/download/cloud.google.com/go/auth/oauth2adapt/@v/v0.2.8.mod", + "GoVersion": "1.23.0", + "Sum": "h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=", + "GoModSum": "h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=" +} +{ + "Path": "cloud.google.com/go/compute/metadata", + "Version": "v0.9.0", + "Time": "2025-09-24T19:41:55Z", + "Dir": "/work/mod/cloud.google.com/go/compute/metadata@v0.9.0", + "GoMod": "/work/mod/cache/download/cloud.google.com/go/compute/metadata/@v/v0.9.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=", + "GoModSum": "h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=" +} +{ + "Path": "cloud.google.com/go/longrunning", + "Version": "v0.5.6", + "Time": "2024-03-14T21:02:19Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cloud.google.com/go/longrunning/@v/v0.5.6.mod", + "GoVersion": "1.19" +} +{ + "Path": "cloud.google.com/go/translate", + "Version": "v1.10.3", + "Time": "2024-05-01T18:24:19Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/cloud.google.com/go/translate/@v/v1.10.3.mod", + "GoVersion": "1.19" +} +{ + "Path": "dario.cat/mergo", + "Version": "v1.0.1", + "Time": "2024-08-17T20:16:10Z", + "Indirect": true, + "Dir": "/work/mod/dario.cat/mergo@v1.0.1", + "GoMod": "/work/mod/cache/download/dario.cat/mergo/@v/v1.0.1.mod", + "GoVersion": "1.13", + "Sum": "h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=", + "GoModSum": "h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=" +} +{ + "Path": "entgo.io/ent", + "Version": "v0.14.5", + "Time": "2025-07-21T09:33:06Z", + "Dir": "/work/mod/entgo.io/ent@v0.14.5", + "GoMod": "/work/mod/cache/download/entgo.io/ent/@v/v0.14.5.mod", + "GoVersion": "1.23", + "Sum": "h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=", + "GoModSum": "h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U=" +} +{ + "Path": "filippo.io/edwards25519", + "Version": "v1.1.1", + "Time": "2026-02-17T16:50:01Z", + "Indirect": true, + "Dir": "/work/mod/filippo.io/edwards25519@v1.1.1", + "GoMod": "/work/mod/cache/download/filippo.io/edwards25519/@v/v1.1.1.mod", + "GoVersion": "1.20", + "Sum": "h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=", + "GoModSum": "h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=" +} +{ + "Path": "github.com/AppsFlyer/go-sundheit", + "Version": "v0.6.0", + "Time": "2024-07-25T06:35:08Z", + "Dir": "/work/mod/github.com/!apps!flyer/go-sundheit@v0.6.0", + "GoMod": "/work/mod/cache/download/github.com/!apps!flyer/go-sundheit/@v/v0.6.0.mod", + "GoVersion": "1.15", + "Sum": "h1:d2hBvCjBSb2lUsEWGfPigr4MCOt04sxB+Rppl0yUMSk=", + "GoModSum": "h1:LDdBHD6tQBtmHsdW+i1GwdTt6Wqc0qazf5ZEJVTbTME=" +} +{ + "Path": "github.com/Azure/go-ntlmssp", + "Version": "v0.1.1", + "Time": "2026-04-23T07:51:54Z", + "Indirect": true, + "Dir": "/work/mod/github.com/!azure/go-ntlmssp@v0.1.1", + "GoMod": "/work/mod/cache/download/github.com/!azure/go-ntlmssp/@v/v0.1.1.mod", + "GoVersion": "1.24", + "Sum": "h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw=", + "GoModSum": "h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=" +} +{ + "Path": "github.com/DATA-DOG/go-sqlmock", + "Version": "v1.5.0", + "Time": "2020-06-28T15:11:42Z", + "Indirect": true, + "Dir": "/work/mod/github.com/!d!a!t!a-!d!o!g/go-sqlmock@v1.5.0", + "GoMod": "/work/mod/cache/download/github.com/!d!a!t!a-!d!o!g/go-sqlmock/@v/v1.5.0.mod", + "Sum": "h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=", + "GoModSum": "h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=" +} +{ + "Path": "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp", + "Version": "v1.33.0", + "Time": "2026-06-04T20:21:43Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/!google!cloud!platform/opentelemetry-operations-go/detectors/gcp/@v/v1.33.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "github.com/Masterminds/goutils", + "Version": "v1.1.1", + "Time": "2021-02-04T20:06:53Z", + "Indirect": true, + "Dir": "/work/mod/github.com/!masterminds/goutils@v1.1.1", + "GoMod": "/work/mod/cache/download/github.com/!masterminds/goutils/@v/v1.1.1.mod", + "Sum": "h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=", + "GoModSum": "h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=" +} +{ + "Path": "github.com/Masterminds/semver", + "Version": "v1.5.0", + "Time": "2019-09-11T18:23:18Z", + "Dir": "/work/mod/github.com/!masterminds/semver@v1.5.0", + "GoMod": "/work/mod/cache/download/github.com/!masterminds/semver/@v/v1.5.0.mod", + "Sum": "h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=", + "GoModSum": "h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=" +} +{ + "Path": "github.com/Masterminds/semver/v3", + "Version": "v3.3.0", + "Time": "2024-08-27T21:33:28Z", + "Indirect": true, + "Dir": "/work/mod/github.com/!masterminds/semver/v3@v3.3.0", + "GoMod": "/work/mod/cache/download/github.com/!masterminds/semver/v3/@v/v3.3.0.mod", + "GoVersion": "1.21", + "Sum": "h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=", + "GoModSum": "h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=" +} +{ + "Path": "github.com/Masterminds/sprig/v3", + "Version": "v3.3.0", + "Time": "2024-08-29T20:12:44Z", + "Dir": "/work/mod/github.com/!masterminds/sprig/v3@v3.3.0", + "GoMod": "/work/mod/cache/download/github.com/!masterminds/sprig/v3/@v/v3.3.0.mod", + "GoVersion": "1.21", + "Sum": "h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=", + "GoModSum": "h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=" +} +{ + "Path": "github.com/agext/levenshtein", + "Version": "v1.2.3", + "Time": "2020-03-12T21:09:59Z", + "Indirect": true, + "Dir": "/work/mod/github.com/agext/levenshtein@v1.2.3", + "GoMod": "/work/mod/cache/download/github.com/agext/levenshtein/@v/v1.2.3.mod", + "Sum": "h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=", + "GoModSum": "h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=" +} +{ + "Path": "github.com/alecthomas/kingpin/v2", + "Version": "v2.4.0", + "Time": "2023-09-30T22:59:49Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/alecthomas/kingpin/v2/@v/v2.4.0.mod", + "GoVersion": "1.17" +} +{ + "Path": "github.com/alecthomas/units", + "Version": "v0.0.0-20211218093645-b94a6e3cc137", + "Time": "2021-12-18T09:36:45Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/alecthomas/units/@v/v0.0.0-20211218093645-b94a6e3cc137.mod", + "GoVersion": "1.15" +} +{ + "Path": "github.com/alexbrainman/sspi", + "Version": "v0.0.0-20250919150558-7d374ff0d59e", + "Time": "2025-09-19T15:05:58Z", + "Indirect": true, + "Dir": "/work/mod/github.com/alexbrainman/sspi@v0.0.0-20250919150558-7d374ff0d59e", + "GoMod": "/work/mod/cache/download/github.com/alexbrainman/sspi/@v/v0.0.0-20250919150558-7d374ff0d59e.mod", + "GoVersion": "1.13", + "Sum": "h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=", + "GoModSum": "h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=" +} +{ + "Path": "github.com/antihax/optional", + "Version": "v1.0.0", + "Time": "2019-10-10T23:37:20Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/antihax/optional/@v/v1.0.0.mod", + "GoVersion": "1.13" +} +{ + "Path": "github.com/apparentlymart/go-dump", + "Version": "v0.0.0-20180507223929-23540a00eaa3", + "Time": "2018-05-07T22:39:29Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/apparentlymart/go-dump/@v/v0.0.0-20180507223929-23540a00eaa3.mod" +} +{ + "Path": "github.com/apparentlymart/go-textseg/v13", + "Version": "v13.0.0", + "Time": "2021-02-22T23:45:06Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/apparentlymart/go-textseg/v13/@v/v13.0.0.mod", + "GoVersion": "1.16" +} +{ + "Path": "github.com/apparentlymart/go-textseg/v15", + "Version": "v15.0.0", + "Time": "2023-08-29T15:35:34Z", + "Indirect": true, + "Dir": "/work/mod/github.com/apparentlymart/go-textseg/v15@v15.0.0", + "GoMod": "/work/mod/cache/download/github.com/apparentlymart/go-textseg/v15/@v/v15.0.0.mod", + "GoVersion": "1.16", + "Sum": "h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=", + "GoModSum": "h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=" +} +{ + "Path": "github.com/armon/go-radix", + "Version": "v0.0.0-20180808171621-7fddfc383310", + "Time": "2018-08-08T17:16:21Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/armon/go-radix/@v/v0.0.0-20180808171621-7fddfc383310.mod" +} +{ + "Path": "github.com/beevik/etree", + "Version": "v1.6.0", + "Time": "2025-08-22T22:58:11Z", + "Dir": "/work/mod/github.com/beevik/etree@v1.6.0", + "GoMod": "/work/mod/cache/download/github.com/beevik/etree/@v/v1.6.0.mod", + "GoVersion": "1.23.0", + "Sum": "h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE=", + "GoModSum": "h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=" +} +{ + "Path": "github.com/beorn7/perks", + "Version": "v1.0.1", + "Time": "2019-07-31T12:00:54Z", + "Indirect": true, + "Dir": "/work/mod/github.com/beorn7/perks@v1.0.1", + "GoMod": "/work/mod/cache/download/github.com/beorn7/perks/@v/v1.0.1.mod", + "GoVersion": "1.11", + "Sum": "h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=", + "GoModSum": "h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=" +} +{ + "Path": "github.com/bgentry/speakeasy", + "Version": "v0.1.0", + "Time": "2017-04-17T20:07:03Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/bgentry/speakeasy/@v/v0.1.0.mod" +} +{ + "Path": "github.com/bmatcuk/doublestar", + "Version": "v1.3.4", + "Time": "2020-11-19T00:35:16Z", + "Indirect": true, + "Dir": "/work/mod/github.com/bmatcuk/doublestar@v1.3.4", + "GoMod": "/work/mod/cache/download/github.com/bmatcuk/doublestar/@v/v1.3.4.mod", + "GoVersion": "1.12", + "Sum": "h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=", + "GoModSum": "h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=" +} +{ + "Path": "github.com/cenkalti/backoff/v4", + "Version": "v4.3.0", + "Time": "2024-01-02T22:56:19Z", + "Indirect": true, + "Dir": "/work/mod/github.com/cenkalti/backoff/v4@v4.3.0", + "GoMod": "/work/mod/cache/download/github.com/cenkalti/backoff/v4/@v/v4.3.0.mod", + "GoVersion": "1.18", + "Sum": "h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=", + "GoModSum": "h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=" +} +{ + "Path": "github.com/cespare/xxhash/v2", + "Version": "v2.3.0", + "Time": "2024-04-04T20:00:10Z", + "Indirect": true, + "Dir": "/work/mod/github.com/cespare/xxhash/v2@v2.3.0", + "GoMod": "/work/mod/cache/download/github.com/cespare/xxhash/v2/@v/v2.3.0.mod", + "GoVersion": "1.11", + "Sum": "h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=", + "GoModSum": "h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=" +} +{ + "Path": "github.com/cncf/xds/go", + "Version": "v0.0.0-20260202195803-dba9d589def2", + "Time": "2026-02-02T19:58:03Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/cncf/xds/go/@v/v0.0.0-20260202195803-dba9d589def2.mod", + "GoVersion": "1.24.6" +} +{ + "Path": "github.com/coreos/go-oidc/v3", + "Version": "v3.17.0", + "Time": "2025-11-21T03:32:42Z", + "Dir": "/work/mod/github.com/coreos/go-oidc/v3@v3.17.0", + "GoMod": "/work/mod/cache/download/github.com/coreos/go-oidc/v3/@v/v3.17.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc=", + "GoModSum": "h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=" +} +{ + "Path": "github.com/coreos/go-semver", + "Version": "v0.3.1", + "Time": "2023-01-16T22:04:39Z", + "Indirect": true, + "Dir": "/work/mod/github.com/coreos/go-semver@v0.3.1", + "GoMod": "/work/mod/cache/download/github.com/coreos/go-semver/@v/v0.3.1.mod", + "GoVersion": "1.8", + "Sum": "h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=", + "GoModSum": "h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=" +} +{ + "Path": "github.com/coreos/go-systemd/v22", + "Version": "v22.5.0", + "Time": "2022-11-07T13:52:27Z", + "Indirect": true, + "Dir": "/work/mod/github.com/coreos/go-systemd/v22@v22.5.0", + "GoMod": "/work/mod/cache/download/github.com/coreos/go-systemd/v22/@v/v22.5.0.mod", + "GoVersion": "1.12", + "Sum": "h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=", + "GoModSum": "h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=" +} +{ + "Path": "github.com/cpuguy83/go-md2man/v2", + "Version": "v2.0.6", + "Time": "2024-12-16T17:50:50Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/cpuguy83/go-md2man/v2/@v/v2.0.6.mod", + "GoVersion": "1.12", + "GoModSum": "h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=" +} +{ + "Path": "github.com/davecgh/go-spew", + "Version": "v1.1.2-0.20180830191138-d8f796af33cc", + "Time": "2018-08-30T19:11:38Z", + "Indirect": true, + "Dir": "/work/mod/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc", + "GoMod": "/work/mod/cache/download/github.com/davecgh/go-spew/@v/v1.1.2-0.20180830191138-d8f796af33cc.mod", + "Sum": "h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=", + "GoModSum": "h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=" +} +{ + "Path": "github.com/dexidp/dex/api/v2", + "Version": "v2.4.0", + "Replace": { + "Path": "./api/v2", + "Dir": "/src/dex/api/v2", + "GoMod": "/src/dex/api/v2/go.mod", + "GoVersion": "1.26.0" + }, + "Dir": "/src/dex/api/v2", + "GoMod": "/src/dex/api/v2/go.mod", + "GoVersion": "1.26.0" +} +{ + "Path": "github.com/dustin/go-humanize", + "Version": "v1.0.1", + "Time": "2023-01-10T06:44:38Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/dustin/go-humanize/@v/v1.0.1.mod", + "GoVersion": "1.16" +} +{ + "Path": "github.com/envoyproxy/go-control-plane", + "Version": "v0.14.0", + "Time": "2025-11-04T22:01:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/@v/v0.14.0.mod", + "GoVersion": "1.23.0" +} +{ + "Path": "github.com/envoyproxy/go-control-plane/envoy", + "Version": "v1.37.0", + "Time": "2026-01-13T06:26:49Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/envoy/@v/v1.37.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/envoyproxy/go-control-plane/ratelimit", + "Version": "v0.1.0", + "Time": "2024-12-23T15:25:59Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/go-control-plane/ratelimit/@v/v0.1.0.mod", + "GoVersion": "1.21" +} +{ + "Path": "github.com/envoyproxy/protoc-gen-validate", + "Version": "v1.3.3", + "Time": "2026-02-18T16:13:16Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/envoyproxy/protoc-gen-validate/@v/v1.3.3.mod", + "GoVersion": "1.24.1" +} +{ + "Path": "github.com/fatih/color", + "Version": "v1.18.0", + "Time": "2024-10-03T07:06:28Z", + "Indirect": true, + "Dir": "/work/mod/github.com/fatih/color@v1.18.0", + "GoMod": "/work/mod/cache/download/github.com/fatih/color/@v/v1.18.0.mod", + "GoVersion": "1.17", + "Sum": "h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=", + "GoModSum": "h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=" +} +{ + "Path": "github.com/felixge/httpsnoop", + "Version": "v1.0.4", + "Time": "2023-03-12T10:31:09Z", + "Indirect": true, + "Dir": "/work/mod/github.com/felixge/httpsnoop@v1.0.4", + "GoMod": "/work/mod/cache/download/github.com/felixge/httpsnoop/@v/v1.0.4.mod", + "GoVersion": "1.13", + "Sum": "h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=", + "GoModSum": "h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=" +} +{ + "Path": "github.com/fortytw2/leaktest", + "Version": "v1.3.0", + "Time": "2018-11-09T15:15:30Z", + "Indirect": true, + "Dir": "/work/mod/github.com/fortytw2/leaktest@v1.3.0", + "GoMod": "/work/mod/cache/download/github.com/fortytw2/leaktest/@v/v1.3.0.mod", + "Sum": "h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=", + "GoModSum": "h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=" +} +{ + "Path": "github.com/frankban/quicktest", + "Version": "v1.14.6", + "Time": "2023-08-01T06:27:26Z", + "Indirect": true, + "Dir": "/work/mod/github.com/frankban/quicktest@v1.14.6", + "GoMod": "/work/mod/cache/download/github.com/frankban/quicktest/@v/v1.14.6.mod", + "GoVersion": "1.13", + "Sum": "h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=", + "GoModSum": "h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=" +} +{ + "Path": "github.com/fsnotify/fsnotify", + "Version": "v1.9.0", + "Time": "2025-04-04T15:13:49Z", + "Dir": "/work/mod/github.com/fsnotify/fsnotify@v1.9.0", + "GoMod": "/work/mod/cache/download/github.com/fsnotify/fsnotify/@v/v1.9.0.mod", + "GoVersion": "1.17", + "Sum": "h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=", + "GoModSum": "h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=" +} +{ + "Path": "github.com/ghodss/yaml", + "Version": "v1.0.0", + "Time": "2017-03-27T23:54:44Z", + "Dir": "/work/mod/github.com/ghodss/yaml@v1.0.0", + "GoMod": "/work/mod/cache/download/github.com/ghodss/yaml/@v/v1.0.0.mod", + "Sum": "h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=", + "GoModSum": "h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=" +} +{ + "Path": "github.com/go-asn1-ber/asn1-ber", + "Version": "v1.5.8-0.20250403174932-29230038a667", + "Time": "2025-04-03T17:49:32Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-asn1-ber/asn1-ber@v1.5.8-0.20250403174932-29230038a667", + "GoMod": "/work/mod/cache/download/github.com/go-asn1-ber/asn1-ber/@v/v1.5.8-0.20250403174932-29230038a667.mod", + "GoVersion": "1.13", + "Sum": "h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=", + "GoModSum": "h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=" +} +{ + "Path": "github.com/go-jose/go-jose/v4", + "Version": "v4.1.4", + "Time": "2026-03-31T23:33:50Z", + "Dir": "/work/mod/github.com/go-jose/go-jose/v4@v4.1.4", + "GoMod": "/work/mod/cache/download/github.com/go-jose/go-jose/v4/@v/v4.1.4.mod", + "GoVersion": "1.24.0", + "Sum": "h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=", + "GoModSum": "h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=" +} +{ + "Path": "github.com/go-ldap/ldap/v3", + "Version": "v3.4.12", + "Time": "2025-10-01T13:57:01Z", + "Dir": "/work/mod/github.com/go-ldap/ldap/v3@v3.4.12", + "GoMod": "/work/mod/cache/download/github.com/go-ldap/ldap/v3/@v/v3.4.12.mod", + "GoVersion": "1.23.0", + "Sum": "h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=", + "GoModSum": "h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo=" +} +{ + "Path": "github.com/go-logr/logr", + "Version": "v1.4.3", + "Time": "2025-05-19T04:56:57Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-logr/logr@v1.4.3", + "GoMod": "/work/mod/cache/download/github.com/go-logr/logr/@v/v1.4.3.mod", + "GoVersion": "1.18", + "Sum": "h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=", + "GoModSum": "h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=" +} +{ + "Path": "github.com/go-logr/stdr", + "Version": "v1.2.2", + "Time": "2021-12-14T08:00:35Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-logr/stdr@v1.2.2", + "GoMod": "/work/mod/cache/download/github.com/go-logr/stdr/@v/v1.2.2.mod", + "GoVersion": "1.16", + "Sum": "h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=", + "GoModSum": "h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=" +} +{ + "Path": "github.com/go-openapi/inflect", + "Version": "v0.19.0", + "Time": "2018-10-07T00:18:42Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-openapi/inflect@v0.19.0", + "GoMod": "/work/mod/cache/download/github.com/go-openapi/inflect/@v/v0.19.0.mod", + "Sum": "h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=", + "GoModSum": "h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=" +} +{ + "Path": "github.com/go-sql-driver/mysql", + "Version": "v1.9.3", + "Time": "2025-06-13T06:20:32Z", + "Dir": "/work/mod/github.com/go-sql-driver/mysql@v1.9.3", + "GoMod": "/work/mod/cache/download/github.com/go-sql-driver/mysql/@v/v1.9.3.mod", + "GoVersion": "1.21.0", + "Sum": "h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=", + "GoModSum": "h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=" +} +{ + "Path": "github.com/go-test/deep", + "Version": "v1.1.1", + "Time": "2024-06-23T16:27:23Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-test/deep@v1.1.1", + "GoMod": "/work/mod/cache/download/github.com/go-test/deep/@v/v1.1.1.mod", + "GoVersion": "1.16", + "Sum": "h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=", + "GoModSum": "h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=" +} +{ + "Path": "github.com/go-viper/mapstructure/v2", + "Version": "v2.4.0", + "Time": "2025-07-15T08:59:08Z", + "Indirect": true, + "Dir": "/work/mod/github.com/go-viper/mapstructure/v2@v2.4.0", + "GoMod": "/work/mod/cache/download/github.com/go-viper/mapstructure/v2/@v/v2.4.0.mod", + "GoVersion": "1.18", + "Sum": "h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=", + "GoModSum": "h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=" +} +{ + "Path": "github.com/godbus/dbus/v5", + "Version": "v5.0.4", + "Time": "2021-03-23T03:10:11Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/godbus/dbus/v5/@v/v5.0.4.mod", + "GoVersion": "1.12", + "GoModSum": "h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=" +} +{ + "Path": "github.com/gogo/protobuf", + "Version": "v1.3.2", + "Time": "2021-01-10T08:01:47Z", + "Indirect": true, + "Dir": "/work/mod/github.com/gogo/protobuf@v1.3.2", + "GoMod": "/work/mod/cache/download/github.com/gogo/protobuf/@v/v1.3.2.mod", + "GoVersion": "1.15", + "Sum": "h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=", + "GoModSum": "h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=" +} +{ + "Path": "github.com/golang/glog", + "Version": "v1.2.5", + "Time": "2025-04-29T08:43:26Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/golang/glog/@v/v1.2.5.mod", + "GoVersion": "1.19" +} +{ + "Path": "github.com/golang/groupcache", + "Version": "v0.0.0-20210331224755-41bb18bfe9da", + "Time": "2021-03-31T22:47:55Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/golang/groupcache/@v/v0.0.0-20210331224755-41bb18bfe9da.mod" +} +{ + "Path": "github.com/golang/protobuf", + "Version": "v1.5.4", + "Time": "2024-03-06T06:45:40Z", + "Indirect": true, + "Dir": "/work/mod/github.com/golang/protobuf@v1.5.4", + "GoMod": "/work/mod/cache/download/github.com/golang/protobuf/@v/v1.5.4.mod", + "GoVersion": "1.17", + "Sum": "h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=", + "GoModSum": "h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=" +} +{ + "Path": "github.com/google/go-cmp", + "Version": "v0.7.0", + "Time": "2025-01-14T18:15:44Z", + "Indirect": true, + "Dir": "/work/mod/github.com/google/go-cmp@v0.7.0", + "GoMod": "/work/mod/cache/download/github.com/google/go-cmp/@v/v0.7.0.mod", + "GoVersion": "1.21", + "Sum": "h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=", + "GoModSum": "h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=" +} +{ + "Path": "github.com/google/go-pkcs11", + "Version": "v0.3.0", + "Time": "2023-09-07T21:50:43Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/google/go-pkcs11/@v/v0.3.0.mod", + "GoVersion": "1.17" +} +{ + "Path": "github.com/google/s2a-go", + "Version": "v0.1.9", + "Time": "2025-01-06T17:53:46Z", + "Indirect": true, + "Dir": "/work/mod/github.com/google/s2a-go@v0.1.9", + "GoMod": "/work/mod/cache/download/github.com/google/s2a-go/@v/v0.1.9.mod", + "GoVersion": "1.20", + "Sum": "h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=", + "GoModSum": "h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=" +} +{ + "Path": "github.com/google/uuid", + "Version": "v1.6.0", + "Time": "2024-01-23T18:54:04Z", + "Dir": "/work/mod/github.com/google/uuid@v1.6.0", + "GoMod": "/work/mod/cache/download/github.com/google/uuid/@v/v1.6.0.mod", + "Sum": "h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=", + "GoModSum": "h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=" +} +{ + "Path": "github.com/googleapis/enterprise-certificate-proxy", + "Version": "v0.3.11", + "Time": "2026-01-13T07:11:36Z", + "Indirect": true, + "Dir": "/work/mod/github.com/googleapis/enterprise-certificate-proxy@v0.3.11", + "GoMod": "/work/mod/cache/download/github.com/googleapis/enterprise-certificate-proxy/@v/v0.3.11.mod", + "GoVersion": "1.24.0", + "Sum": "h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=", + "GoModSum": "h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=" +} +{ + "Path": "github.com/googleapis/gax-go/v2", + "Version": "v2.17.0", + "Time": "2026-02-03T18:41:38Z", + "Indirect": true, + "Dir": "/work/mod/github.com/googleapis/gax-go/v2@v2.17.0", + "GoMod": "/work/mod/cache/download/github.com/googleapis/gax-go/v2/@v/v2.17.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc=", + "GoModSum": "h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY=" +} +{ + "Path": "github.com/gorilla/handlers", + "Version": "v1.5.2", + "Time": "2023-10-18T11:25:31Z", + "Dir": "/work/mod/github.com/gorilla/handlers@v1.5.2", + "GoMod": "/work/mod/cache/download/github.com/gorilla/handlers/@v/v1.5.2.mod", + "GoVersion": "1.20", + "Sum": "h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=", + "GoModSum": "h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=" +} +{ + "Path": "github.com/gorilla/mux", + "Version": "v1.8.1", + "Time": "2023-10-18T11:23:00Z", + "Dir": "/work/mod/github.com/gorilla/mux@v1.8.1", + "GoMod": "/work/mod/cache/download/github.com/gorilla/mux/@v/v1.8.1.mod", + "GoVersion": "1.20", + "Sum": "h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=", + "GoModSum": "h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=" +} +{ + "Path": "github.com/gorilla/websocket", + "Version": "v1.5.0", + "Time": "2022-01-04T01:59:52Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/gorilla/websocket/@v/v1.5.0.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus", + "Version": "v1.0.1", + "Time": "2024-04-25T04:50:13Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/@v/v1.0.1.mod", + "GoVersion": "1.19" +} +{ + "Path": "github.com/grpc-ecosystem/go-grpc-middleware/v2", + "Version": "v2.1.0", + "Time": "2024-02-22T15:43:25Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/grpc-ecosystem/go-grpc-middleware/v2/@v/v2.1.0.mod", + "GoVersion": "1.19" +} +{ + "Path": "github.com/grpc-ecosystem/go-grpc-prometheus", + "Version": "v1.2.0", + "Time": "2018-06-04T12:28:56Z", + "Dir": "/work/mod/github.com/grpc-ecosystem/go-grpc-prometheus@v1.2.0", + "GoMod": "/work/mod/cache/download/github.com/grpc-ecosystem/go-grpc-prometheus/@v/v1.2.0.mod", + "Sum": "h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=", + "GoModSum": "h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=" +} +{ + "Path": "github.com/grpc-ecosystem/grpc-gateway/v2", + "Version": "v2.26.3", + "Time": "2025-03-04T17:40:45Z", + "Indirect": true, + "Dir": "/work/mod/github.com/grpc-ecosystem/grpc-gateway/v2@v2.26.3", + "GoMod": "/work/mod/cache/download/github.com/grpc-ecosystem/grpc-gateway/v2/@v/v2.26.3.mod", + "GoVersion": "1.23.0", + "Sum": "h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=", + "GoModSum": "h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=" +} +{ + "Path": "github.com/hashicorp/errwrap", + "Version": "v1.1.0", + "Time": "2020-07-14T15:51:01Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/errwrap@v1.1.0", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/errwrap/@v/v1.1.0.mod", + "Sum": "h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=", + "GoModSum": "h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=" +} +{ + "Path": "github.com/hashicorp/go-cleanhttp", + "Version": "v0.5.2", + "Time": "2021-02-03T18:51:13Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-cleanhttp@v0.5.2", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-cleanhttp/@v/v0.5.2.mod", + "GoVersion": "1.13", + "Sum": "h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=", + "GoModSum": "h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=" +} +{ + "Path": "github.com/hashicorp/go-hclog", + "Version": "v1.6.3", + "Time": "2024-04-01T20:03:54Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-hclog@v1.6.3", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-hclog/@v/v1.6.3.mod", + "GoVersion": "1.13", + "Sum": "h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=", + "GoModSum": "h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=" +} +{ + "Path": "github.com/hashicorp/go-multierror", + "Version": "v1.1.1", + "Time": "2021-03-11T20:17:12Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-multierror@v1.1.1", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-multierror/@v/v1.1.1.mod", + "GoVersion": "1.13", + "Sum": "h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=", + "GoModSum": "h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=" +} +{ + "Path": "github.com/hashicorp/go-retryablehttp", + "Version": "v0.7.8", + "Time": "2025-06-18T14:25:10Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-retryablehttp@v0.7.8", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-retryablehttp/@v/v0.7.8.mod", + "GoVersion": "1.23", + "Sum": "h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=", + "GoModSum": "h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=" +} +{ + "Path": "github.com/hashicorp/go-secure-stdlib/parseutil", + "Version": "v0.2.0", + "Time": "2025-03-06T22:34:24Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-secure-stdlib/parseutil@v0.2.0", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-secure-stdlib/parseutil/@v/v0.2.0.mod", + "GoVersion": "1.20", + "Sum": "h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=", + "GoModSum": "h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=" +} +{ + "Path": "github.com/hashicorp/go-secure-stdlib/strutil", + "Version": "v0.1.2", + "Time": "2021-11-22T19:44:14Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-secure-stdlib/strutil/@v/v0.1.2.mod", + "GoVersion": "1.16", + "Sum": "h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=", + "GoModSum": "h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=" +} +{ + "Path": "github.com/hashicorp/go-sockaddr", + "Version": "v1.0.7", + "Time": "2024-09-19T09:47:04Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-sockaddr@v1.0.7", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-sockaddr/@v/v1.0.7.mod", + "GoVersion": "1.19", + "Sum": "h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=", + "GoModSum": "h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=" +} +{ + "Path": "github.com/hashicorp/go-uuid", + "Version": "v1.0.3", + "Time": "2022-04-08T14:59:45Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/go-uuid@v1.0.3", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/go-uuid/@v/v1.0.3.mod", + "Sum": "h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=", + "GoModSum": "h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=" +} +{ + "Path": "github.com/hashicorp/hcl", + "Version": "v1.0.1-vault-7", + "Time": "2024-11-07T22:23:56Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/hcl@v1.0.1-vault-7", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/hcl/@v/v1.0.1-vault-7.mod", + "GoVersion": "1.15", + "Sum": "h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=", + "GoModSum": "h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=" +} +{ + "Path": "github.com/hashicorp/hcl/v2", + "Version": "v2.18.1", + "Time": "2023-10-06T01:44:43Z", + "Indirect": true, + "Dir": "/work/mod/github.com/hashicorp/hcl/v2@v2.18.1", + "GoMod": "/work/mod/cache/download/github.com/hashicorp/hcl/v2/@v/v2.18.1.mod", + "GoVersion": "1.18", + "Sum": "h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo=", + "GoModSum": "h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=" +} +{ + "Path": "github.com/huandu/xstrings", + "Version": "v1.5.0", + "Time": "2024-06-06T08:07:36Z", + "Indirect": true, + "Dir": "/work/mod/github.com/huandu/xstrings@v1.5.0", + "GoMod": "/work/mod/cache/download/github.com/huandu/xstrings/@v/v1.5.0.mod", + "GoVersion": "1.12", + "Sum": "h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=", + "GoModSum": "h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=" +} +{ + "Path": "github.com/imdario/mergo", + "Version": "v0.3.11", + "Time": "2020-08-11T19:49:30Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/imdario/mergo/@v/v0.3.11.mod", + "GoVersion": "1.13" +} +{ + "Path": "github.com/inconshreveable/mousetrap", + "Version": "v1.1.0", + "Time": "2022-11-27T22:01:53Z", + "Indirect": true, + "Dir": "/work/mod/github.com/inconshreveable/mousetrap@v1.1.0", + "GoMod": "/work/mod/cache/download/github.com/inconshreveable/mousetrap/@v/v1.1.0.mod", + "GoVersion": "1.18", + "Sum": "h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=", + "GoModSum": "h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=" +} +{ + "Path": "github.com/jcmturner/aescts/v2", + "Version": "v2.0.0", + "Time": "2020-02-04T21:18:11Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/aescts/v2@v2.0.0", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/aescts/v2/@v/v2.0.0.mod", + "GoVersion": "1.13", + "Sum": "h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=", + "GoModSum": "h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=" +} +{ + "Path": "github.com/jcmturner/dnsutils/v2", + "Version": "v2.0.0", + "Time": "2020-02-04T20:52:29Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/dnsutils/v2@v2.0.0", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/dnsutils/v2/@v/v2.0.0.mod", + "GoVersion": "1.13", + "Sum": "h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=", + "GoModSum": "h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=" +} +{ + "Path": "github.com/jcmturner/gofork", + "Version": "v1.7.6", + "Time": "2022-07-26T06:17:42Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/gofork@v1.7.6", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/gofork/@v/v1.7.6.mod", + "GoVersion": "1.7", + "Sum": "h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=", + "GoModSum": "h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=" +} +{ + "Path": "github.com/jcmturner/goidentity/v6", + "Version": "v6.0.1", + "Time": "2020-01-19T21:33:46Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/goidentity/v6@v6.0.1", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/goidentity/v6/@v/v6.0.1.mod", + "GoVersion": "1.13", + "Sum": "h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=", + "GoModSum": "h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=" +} +{ + "Path": "github.com/jcmturner/gokrb5/v8", + "Version": "v8.4.4", + "Time": "2023-02-25T07:18:19Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/gokrb5/v8@v8.4.4", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/gokrb5/v8/@v/v8.4.4.mod", + "GoVersion": "1.16", + "Sum": "h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=", + "GoModSum": "h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=" +} +{ + "Path": "github.com/jcmturner/rpc/v2", + "Version": "v2.0.3", + "Time": "2020-11-12T14:32:19Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jcmturner/rpc/v2@v2.0.3", + "GoMod": "/work/mod/cache/download/github.com/jcmturner/rpc/v2/@v/v2.0.3.mod", + "GoVersion": "1.13", + "Sum": "h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=", + "GoModSum": "h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=" +} +{ + "Path": "github.com/jessevdk/go-flags", + "Version": "v1.5.0", + "Time": "2021-03-21T10:32:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/jessevdk/go-flags/@v/v1.5.0.mod", + "GoVersion": "1.15" +} +{ + "Path": "github.com/jonboulle/clockwork", + "Version": "v0.5.0", + "Time": "2024-11-29T18:02:53Z", + "Indirect": true, + "Dir": "/work/mod/github.com/jonboulle/clockwork@v0.5.0", + "GoMod": "/work/mod/cache/download/github.com/jonboulle/clockwork/@v/v0.5.0.mod", + "GoVersion": "1.21", + "Sum": "h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=", + "GoModSum": "h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=" +} +{ + "Path": "github.com/jpillora/backoff", + "Version": "v1.0.0", + "Time": "2019-10-03T12:57:08Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/jpillora/backoff/@v/v1.0.0.mod", + "GoVersion": "1.13" +} +{ + "Path": "github.com/json-iterator/go", + "Version": "v1.1.12", + "Time": "2021-09-11T02:17:26Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/json-iterator/go/@v/v1.1.12.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/julienschmidt/httprouter", + "Version": "v1.3.0", + "Time": "2019-09-29T23:21:22Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/julienschmidt/httprouter/@v/v1.3.0.mod", + "GoVersion": "1.7" +} +{ + "Path": "github.com/kisielk/errcheck", + "Version": "v1.5.0", + "Time": "2021-01-05T19:12:31Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/kisielk/errcheck/@v/v1.5.0.mod", + "GoVersion": "1.14", + "GoModSum": "h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=" +} +{ + "Path": "github.com/kisielk/gotool", + "Version": "v1.0.0", + "Time": "2018-02-21T18:54:26Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/kisielk/gotool/@v/v1.0.0.mod", + "GoModSum": "h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=" +} +{ + "Path": "github.com/klauspost/compress", + "Version": "v1.18.0", + "Time": "2025-02-19T09:26:03Z", + "Indirect": true, + "Dir": "/work/mod/github.com/klauspost/compress@v1.18.0", + "GoMod": "/work/mod/cache/download/github.com/klauspost/compress/@v/v1.18.0.mod", + "GoVersion": "1.22", + "Sum": "h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=", + "GoModSum": "h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=" +} +{ + "Path": "github.com/kr/pretty", + "Version": "v0.3.1", + "Time": "2022-08-29T23:03:05Z", + "Indirect": true, + "Dir": "/work/mod/github.com/kr/pretty@v0.3.1", + "GoMod": "/work/mod/cache/download/github.com/kr/pretty/@v/v0.3.1.mod", + "GoVersion": "1.12", + "Sum": "h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=", + "GoModSum": "h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=" +} +{ + "Path": "github.com/kr/pty", + "Version": "v1.1.1", + "Time": "2018-01-13T18:08:13Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/kr/pty/@v/v1.1.1.mod", + "GoModSum": "h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=" +} +{ + "Path": "github.com/kr/text", + "Version": "v0.2.0", + "Time": "2020-02-14T20:31:06Z", + "Indirect": true, + "Dir": "/work/mod/github.com/kr/text@v0.2.0", + "GoMod": "/work/mod/cache/download/github.com/kr/text/@v/v0.2.0.mod", + "Sum": "h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=", + "GoModSum": "h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=" +} +{ + "Path": "github.com/kylelemons/godebug", + "Version": "v1.1.0", + "Time": "2019-05-05T01:16:37Z", + "Dir": "/work/mod/github.com/kylelemons/godebug@v1.1.0", + "GoMod": "/work/mod/cache/download/github.com/kylelemons/godebug/@v/v1.1.0.mod", + "GoVersion": "1.11", + "Sum": "h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=", + "GoModSum": "h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=" +} +{ + "Path": "github.com/lib/pq", + "Version": "v1.11.2", + "Time": "2026-02-10T12:12:42Z", + "Dir": "/work/mod/github.com/lib/pq@v1.11.2", + "GoMod": "/work/mod/cache/download/github.com/lib/pq/@v/v1.11.2.mod", + "GoVersion": "1.21", + "Sum": "h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs=", + "GoModSum": "h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=" +} +{ + "Path": "github.com/mattermost/xml-roundtrip-validator", + "Version": "v0.1.0", + "Time": "2020-12-19T04:09:09Z", + "Dir": "/work/mod/github.com/mattermost/xml-roundtrip-validator@v0.1.0", + "GoMod": "/work/mod/cache/download/github.com/mattermost/xml-roundtrip-validator/@v/v0.1.0.mod", + "GoVersion": "1.14", + "Sum": "h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU=", + "GoModSum": "h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=" +} +{ + "Path": "github.com/mattn/go-colorable", + "Version": "v0.1.14", + "Time": "2025-01-10T08:29:27Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mattn/go-colorable@v0.1.14", + "GoMod": "/work/mod/cache/download/github.com/mattn/go-colorable/@v/v0.1.14.mod", + "GoVersion": "1.18", + "Sum": "h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=", + "GoModSum": "h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=" +} +{ + "Path": "github.com/mattn/go-isatty", + "Version": "v0.0.20", + "Time": "2023-10-17T07:28:21Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mattn/go-isatty@v0.0.20", + "GoMod": "/work/mod/cache/download/github.com/mattn/go-isatty/@v/v0.0.20.mod", + "GoVersion": "1.15", + "Sum": "h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=", + "GoModSum": "h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=" +} +{ + "Path": "github.com/mattn/go-runewidth", + "Version": "v0.0.9", + "Time": "2020-03-20T06:32:21Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mattn/go-runewidth@v0.0.9", + "GoMod": "/work/mod/cache/download/github.com/mattn/go-runewidth/@v/v0.0.9.mod", + "GoVersion": "1.9", + "Sum": "h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=", + "GoModSum": "h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=" +} +{ + "Path": "github.com/mattn/go-sqlite3", + "Version": "v1.14.34", + "Time": "2026-01-16T08:19:36Z", + "Dir": "/work/mod/github.com/mattn/go-sqlite3@v1.14.34", + "GoMod": "/work/mod/cache/download/github.com/mattn/go-sqlite3/@v/v1.14.34.mod", + "GoVersion": "1.19", + "Sum": "h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=", + "GoModSum": "h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=" +} +{ + "Path": "github.com/mitchellh/cli", + "Version": "v1.1.5", + "Time": "2022-09-30T19:19:43Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/mitchellh/cli/@v/v1.1.5.mod", + "GoVersion": "1.11" +} +{ + "Path": "github.com/mitchellh/copystructure", + "Version": "v1.2.0", + "Time": "2021-05-05T17:08:07Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mitchellh/copystructure@v1.2.0", + "GoMod": "/work/mod/cache/download/github.com/mitchellh/copystructure/@v/v1.2.0.mod", + "GoVersion": "1.15", + "Sum": "h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=", + "GoModSum": "h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=" +} +{ + "Path": "github.com/mitchellh/go-wordwrap", + "Version": "v1.0.1", + "Time": "2020-09-25T18:08:01Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mitchellh/go-wordwrap@v1.0.1", + "GoMod": "/work/mod/cache/download/github.com/mitchellh/go-wordwrap/@v/v1.0.1.mod", + "GoVersion": "1.14", + "Sum": "h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=", + "GoModSum": "h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=" +} +{ + "Path": "github.com/mitchellh/mapstructure", + "Version": "v1.5.0", + "Time": "2022-04-20T22:31:31Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mitchellh/mapstructure@v1.5.0", + "GoMod": "/work/mod/cache/download/github.com/mitchellh/mapstructure/@v/v1.5.0.mod", + "GoVersion": "1.14", + "Sum": "h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=", + "GoModSum": "h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=" +} +{ + "Path": "github.com/mitchellh/reflectwalk", + "Version": "v1.0.2", + "Time": "2021-05-03T23:34:11Z", + "Indirect": true, + "Dir": "/work/mod/github.com/mitchellh/reflectwalk@v1.0.2", + "GoMod": "/work/mod/cache/download/github.com/mitchellh/reflectwalk/@v/v1.0.2.mod", + "Sum": "h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=", + "GoModSum": "h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=" +} +{ + "Path": "github.com/modern-go/concurrent", + "Version": "v0.0.0-20180306012644-bacd9c7ef1dd", + "Time": "2018-03-06T01:26:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/modern-go/concurrent/@v/v0.0.0-20180306012644-bacd9c7ef1dd.mod" +} +{ + "Path": "github.com/modern-go/reflect2", + "Version": "v1.0.2", + "Time": "2021-09-11T02:10:30Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/modern-go/reflect2/@v/v1.0.2.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/munnerz/goautoneg", + "Version": "v0.0.0-20191010083416-a7dc8b61c822", + "Time": "2019-10-10T08:34:16Z", + "Indirect": true, + "Dir": "/work/mod/github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822", + "GoMod": "/work/mod/cache/download/github.com/munnerz/goautoneg/@v/v0.0.0-20191010083416-a7dc8b61c822.mod", + "Sum": "h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=", + "GoModSum": "h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=" +} +{ + "Path": "github.com/mwitkow/go-conntrack", + "Version": "v0.0.0-20190716064945-2f068394615f", + "Time": "2019-07-16T06:49:45Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/mwitkow/go-conntrack/@v/v0.0.0-20190716064945-2f068394615f.mod" +} +{ + "Path": "github.com/niemeyer/pretty", + "Version": "v0.0.0-20200227124842-a10e7caefd8e", + "Time": "2020-02-27T12:48:42Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/niemeyer/pretty/@v/v0.0.0-20200227124842-a10e7caefd8e.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/oklog/run", + "Version": "v1.2.0", + "Time": "2025-06-27T13:52:26Z", + "Dir": "/work/mod/github.com/oklog/run@v1.2.0", + "GoMod": "/work/mod/cache/download/github.com/oklog/run/@v/v1.2.0.mod", + "GoVersion": "1.20", + "Sum": "h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=", + "GoModSum": "h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk=" +} +{ + "Path": "github.com/olekukonko/tablewriter", + "Version": "v0.0.5", + "Time": "2021-02-10T15:55:18Z", + "Indirect": true, + "Dir": "/work/mod/github.com/olekukonko/tablewriter@v0.0.5", + "GoMod": "/work/mod/cache/download/github.com/olekukonko/tablewriter/@v/v0.0.5.mod", + "GoVersion": "1.12", + "Sum": "h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=", + "GoModSum": "h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=" +} +{ + "Path": "github.com/openbao/openbao/api/v2", + "Version": "v2.5.1", + "Time": "2026-02-04T13:41:17Z", + "Dir": "/work/mod/github.com/openbao/openbao/api/v2@v2.5.1", + "GoMod": "/work/mod/cache/download/github.com/openbao/openbao/api/v2/@v/v2.5.1.mod", + "GoVersion": "1.24.0", + "Sum": "h1:Br79D6L20SbAa5P7xqENxmvv8LyI4HoKosPy7klhn4o=", + "GoModSum": "h1:Dh5un77tqGgMbmlVEqjqN+8/dMyUohnkaQVg/wXW0Ig=" +} +{ + "Path": "github.com/pkg/errors", + "Version": "v0.9.1", + "Time": "2020-01-14T19:47:44Z", + "Dir": "/work/mod/github.com/pkg/errors@v0.9.1", + "GoMod": "/work/mod/cache/download/github.com/pkg/errors/@v/v0.9.1.mod", + "Sum": "h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=", + "GoModSum": "h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=" +} +{ + "Path": "github.com/planetscale/vtprotobuf", + "Version": "v0.6.1-0.20240319094008-0393e58bdf10", + "Time": "2024-03-19T09:40:08Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/planetscale/vtprotobuf/@v/v0.6.1-0.20240319094008-0393e58bdf10.mod", + "GoVersion": "1.20" +} +{ + "Path": "github.com/pmezard/go-difflib", + "Version": "v1.0.1-0.20181226105442-5d4384ee4fb2", + "Time": "2018-12-26T10:54:42Z", + "Indirect": true, + "Dir": "/work/mod/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2", + "GoMod": "/work/mod/cache/download/github.com/pmezard/go-difflib/@v/v1.0.1-0.20181226105442-5d4384ee4fb2.mod", + "Sum": "h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=", + "GoModSum": "h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=" +} +{ + "Path": "github.com/posener/complete", + "Version": "v1.1.1", + "Time": "2018-03-09T06:24:32Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/posener/complete/@v/v1.1.1.mod" +} +{ + "Path": "github.com/prometheus/client_golang", + "Version": "v1.23.2", + "Time": "2025-09-05T14:03:59Z", + "Dir": "/work/mod/github.com/prometheus/client_golang@v1.23.2", + "GoMod": "/work/mod/cache/download/github.com/prometheus/client_golang/@v/v1.23.2.mod", + "GoVersion": "1.23.0", + "Sum": "h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=", + "GoModSum": "h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=" +} +{ + "Path": "github.com/prometheus/client_model", + "Version": "v0.6.2", + "Time": "2025-04-11T05:38:16Z", + "Indirect": true, + "Dir": "/work/mod/github.com/prometheus/client_model@v0.6.2", + "GoMod": "/work/mod/cache/download/github.com/prometheus/client_model/@v/v0.6.2.mod", + "GoVersion": "1.22.0", + "Sum": "h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=", + "GoModSum": "h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=" +} +{ + "Path": "github.com/prometheus/common", + "Version": "v0.66.1", + "Time": "2025-09-05T07:53:47Z", + "Indirect": true, + "Dir": "/work/mod/github.com/prometheus/common@v0.66.1", + "GoMod": "/work/mod/cache/download/github.com/prometheus/common/@v/v0.66.1.mod", + "GoVersion": "1.23.0", + "Sum": "h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=", + "GoModSum": "h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=" +} +{ + "Path": "github.com/prometheus/procfs", + "Version": "v0.16.1", + "Time": "2025-04-19T15:43:08Z", + "Indirect": true, + "Dir": "/work/mod/github.com/prometheus/procfs@v0.16.1", + "GoMod": "/work/mod/cache/download/github.com/prometheus/procfs/@v/v0.16.1.mod", + "GoVersion": "1.23.0", + "Sum": "h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=", + "GoModSum": "h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=" +} +{ + "Path": "github.com/rogpeppe/fastuuid", + "Version": "v1.2.0", + "Time": "2019-07-08T15:05:45Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/rogpeppe/fastuuid/@v/v1.2.0.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/rogpeppe/go-internal", + "Version": "v1.14.1", + "Time": "2025-02-25T12:37:03Z", + "Indirect": true, + "Dir": "/work/mod/github.com/rogpeppe/go-internal@v1.14.1", + "GoMod": "/work/mod/cache/download/github.com/rogpeppe/go-internal/@v/v1.14.1.mod", + "GoVersion": "1.23", + "Sum": "h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=", + "GoModSum": "h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=" +} +{ + "Path": "github.com/russellhaering/goxmldsig", + "Version": "v1.6.0", + "Time": "2026-03-18T05:07:36Z", + "Dir": "/work/mod/github.com/russellhaering/goxmldsig@v1.6.0", + "GoMod": "/work/mod/cache/download/github.com/russellhaering/goxmldsig/@v/v1.6.0.mod", + "GoVersion": "1.23.0", + "Sum": "h1:8fdWXEPh2k/NZNQBPFNoVfS3JmzS4ZprY/sAOpKQLks=", + "GoModSum": "h1:TrnaquDcYxWXfJrOjeMBTX4mLBeYAqaHEyUeWPxZlBM=" +} +{ + "Path": "github.com/russross/blackfriday/v2", + "Version": "v2.1.0", + "Time": "2020-10-27T03:47:54Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/russross/blackfriday/v2/@v/v2.1.0.mod", + "GoModSum": "h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=" +} +{ + "Path": "github.com/ryanuber/columnize", + "Version": "v2.1.2+incompatible", + "Time": "2020-08-19T15:58:40Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/ryanuber/columnize/@v/v2.1.2+incompatible.mod" +} +{ + "Path": "github.com/ryanuber/go-glob", + "Version": "v1.0.0", + "Time": "2019-01-24T19:22:32Z", + "Indirect": true, + "Dir": "/work/mod/github.com/ryanuber/go-glob@v1.0.0", + "GoMod": "/work/mod/cache/download/github.com/ryanuber/go-glob/@v/v1.0.0.mod", + "Sum": "h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=", + "GoModSum": "h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=" +} +{ + "Path": "github.com/sergi/go-diff", + "Version": "v1.3.1", + "Time": "2023-01-13T08:54:48Z", + "Indirect": true, + "Dir": "/work/mod/github.com/sergi/go-diff@v1.3.1", + "GoMod": "/work/mod/cache/download/github.com/sergi/go-diff/@v/v1.3.1.mod", + "GoVersion": "1.12", + "Sum": "h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=", + "GoModSum": "h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=" +} +{ + "Path": "github.com/shopspring/decimal", + "Version": "v1.4.0", + "Time": "2024-04-12T14:15:38Z", + "Indirect": true, + "Dir": "/work/mod/github.com/shopspring/decimal@v1.4.0", + "GoMod": "/work/mod/cache/download/github.com/shopspring/decimal/@v/v1.4.0.mod", + "GoVersion": "1.10", + "Sum": "h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=", + "GoModSum": "h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=" +} +{ + "Path": "github.com/spf13/cast", + "Version": "v1.7.0", + "Time": "2024-08-06T19:08:19Z", + "Indirect": true, + "Dir": "/work/mod/github.com/spf13/cast@v1.7.0", + "GoMod": "/work/mod/cache/download/github.com/spf13/cast/@v/v1.7.0.mod", + "GoVersion": "1.19", + "Sum": "h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=", + "GoModSum": "h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=" +} +{ + "Path": "github.com/spf13/cobra", + "Version": "v1.10.2", + "Time": "2025-12-03T23:51:15Z", + "Dir": "/work/mod/github.com/spf13/cobra@v1.10.2", + "GoMod": "/work/mod/cache/download/github.com/spf13/cobra/@v/v1.10.2.mod", + "GoVersion": "1.15", + "Sum": "h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=", + "GoModSum": "h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=" +} +{ + "Path": "github.com/spf13/pflag", + "Version": "v1.0.9", + "Time": "2025-09-01T07:27:15Z", + "Indirect": true, + "Dir": "/work/mod/github.com/spf13/pflag@v1.0.9", + "GoMod": "/work/mod/cache/download/github.com/spf13/pflag/@v/v1.0.9.mod", + "GoVersion": "1.12", + "Sum": "h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=", + "GoModSum": "h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=" +} +{ + "Path": "github.com/spiffe/go-spiffe/v2", + "Version": "v2.7.0", + "Time": "2026-06-03T20:07:47Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/spiffe/go-spiffe/v2/@v/v2.7.0.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "github.com/stretchr/objx", + "Version": "v0.5.2", + "Time": "2024-02-29T09:57:51Z", + "Indirect": true, + "Dir": "/work/mod/github.com/stretchr/objx@v0.5.2", + "GoMod": "/work/mod/cache/download/github.com/stretchr/objx/@v/v0.5.2.mod", + "GoVersion": "1.20", + "Sum": "h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=", + "GoModSum": "h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=" +} +{ + "Path": "github.com/stretchr/testify", + "Version": "v1.11.1", + "Time": "2025-08-27T10:46:31Z", + "Dir": "/work/mod/github.com/stretchr/testify@v1.11.1", + "GoMod": "/work/mod/cache/download/github.com/stretchr/testify/@v/v1.11.1.mod", + "GoVersion": "1.17", + "Sum": "h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=", + "GoModSum": "h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=" +} +{ + "Path": "github.com/vmihailenco/msgpack/v5", + "Version": "v5.3.5", + "Time": "2021-10-22T10:21:31Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/vmihailenco/msgpack/v5/@v/v5.3.5.mod", + "GoVersion": "1.11" +} +{ + "Path": "github.com/vmihailenco/tagparser/v2", + "Version": "v2.0.0", + "Time": "2021-02-03T10:04:46Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/vmihailenco/tagparser/v2/@v/v2.0.0.mod", + "GoVersion": "1.15" +} +{ + "Path": "github.com/xhit/go-str2duration/v2", + "Version": "v2.1.0", + "Time": "2022-12-07T00:32:32Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/xhit/go-str2duration/v2/@v/v2.1.0.mod", + "GoVersion": "1.13" +} +{ + "Path": "github.com/yuin/goldmark", + "Version": "v1.4.13", + "Time": "2022-07-09T07:22:17Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/yuin/goldmark/@v/v1.4.13.mod", + "GoVersion": "1.18" +} +{ + "Path": "github.com/zclconf/go-cty", + "Version": "v1.14.4", + "Time": "2024-03-20T23:15:14Z", + "Indirect": true, + "Dir": "/work/mod/github.com/zclconf/go-cty@v1.14.4", + "GoMod": "/work/mod/cache/download/github.com/zclconf/go-cty/@v/v1.14.4.mod", + "GoVersion": "1.18", + "Sum": "h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=", + "GoModSum": "h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=" +} +{ + "Path": "github.com/zclconf/go-cty-debug", + "Version": "v0.0.0-20191215020915-b22d67c1ba0b", + "Time": "2019-12-15T02:09:15Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/github.com/zclconf/go-cty-debug/@v/v0.0.0-20191215020915-b22d67c1ba0b.mod", + "GoVersion": "1.12" +} +{ + "Path": "github.com/zclconf/go-cty-yaml", + "Version": "v1.1.0", + "Time": "2024-10-02T16:59:11Z", + "Indirect": true, + "Dir": "/work/mod/github.com/zclconf/go-cty-yaml@v1.1.0", + "GoMod": "/work/mod/cache/download/github.com/zclconf/go-cty-yaml/@v/v1.1.0.mod", + "GoVersion": "1.17", + "Sum": "h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0=", + "GoModSum": "h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs=" +} +{ + "Path": "go.etcd.io/etcd/api/v3", + "Version": "v3.6.8", + "Time": "2026-02-13T18:39:11Z", + "Indirect": true, + "Dir": "/work/mod/go.etcd.io/etcd/api/v3@v3.6.8", + "GoMod": "/work/mod/cache/download/go.etcd.io/etcd/api/v3/@v/v3.6.8.mod", + "GoVersion": "1.24.0", + "Sum": "h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM=", + "GoModSum": "h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q=" +} +{ + "Path": "go.etcd.io/etcd/client/pkg/v3", + "Version": "v3.6.8", + "Time": "2026-02-13T18:39:11Z", + "Dir": "/work/mod/go.etcd.io/etcd/client/pkg/v3@v3.6.8", + "GoMod": "/work/mod/cache/download/go.etcd.io/etcd/client/pkg/v3/@v/v3.6.8.mod", + "GoVersion": "1.24.0", + "Sum": "h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50=", + "GoModSum": "h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw=" +} +{ + "Path": "go.etcd.io/etcd/client/v3", + "Version": "v3.6.8", + "Time": "2026-02-13T18:39:11Z", + "Dir": "/work/mod/go.etcd.io/etcd/client/v3@v3.6.8", + "GoMod": "/work/mod/cache/download/go.etcd.io/etcd/client/v3/@v/v3.6.8.mod", + "GoVersion": "1.24.0", + "Sum": "h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY=", + "GoModSum": "h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8=" +} +{ + "Path": "go.opencensus.io", + "Version": "v0.24.0", + "Time": "2022-11-03T20:13:50Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/go.opencensus.io/@v/v0.24.0.mod", + "GoVersion": "1.13" +} +{ + "Path": "go.opentelemetry.io/auto/sdk", + "Version": "v1.2.1", + "Time": "2025-09-15T16:53:44Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/auto/sdk@v1.2.1", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/auto/sdk/@v/v1.2.1.mod", + "GoVersion": "1.24.0", + "Sum": "h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=", + "GoModSum": "h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=" +} +{ + "Path": "go.opentelemetry.io/contrib/detectors/gcp", + "Version": "v1.44.0", + "Time": "2026-05-28T05:28:14Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/contrib/detectors/gcp/@v/v1.44.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc", + "Version": "v0.61.0", + "Time": "2025-05-22T14:29:43Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.61.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/@v/v0.61.0.mod", + "GoVersion": "1.23.0", + "Sum": "h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=", + "GoModSum": "h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=" +} +{ + "Path": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", + "Version": "v0.61.0", + "Time": "2025-05-22T14:29:43Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.61.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/@v/v0.61.0.mod", + "GoVersion": "1.23.0", + "Sum": "h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=", + "GoModSum": "h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=" +} +{ + "Path": "go.opentelemetry.io/otel", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=", + "GoModSum": "h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=" +} +{ + "Path": "go.opentelemetry.io/otel/metric", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/metric@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/metric/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=", + "GoModSum": "h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=" +} +{ + "Path": "go.opentelemetry.io/otel/sdk", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/sdk@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/sdk/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=", + "GoModSum": "h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=" +} +{ + "Path": "go.opentelemetry.io/otel/sdk/metric", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/sdk/metric@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/sdk/metric/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=", + "GoModSum": "h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=" +} +{ + "Path": "go.opentelemetry.io/otel/trace", + "Version": "v1.44.0", + "Time": "2026-05-27T16:42:37Z", + "Indirect": true, + "Dir": "/work/mod/go.opentelemetry.io/otel/trace@v1.44.0", + "GoMod": "/work/mod/cache/download/go.opentelemetry.io/otel/trace/@v/v1.44.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=", + "GoModSum": "h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=" +} +{ + "Path": "go.uber.org/goleak", + "Version": "v1.3.0", + "Time": "2023-10-24T16:28:03Z", + "Indirect": true, + "Dir": "/work/mod/go.uber.org/goleak@v1.3.0", + "GoMod": "/work/mod/cache/download/go.uber.org/goleak/@v/v1.3.0.mod", + "GoVersion": "1.20", + "Sum": "h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=", + "GoModSum": "h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=" +} +{ + "Path": "go.uber.org/multierr", + "Version": "v1.11.0", + "Time": "2023-03-29T23:00:37Z", + "Indirect": true, + "Dir": "/work/mod/go.uber.org/multierr@v1.11.0", + "GoMod": "/work/mod/cache/download/go.uber.org/multierr/@v/v1.11.0.mod", + "GoVersion": "1.19", + "Sum": "h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=", + "GoModSum": "h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=" +} +{ + "Path": "go.uber.org/zap", + "Version": "v1.27.0", + "Time": "2024-02-20T20:55:06Z", + "Indirect": true, + "Dir": "/work/mod/go.uber.org/zap@v1.27.0", + "GoMod": "/work/mod/cache/download/go.uber.org/zap/@v/v1.27.0.mod", + "GoVersion": "1.19", + "Sum": "h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=", + "GoModSum": "h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=" +} +{ + "Path": "go.yaml.in/yaml/v2", + "Version": "v2.4.2", + "Time": "2025-06-02T16:37:17Z", + "Indirect": true, + "Dir": "/work/mod/go.yaml.in/yaml/v2@v2.4.2", + "GoMod": "/work/mod/cache/download/go.yaml.in/yaml/v2/@v/v2.4.2.mod", + "GoVersion": "1.15", + "Sum": "h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=", + "GoModSum": "h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=" +} +{ + "Path": "go.yaml.in/yaml/v3", + "Version": "v3.0.4", + "Time": "2025-06-29T14:09:51Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/go.yaml.in/yaml/v3/@v/v3.0.4.mod", + "GoVersion": "1.16", + "GoModSum": "h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=" +} +{ + "Path": "golang.org/x/crypto", + "Version": "v0.56.0", + "Time": "2026-09-02T18:02:47Z", + "Dir": "/work/mod/golang.org/x/crypto@v0.56.0", + "GoMod": "/work/mod/cache/download/golang.org/x/crypto/@v/v0.56.0.mod", + "GoVersion": "1.26.0", + "Sum": "h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y=", + "GoModSum": "h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I=" +} +{ + "Path": "golang.org/x/exp", + "Version": "v0.0.0-20221004215720-b9f4876ce741", + "Time": "2022-10-04T21:57:20Z", + "Dir": "/work/mod/golang.org/x/exp@v0.0.0-20221004215720-b9f4876ce741", + "GoMod": "/work/mod/cache/download/golang.org/x/exp/@v/v0.0.0-20221004215720-b9f4876ce741.mod", + "GoVersion": "1.18", + "Sum": "h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY=", + "GoModSum": "h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=" +} +{ + "Path": "golang.org/x/mod", + "Version": "v0.40.0", + "Time": "2026-08-13T19:09:22Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/mod@v0.40.0", + "GoMod": "/work/mod/cache/download/golang.org/x/mod/@v/v0.40.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=", + "GoModSum": "h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=" +} +{ + "Path": "golang.org/x/net", + "Version": "v0.58.0", + "Time": "2026-08-12T17:41:32Z", + "Dir": "/work/mod/golang.org/x/net@v0.58.0", + "GoMod": "/work/mod/cache/download/golang.org/x/net/@v/v0.58.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=", + "GoModSum": "h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=" +} +{ + "Path": "golang.org/x/oauth2", + "Version": "v0.36.0", + "Time": "2026-02-11T19:14:10Z", + "Dir": "/work/mod/golang.org/x/oauth2@v0.36.0", + "GoMod": "/work/mod/cache/download/golang.org/x/oauth2/@v/v0.36.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=", + "GoModSum": "h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=" +} +{ + "Path": "golang.org/x/sync", + "Version": "v0.22.0", + "Time": "2026-07-01T17:29:34Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/sync@v0.22.0", + "GoMod": "/work/mod/cache/download/golang.org/x/sync/@v/v0.22.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=", + "GoModSum": "h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=" +} +{ + "Path": "golang.org/x/sys", + "Version": "v0.47.0", + "Time": "2026-06-30T17:07:31Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/sys@v0.47.0", + "GoMod": "/work/mod/cache/download/golang.org/x/sys/@v/v0.47.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=", + "GoModSum": "h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=" +} +{ + "Path": "golang.org/x/telemetry", + "Version": "v0.0.0-20260811182544-a038080d80e5", + "Time": "2026-08-11T18:25:44Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/telemetry/@v/v0.0.0-20260811182544-a038080d80e5.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/term", + "Version": "v0.45.0", + "Time": "2026-07-08T15:40:56Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/term/@v/v0.45.0.mod", + "GoVersion": "1.25.0" +} +{ + "Path": "golang.org/x/text", + "Version": "v0.41.0", + "Time": "2026-08-11T15:22:47Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/text@v0.41.0", + "GoMod": "/work/mod/cache/download/golang.org/x/text/@v/v0.41.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=", + "GoModSum": "h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=" +} +{ + "Path": "golang.org/x/time", + "Version": "v0.14.0", + "Time": "2025-09-16T23:29:52Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/time@v0.14.0", + "GoMod": "/work/mod/cache/download/golang.org/x/time/@v/v0.14.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=", + "GoModSum": "h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=" +} +{ + "Path": "golang.org/x/tools", + "Version": "v0.49.0", + "Time": "2026-08-13T14:53:26Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/tools@v0.49.0", + "GoMod": "/work/mod/cache/download/golang.org/x/tools/@v/v0.49.0.mod", + "GoVersion": "1.25.0", + "Sum": "h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=", + "GoModSum": "h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=" +} +{ + "Path": "golang.org/x/tools/go/expect", + "Version": "v0.1.0-deprecated", + "Time": "2025-06-12T15:17:39Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/tools/go/expect@v0.1.0-deprecated", + "GoMod": "/work/mod/cache/download/golang.org/x/tools/go/expect/@v/v0.1.0-deprecated.mod", + "GoVersion": "1.23.0", + "Sum": "h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY=", + "GoModSum": "h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=" +} +{ + "Path": "golang.org/x/tools/go/packages/packagestest", + "Version": "v0.1.1-deprecated", + "Time": "2025-06-13T18:44:18Z", + "Indirect": true, + "Dir": "/work/mod/golang.org/x/tools/go/packages/packagestest@v0.1.1-deprecated", + "GoMod": "/work/mod/cache/download/golang.org/x/tools/go/packages/packagestest/@v/v0.1.1-deprecated.mod", + "GoVersion": "1.23.0", + "Sum": "h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=", + "GoModSum": "h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=" +} +{ + "Path": "golang.org/x/xerrors", + "Version": "v0.0.0-20200804184101-5ec99f83aff1", + "Time": "2020-08-04T18:41:01Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/golang.org/x/xerrors/@v/v0.0.0-20200804184101-5ec99f83aff1.mod", + "GoVersion": "1.11", + "GoModSum": "h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=" +} +{ + "Path": "gonum.org/v1/gonum", + "Version": "v0.17.0", + "Time": "2025-12-29T19:16:44Z", + "Indirect": true, + "Dir": "/work/mod/gonum.org/v1/gonum@v0.17.0", + "GoMod": "/work/mod/cache/download/gonum.org/v1/gonum/@v/v0.17.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=", + "GoModSum": "h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=" +} +{ + "Path": "google.golang.org/api", + "Version": "v0.267.0", + "Time": "2026-02-17T16:52:11Z", + "Dir": "/work/mod/google.golang.org/api@v0.267.0", + "GoMod": "/work/mod/cache/download/google.golang.org/api/@v/v0.267.0.mod", + "GoVersion": "1.24.0", + "Sum": "h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE=", + "GoModSum": "h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0=" +} +{ + "Path": "google.golang.org/appengine", + "Version": "v1.6.8", + "Time": "2023-08-30T01:12:52Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/google.golang.org/appengine/@v/v1.6.8.mod", + "GoVersion": "1.11" +} +{ + "Path": "google.golang.org/genproto", + "Version": "v0.0.0-20260128011058-8636f8732409", + "Time": "2026-01-28T01:10:58Z", + "Indirect": true, + "Dir": "/work/mod/google.golang.org/genproto@v0.0.0-20260128011058-8636f8732409", + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/@v/v0.0.0-20260128011058-8636f8732409.mod", + "GoVersion": "1.24.0", + "Sum": "h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=", + "GoModSum": "h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=" +} +{ + "Path": "google.golang.org/genproto/googleapis/api", + "Version": "v0.0.0-20260526163538-3dc84a4a5aaa", + "Time": "2026-05-26T16:35:38Z", + "Indirect": true, + "Dir": "/work/mod/google.golang.org/genproto/googleapis/api@v0.0.0-20260526163538-3dc84a4a5aaa", + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/googleapis/api/@v/v0.0.0-20260526163538-3dc84a4a5aaa.mod", + "GoVersion": "1.25.0", + "Sum": "h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=", + "GoModSum": "h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=" +} +{ + "Path": "google.golang.org/genproto/googleapis/bytestream", + "Version": "v0.0.0-20260203192932-546029d2fa20", + "Time": "2026-02-03T19:29:32Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/googleapis/bytestream/@v/v0.0.0-20260203192932-546029d2fa20.mod", + "GoVersion": "1.24.0" +} +{ + "Path": "google.golang.org/genproto/googleapis/rpc", + "Version": "v0.0.0-20260526163538-3dc84a4a5aaa", + "Time": "2026-05-26T16:35:38Z", + "Indirect": true, + "Dir": "/work/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20260526163538-3dc84a4a5aaa", + "GoMod": "/work/mod/cache/download/google.golang.org/genproto/googleapis/rpc/@v/v0.0.0-20260526163538-3dc84a4a5aaa.mod", + "GoVersion": "1.25.0", + "Sum": "h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=", + "GoModSum": "h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=" +} +{ + "Path": "google.golang.org/grpc", + "Version": "v1.83.2", + "Time": "2026-08-25T15:47:16Z", + "Dir": "/work/mod/google.golang.org/grpc@v1.83.2", + "GoMod": "/work/mod/cache/download/google.golang.org/grpc/@v/v1.83.2.mod", + "GoVersion": "1.25.0", + "Sum": "h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=", + "GoModSum": "h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=" +} +{ + "Path": "google.golang.org/protobuf", + "Version": "v1.36.11", + "Time": "2025-12-12T08:48:31Z", + "Dir": "/work/mod/google.golang.org/protobuf@v1.36.11", + "GoMod": "/work/mod/cache/download/google.golang.org/protobuf/@v/v1.36.11.mod", + "GoVersion": "1.23", + "Sum": "h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=", + "GoModSum": "h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=" +} +{ + "Path": "gopkg.in/check.v1", + "Version": "v1.0.0-20201130134442-10cb98267c6c", + "Time": "2020-11-30T13:44:42Z", + "Indirect": true, + "Dir": "/work/mod/gopkg.in/check.v1@v1.0.0-20201130134442-10cb98267c6c", + "GoMod": "/work/mod/cache/download/gopkg.in/check.v1/@v/v1.0.0-20201130134442-10cb98267c6c.mod", + "GoVersion": "1.11", + "Sum": "h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=", + "GoModSum": "h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=" +} +{ + "Path": "gopkg.in/yaml.v2", + "Version": "v2.4.0", + "Time": "2020-11-17T15:46:20Z", + "Indirect": true, + "Dir": "/work/mod/gopkg.in/yaml.v2@v2.4.0", + "GoMod": "/work/mod/cache/download/gopkg.in/yaml.v2/@v/v2.4.0.mod", + "GoVersion": "1.15", + "Sum": "h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=", + "GoModSum": "h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=" +} +{ + "Path": "gopkg.in/yaml.v3", + "Version": "v3.0.1", + "Time": "2022-05-27T08:35:30Z", + "Indirect": true, + "Dir": "/work/mod/gopkg.in/yaml.v3@v3.0.1", + "GoMod": "/work/mod/cache/download/gopkg.in/yaml.v3/@v/v3.0.1.mod", + "Sum": "h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=", + "GoModSum": "h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=" +} +{ + "Path": "sigs.k8s.io/yaml", + "Version": "v1.4.0", + "Time": "2023-10-24T17:13:34Z", + "Indirect": true, + "GoMod": "/work/mod/cache/download/sigs.k8s.io/yaml/@v/v1.4.0.mod", + "GoVersion": "1.12" +} diff --git a/bridge/idp/locks/generated/requests.txt b/bridge/idp/locks/generated/requests.txt new file mode 100644 index 00000000..923f3afd --- /dev/null +++ b/bridge/idp/locks/generated/requests.txt @@ -0,0 +1,11 @@ +github.com/Azure/go-ntlmssp@v0.1.1 +github.com/go-jose/go-jose/v4@v4.1.4 +github.com/russellhaering/goxmldsig@v1.6.0 +go.opentelemetry.io/otel@v1.44.0 +go.opentelemetry.io/otel/metric@v1.44.0 +go.opentelemetry.io/otel/trace@v1.44.0 +golang.org/x/crypto@v0.56.0 +golang.org/x/mod@v0.40.0 +golang.org/x/net@v0.58.0 +golang.org/x/text@v0.41.0 +google.golang.org/grpc@v1.83.2 diff --git a/bridge/idp/locks/generated/toolchain.txt b/bridge/idp/locks/generated/toolchain.txt new file mode 100644 index 00000000..b0b893ce --- /dev/null +++ b/bridge/idp/locks/generated/toolchain.txt @@ -0,0 +1 @@ +go version go1.26.8 linux/amd64 diff --git a/bridge/idp/locks/generated/upstream/api/v2/go.mod.snapshot b/bridge/idp/locks/generated/upstream/api/v2/go.mod.snapshot new file mode 100644 index 00000000..6c14b7e4 --- /dev/null +++ b/bridge/idp/locks/generated/upstream/api/v2/go.mod.snapshot @@ -0,0 +1,15 @@ +module github.com/dexidp/dex/api/v2 + +go 1.24.0 + +require ( + google.golang.org/grpc v1.79.1 + google.golang.org/protobuf v1.36.11 +) + +require ( + golang.org/x/net v0.50.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect +) diff --git a/bridge/idp/locks/generated/upstream/api/v2/go.sum.snapshot b/bridge/idp/locks/generated/upstream/api/v2/go.sum.snapshot new file mode 100644 index 00000000..727897fb --- /dev/null +++ b/bridge/idp/locks/generated/upstream/api/v2/go.sum.snapshot @@ -0,0 +1,38 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/bridge/idp/locks/generated/upstream/go.mod.snapshot b/bridge/idp/locks/generated/upstream/go.mod.snapshot new file mode 100644 index 00000000..ee55dd4e --- /dev/null +++ b/bridge/idp/locks/generated/upstream/go.mod.snapshot @@ -0,0 +1,129 @@ +module github.com/dexidp/dex + +go 1.25.0 + +require ( + cloud.google.com/go/compute/metadata v0.9.0 + entgo.io/ent v0.14.5 + github.com/AppsFlyer/go-sundheit v0.6.0 + github.com/Masterminds/semver v1.5.0 + github.com/Masterminds/sprig/v3 v3.3.0 + github.com/beevik/etree v1.6.0 + github.com/coreos/go-oidc/v3 v3.17.0 + github.com/dexidp/dex/api/v2 v2.4.0 + github.com/fsnotify/fsnotify v1.9.0 + github.com/ghodss/yaml v1.0.0 + github.com/go-jose/go-jose/v4 v4.1.3 + github.com/go-ldap/ldap/v3 v3.4.12 + github.com/go-sql-driver/mysql v1.9.3 + github.com/google/uuid v1.6.0 + github.com/gorilla/handlers v1.5.2 + github.com/gorilla/mux v1.8.1 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/kylelemons/godebug v1.1.0 + github.com/lib/pq v1.11.2 + github.com/mattermost/xml-roundtrip-validator v0.1.0 + github.com/mattn/go-sqlite3 v1.14.34 + github.com/oklog/run v1.2.0 + github.com/openbao/openbao/api/v2 v2.5.1 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.23.2 + github.com/russellhaering/goxmldsig v1.5.0 + github.com/spf13/cobra v1.10.2 + github.com/stretchr/testify v1.11.1 + go.etcd.io/etcd/client/pkg/v3 v3.6.8 + go.etcd.io/etcd/client/v3 v3.6.8 + golang.org/x/crypto v0.48.0 + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 + golang.org/x/net v0.50.0 + golang.org/x/oauth2 v0.35.0 + google.golang.org/api v0.267.0 + google.golang.org/grpc v1.79.1 + google.golang.org/protobuf v1.36.11 +) + +require ( + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect + cloud.google.com/go/auth v0.18.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + dario.cat/mergo v1.0.1 // indirect + filippo.io/edwards25519 v1.1.1 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bmatcuk/doublestar v1.3.4 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/inflect v0.19.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect + github.com/googleapis/gax-go/v2 v2.17.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty-yaml v1.1.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.8 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.41.0 // indirect + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/dexidp/dex/api/v2 => ./api/v2 + +tool entgo.io/ent/cmd/ent diff --git a/bridge/idp/locks/generated/upstream/go.sum.snapshot b/bridge/idp/locks/generated/upstream/go.sum.snapshot new file mode 100644 index 00000000..ac41652e --- /dev/null +++ b/bridge/idp/locks/generated/upstream/go.sum.snapshot @@ -0,0 +1,339 @@ +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc= +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w= +cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= +cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4= +entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AppsFlyer/go-sundheit v0.6.0 h1:d2hBvCjBSb2lUsEWGfPigr4MCOt04sxB+Rppl0yUMSk= +github.com/AppsFlyer/go-sundheit v0.6.0/go.mod h1:LDdBHD6tQBtmHsdW+i1GwdTt6Wqc0qazf5ZEJVTbTME= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= +github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= +github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4= +github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= +github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= +github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= +github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= +github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/openbao/openbao/api/v2 v2.5.1 h1:Br79D6L20SbAa5P7xqENxmvv8LyI4HoKosPy7klhn4o= +github.com/openbao/openbao/api/v2 v2.5.1/go.mod h1:Dh5un77tqGgMbmlVEqjqN+8/dMyUohnkaQVg/wXW0Ig= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russellhaering/goxmldsig v1.5.0 h1:AU2UkkYIUOTyZRbe08XMThaOCelArgvNfYapcmSjBNw= +github.com/russellhaering/goxmldsig v1.5.0/go.mod h1:x98CjQNFJcWfMxeOrMnMKg70lvDP6tE0nTaeUnjXDmk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= +github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= +go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= +go.etcd.io/etcd/api/v3 v3.6.8/go.mod h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q= +go.etcd.io/etcd/client/pkg/v3 v3.6.8 h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50= +go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= +go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= +go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= +golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE= +google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/bridge/idp/locks/inputs.lock b/bridge/idp/locks/inputs.lock new file mode 100644 index 00000000..8f0a8db2 --- /dev/null +++ b/bridge/idp/locks/inputs.lock @@ -0,0 +1,6 @@ +# Public, immutable shell assignments; never source an unreviewed generated file. +DEX_COMMIT=11d2eeb52b42e1980e14cb91e69dd9e3faab2076 +DEX_ARCHIVE_SHA256=18bf92e8ccbf53e86814c2beb39b7d59f28fb07c84639e9f47a9bb5ea764e0b9 +DEX_VERSION=v2.45.1-kars.1 +GO_VERSION=go1.26.8 +SOURCE_DATE_EPOCH=0 diff --git a/bridge/idp/locks/requests.txt b/bridge/idp/locks/requests.txt new file mode 100644 index 00000000..923f3afd --- /dev/null +++ b/bridge/idp/locks/requests.txt @@ -0,0 +1,11 @@ +github.com/Azure/go-ntlmssp@v0.1.1 +github.com/go-jose/go-jose/v4@v4.1.4 +github.com/russellhaering/goxmldsig@v1.6.0 +go.opentelemetry.io/otel@v1.44.0 +go.opentelemetry.io/otel/metric@v1.44.0 +go.opentelemetry.io/otel/trace@v1.44.0 +golang.org/x/crypto@v0.56.0 +golang.org/x/mod@v0.40.0 +golang.org/x/net@v0.58.0 +golang.org/x/text@v0.41.0 +google.golang.org/grpc@v1.83.2 diff --git a/bridge/idp/patches/0001-literal-oauth-error-descriptions.patch b/bridge/idp/patches/0001-literal-oauth-error-descriptions.patch new file mode 100644 index 00000000..5e2c56aa --- /dev/null +++ b/bridge/idp/patches/0001-literal-oauth-error-descriptions.patch @@ -0,0 +1,26 @@ +Subject: [Kars compatibility] Preserve literal preformatted OAuth error descriptions +Upstream: dexidp/dex v2.45.1, 11d2eeb52b42e1980e14cb91e69dd9e3faab2076 +Reason: Go 1.26 vet rejects two nonconstant format arguments. A constant %s +also prevents percent text in an unsupported PKCE method from being formatted +twice. No error type, redirect destination, or validation decision changes. + +--- a/server/oauth2.go ++++ b/server/oauth2.go +@@ -474,7 +474,7 @@ + + if codeChallengeMethod != codeChallengeMethodS256 && codeChallengeMethod != codeChallengeMethodPlain { + description := fmt.Sprintf("Unsupported PKCE challenge method (%q).", codeChallengeMethod) +- return nil, newRedirectedErr(errInvalidRequest, description) ++ return nil, newRedirectedErr(errInvalidRequest, "%s", description) + } + + var ( +@@ -558,7 +558,7 @@ + if rt.token { + if redirectURI == redirectURIOOB { + err := fmt.Sprintf("Cannot use response type 'token' with redirect_uri '%s'.", redirectURIOOB) +- return nil, newRedirectedErr(errInvalidRequest, err) ++ return nil, newRedirectedErr(errInvalidRequest, "%s", err) + } + } + diff --git a/bridge/idp/patches/0002-saml-fixture-validation-clock.patch b/bridge/idp/patches/0002-saml-fixture-validation-clock.patch new file mode 100644 index 00000000..9c6073c8 --- /dev/null +++ b/bridge/idp/patches/0002-saml-fixture-validation-clock.patch @@ -0,0 +1,39 @@ +Subject: [Kars test-only compatibility] Validate the historical OAM signature at fixture time +Upstream: dexidp/dex v2.45.1, 11d2eeb52b42e1980e14cb91e69dd9e3faab2076 +Fixture: connector/saml/testdata/oam-resp.xml IssueInstant 2016-12-12T16:54:35Z +Certificate: oam-ca.pem valid 2016-06-30T04:54:16Z through 2026-06-28T04:54:16Z +Reason: This XML namespace/signature test is not a wall-clock expiry test. +Only this historical fixture selects goxmldsig's supported fake test clock. +All other runVerify callers retain the real clock. Production validation, +the signed XML, and the certificate remain unchanged. + +--- a/connector/saml/saml_test.go ++++ b/connector/saml/saml_test.go +@@ -544,11 +544,16 @@ + func runVerify(t *testing.T, ca string, resp string, shouldSucceed bool) { ++ runVerifyWithClock(t, ca, resp, shouldSucceed, nil) ++} ++ ++func runVerifyWithClock(t *testing.T, ca string, resp string, shouldSucceed bool, clock *dsig.Clock) { + cert, err := loadCert(ca) + if err != nil { + t.Fatal(err) + } + s := certStore{[]*x509.Certificate{cert}} + + validator := dsig.NewDefaultValidationContext(s) ++ validator.Clock = clock + + data, err := os.ReadFile(resp) + if err != nil { +@@ -573,7 +578,9 @@ + func TestVerifyUnsignedMessageAndSignedAssertionWithRootXmlNs(t *testing.T) { +- runVerify(t, "testdata/oam-ca.pem", "testdata/oam-resp.xml", true) ++ // Match the signed fixture's IssueInstant, not the wall clock. ++ clock := dsig.NewFakeClockAt(time.Date(2016, time.December, 12, 16, 54, 35, 0, time.UTC)) ++ runVerifyWithClock(t, "testdata/oam-ca.pem", "testdata/oam-resp.xml", true, clock) + } + + func TestVerifySignedMessageAndUnsignedAssertion(t *testing.T) { + runVerify(t, "testdata/idp-cert.pem", "testdata/idp-resp-signed-message.xml", true) + } diff --git a/bridge/idp/patches/SHA256SUMS b/bridge/idp/patches/SHA256SUMS new file mode 100644 index 00000000..32b5d80b --- /dev/null +++ b/bridge/idp/patches/SHA256SUMS @@ -0,0 +1,7 @@ +8755f6149041ae291a8850de1e6b3012ffcbbaf01a4f259705dcab64645b373f 0001-literal-oauth-error-descriptions.patch +31d1e5b8438325374d2ab973c02eeed1539e4452b57d299ed747feac6c50bda6 0002-saml-fixture-validation-clock.patch +f936045965a7d837c1b5b59b6ea66b4e206b04e8e5c84272036e57e985a1b0d3 patched.sha256 +63da3c3b7a5739568f4e8601daaadd2b5e85e3b4776414d6ed0046c7fb876eff saml_compat_test.go +12b20222b552ad8d21cc5b98cf0abb8685c926c380909e851af75e8b76f30fc0 series +e310d58df8845a7fd8e839a5428880358789bff128b561558dfddd61b7a2853d server_compat_test.go +012b8266acefcfe80fbf0683ed69c4b44c00251d49d25f949f3f4c338deb723b upstream.sha256 diff --git a/bridge/idp/patches/patched.sha256 b/bridge/idp/patches/patched.sha256 new file mode 100644 index 00000000..6a1d541a --- /dev/null +++ b/bridge/idp/patches/patched.sha256 @@ -0,0 +1,4 @@ +c8b250efd8e8d41f88fb21968847e4d82f6eb3738f9815de662b6a7854cddeeb ./server/oauth2.go +de88d7c7361b41e306001280ef2b5f6e01827eff572a0404a047194e660bde31 ./connector/saml/saml_test.go +e310d58df8845a7fd8e839a5428880358789bff128b561558dfddd61b7a2853d ./server/kars_compat_test.go +63da3c3b7a5739568f4e8601daaadd2b5e85e3b4776414d6ed0046c7fb876eff ./connector/saml/kars_compat_test.go diff --git a/bridge/idp/patches/saml_compat_test.go b/bridge/idp/patches/saml_compat_test.go new file mode 100644 index 00000000..9fc1da04 --- /dev/null +++ b/bridge/idp/patches/saml_compat_test.go @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package saml + +import ( + "crypto/x509" + "os" + "strings" + "testing" + "time" + + dsig "github.com/russellhaering/goxmldsig" +) + +func TestKarsSAMLFixtureCertificateValidity(t *testing.T) { + cert, err := loadCert("testdata/oam-ca.pem") + if err != nil { + t.Fatal(err) + } + data, err := os.ReadFile("testdata/oam-resp.xml") + if err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + name string + now time.Time + valid bool + }{ + {"at signed fixture time", time.Date(2016, time.December, 12, 16, 54, 35, 0, time.UTC), true}, + {"before certificate validity", cert.NotBefore.Add(-time.Second), false}, + {"after certificate expiry", cert.NotAfter.Add(time.Second), false}, + } { + t.Run(tc.name, func(t *testing.T) { + validator := dsig.NewDefaultValidationContext(certStore{[]*x509.Certificate{cert}}) + if validator.Clock != nil { + t.Fatal("production validation context must default to the real clock") + } + validator.Clock = dsig.NewFakeClockAt(tc.now) + _, rootVerified, err := verifyResponseSig(validator, data) + if tc.valid { + if err != nil || rootVerified { + t.Fatalf("expected verified assertion with unsigned root: rootVerified=%v, error=%v", rootVerified, err) + } + } else if err == nil || !strings.Contains(err.Error(), "Cert is not valid at this time") { + t.Fatalf("certificate validity must remain enforced, got %v", err) + } + }) + } +} diff --git a/bridge/idp/patches/series b/bridge/idp/patches/series new file mode 100644 index 00000000..3f779661 --- /dev/null +++ b/bridge/idp/patches/series @@ -0,0 +1,2 @@ +0001-literal-oauth-error-descriptions.patch +0002-saml-fixture-validation-clock.patch diff --git a/bridge/idp/patches/server_compat_test.go b/bridge/idp/patches/server_compat_test.go new file mode 100644 index 00000000..26f5f42c --- /dev/null +++ b/bridge/idp/patches/server_compat_test.go @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package server + +import ( + "fmt" + "net/http/httptest" + "net/url" + "testing" + + "github.com/dexidp/dex/storage" +) + +func TestKarsAuthorizationErrorDescriptionsLiteral(t *testing.T) { + for _, tc := range []struct { + name, method, redirectURI, responseType, description string + }{ + { + name: "percent verbs in PKCE method", method: "%s%[1]s%%", + redirectURI: "https://example.invalid/callback", responseType: "code", + description: `Unsupported PKCE challenge method ("%s%[1]s%%").`, + }, + { + name: "ordinary unsupported PKCE method", method: "unsupported", + redirectURI: "https://example.invalid/callback", responseType: "code", + description: `Unsupported PKCE challenge method ("unsupported").`, + }, + { + name: "token with out-of-band redirect", method: codeChallengeMethodS256, + redirectURI: redirectURIOOB, responseType: "code token", + description: fmt.Sprintf("Cannot use response type 'token' with redirect_uri '%s'.", redirectURIOOB), + }, + } { + t.Run(tc.name, func(t *testing.T) { + httpServer, server := newTestServerMultipleConnectors(t, func(c *Config) { + c.SupportedResponseTypes = []string{"code", "token"} + c.Storage = storage.WithStaticClients(c.Storage, []storage.Client{{ + ID: "compat-client", RedirectURIs: []string{tc.redirectURI}, + }}) + }) + defer httpServer.Close() + params := url.Values{ + "client_id": {"compat-client"}, "redirect_uri": {tc.redirectURI}, + "response_type": {tc.responseType}, "scope": {"openid"}, + "state": {"literal-state%25"}, "code_challenge_method": {tc.method}, + "code_challenge": {"challenge"}, + } + req := httptest.NewRequest("GET", httpServer.URL+"/auth?"+params.Encode(), nil) + _, err := server.parseAuthorizationRequest(req) + redirected, ok := err.(*redirectedAuthErr) + if !ok { + t.Fatalf("expected redirectedAuthErr, got %T: %v", err, err) + } + if redirected.Type != errInvalidRequest || redirected.RedirectURI != tc.redirectURI || + redirected.State != params.Get("state") || redirected.Description != tc.description { + t.Fatalf("redirected error = %+v; expected unchanged type/state/URI and literal description %q", + redirected, tc.description) + } + }) + } +} diff --git a/bridge/idp/patches/upstream.sha256 b/bridge/idp/patches/upstream.sha256 new file mode 100644 index 00000000..ba5588c8 --- /dev/null +++ b/bridge/idp/patches/upstream.sha256 @@ -0,0 +1,2 @@ +4dbc9a51b9b65b2295aaff258a36eced579c6b9b0b42816eacd179cd15f33cc7 ./server/oauth2.go +88e5ed609e7cf652d7ffb404ad15fab322f88d24627bfac9df453f1656a56395 ./connector/saml/saml_test.go diff --git a/bridge/idp/scripts/apply-source-patches.sh b/bridge/idp/scripts/apply-source-patches.sh new file mode 100644 index 00000000..cf90dc3e --- /dev/null +++ b/bridge/idp/scripts/apply-source-patches.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +packaging="${1:-/packaging}" +patches="$packaging/patches" +(cd "$patches" && sha256sum --check --strict SHA256SUMS) +sha256sum --check --strict --quiet "$packaging/source.upstream.sha256" +sha256sum --check --strict "$patches/upstream.sha256" +while IFS= read -r name; do + git apply --no-index --check --whitespace=error-all "$patches/$name" + git apply --no-index --whitespace=error-all "$patches/$name" +done < "$patches/series" +test ! -e server/kars_compat_test.go +test ! -e connector/saml/kars_compat_test.go +cp "$patches/server_compat_test.go" server/kars_compat_test.go +cp "$patches/saml_compat_test.go" connector/saml/kars_compat_test.go +sha256sum --check --strict "$patches/patched.sha256" + +# Build the EXPECTED inventory from the verified original plus only the +# reviewed replacement/addition hashes, never from whatever patch produced. +awk 'NR == FNR { replacement[$2] = $1; next } + { if ($2 in replacement) { + print replacement[$2] " " $2; delete replacement[$2] + } else { print } } + END { for (name in replacement) print replacement[name] " " name }' \ + "$patches/patched.sha256" "$packaging/source.upstream.sha256" \ + | LC_ALL=C sort -k2 > "$packaging/source.sha256" +sha256sum --check --strict --quiet "$packaging/source.sha256" +sh "$packaging/scripts/source-inventory.sh" > "$packaging/source.actual.sha256" +cmp "$packaging/source.sha256" "$packaging/source.actual.sha256" diff --git a/bridge/idp/scripts/build.sh b/bridge/idp/scripts/build.sh new file mode 100644 index 00000000..74454555 --- /dev/null +++ b/bridge/idp/scripts/build.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +. /packaging/locks/inputs.lock +export SOURCE_DATE_EPOCH +mkdir -p /out/doc /out/etc /out/data +sha256sum --check --strict /packaging/source.sha256 > /dev/null +# No CGO disablement, custom build tags, static libc or copied library closure. +go build -trimpath -buildvcs=false -ldflags="-w -buildid= -X main.version=$DEX_VERSION" \ + -o /out/dex ./cmd/dex +go version -m /out/dex > /out/doc/build-info.txt +readelf --wide --dynamic /out/dex > /out/doc/elf-dynamic.txt +readelf --wide --program-headers /out/dex > /out/doc/elf-program-headers.txt +readelf --wide --version-info /out/dex > /out/doc/elf-versions.txt +grep -q 'CGO_ENABLED=1' /out/doc/build-info.txt +cp LICENSE /out/doc/DEX-LICENSE +if test -f NOTICE; then cp NOTICE /out/doc/DEX-NOTICE; fi +cp /packaging/NOTICE /out/doc/KARS-NOTICE +cp /packaging/LICENSE /out/doc/KARS-LICENSE +cp /packaging/README.md /out/doc/PACKAGING-README.md +cp -R /locks /out/doc/locks +cp -R /packaging/patches /out/doc/source-patches +cp /packaging/source.upstream.sha256 /packaging/source.sha256 /out/doc/ +go list -deps -json=ImportPath,Module ./cmd/dex > /out/doc/runtime-packages.json +go run /packaging/scripts/notices.go /out/doc/runtime-packages.json /out/doc/third-party +sha256sum --check --strict /packaging/source.sha256 > /dev/null +cmp go.mod /locks/go.mod +cmp go.sum /locks/go.sum +cmp api/v2/go.mod /locks/api/v2/go.mod +cmp api/v2/go.sum /locks/api/v2/go.sum diff --git a/bridge/idp/scripts/fetch-source.sh b/bridge/idp/scripts/fetch-source.sh new file mode 100644 index 00000000..c0b90a81 --- /dev/null +++ b/bridge/idp/scripts/fetch-source.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +. /packaging/locks/inputs.lock +test "$(go env GOVERSION)" = "$GO_VERSION" +curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 \ + "https://codeload.github.com/dexidp/dex/tar.gz/$DEX_COMMIT" -o /tmp/dex.tar.gz +printf '%s %s\n' "$DEX_ARCHIVE_SHA256" /tmp/dex.tar.gz | sha256sum --check --strict +tar -xzf /tmp/dex.tar.gz --strip-components=1 -C /src/dex +rm /tmp/dex.tar.gz +sh /packaging/scripts/source-inventory.sh > /packaging/source.upstream.sha256 +mkdir -p /packaging/upstream/api/v2 +for file in go.mod go.sum api/v2/go.mod api/v2/go.sum; do + cp "$file" "/packaging/upstream/$file.snapshot" +done +sh /packaging/scripts/apply-source-patches.sh diff --git a/bridge/idp/scripts/generate-locks.sh b/bridge/idp/scripts/generate-locks.sh new file mode 100644 index 00000000..8162297e --- /dev/null +++ b/bridge/idp/scripts/generate-locks.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +. /packaging/locks/inputs.lock +export GOFLAGS=-mod=mod +mkdir -p /out/api/v2 + +# Update the nested API as well as the application; the local replace is retained. +( + cd api/v2 + go mod edit -go=1.26.0 -toolchain="$GO_VERSION" + go get google.golang.org/grpc@v1.83.2 golang.org/x/crypto@v0.56.0 + go mod tidy + go mod download + go mod verify + go list -m -json all > /out/api-modules.json +) +go mod edit -go=1.26.0 -toolchain="$GO_VERSION" +set -- +while IFS= read -r request; do + test -n "$request" + set -- "$@" "$request" +done < /packaging/locks/requests.txt +go get "$@" +go mod tidy +go mod download +go mod verify +sha256sum --check --strict /packaging/source.sha256 > /dev/null +go list -m -json all > /out/modules.json +go mod graph > /out/graph.txt +go version > /out/toolchain.txt +cp go.mod go.sum /out/ +cp api/v2/go.mod api/v2/go.sum /out/api/v2/ +cp /packaging/locks/inputs.lock /packaging/locks/requests.txt /out/ +cp -R /packaging/upstream /out/upstream +: > /out/dependencies.patch +for file in go.mod go.sum api/v2/go.mod api/v2/go.sum; do + set +e + diff -u --label "upstream/$file" --label "kars/$file" \ + "/packaging/upstream/$file.snapshot" "/out/$file" >> /out/dependencies.patch + status=$? + set -e + test "$status" -le 1 +done +( + cd /out + find . -type f ! -name SHA256SUMS -print0 | LC_ALL=C sort -z \ + | xargs -0 sha256sum > SHA256SUMS +) +# ACR --no-push runs can return this public artifact via their build log. +tar --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 \ + -C /out -cf /tmp/dex-locks.tar . +gzip -n /tmp/dex-locks.tar +printf '\nKARS_DEX_LOCKS_BASE64_BEGIN\n' +base64 -w 0 /tmp/dex-locks.tar.gz +printf '\nKARS_DEX_LOCKS_BASE64_END\n' +sha256sum /tmp/dex-locks.tar.gz diff --git a/bridge/idp/scripts/import-locks.py b/bridge/idp/scripts/import-locks.py new file mode 100644 index 00000000..ef054255 --- /dev/null +++ b/bridge/idp/scripts/import-locks.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Import active Go locks and archival .snapshot baselines from a no-push build log.""" + +import argparse +import base64 +import gzip +import hashlib +import io +from pathlib import Path +import re +import shutil +import sys +import tarfile +import tempfile +import zlib + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "tests")) +from contracts import LOCK_FILES, check_modules, require + +MAX_ARCHIVE_BYTES = 16 * 1024 * 1024 + + +def decode_artifact(log): + blocks = re.findall( + r"(?m)^KARS_DEX_LOCKS_BASE64_BEGIN\r?\n([A-Za-z0-9+/=]+)\r?\nKARS_DEX_LOCKS_BASE64_END\r?$", + log, + ) + require(len(blocks) == 1, "expected exactly one unprefixed lock artifact in the raw ACR log") + require(len(blocks[0]) < 8 * 1024 * 1024, "unexpectedly large lock artifact") + payload = base64.b64decode(blocks[0], validate=True) + digests = re.findall(r"(?m)^([0-9a-f]{64}) /tmp/dex-locks\.tar\.gz\r?$", log) + require(len(digests) == 1 and hashlib.sha256(payload).hexdigest() == digests[0], + "missing or mismatched transport SHA-256") + # Bound the entire tar, including headers and directory entries, before + # tarfile can allocate an unbounded member index for a compressed archive. + with gzip.GzipFile(fileobj=io.BytesIO(payload)) as compressed: + expanded = compressed.read(MAX_ARCHIVE_BYTES + 1) + require(len(expanded) <= MAX_ARCHIVE_BYTES, "expanded artifact exceeds bounded lock size") + result = {} + size = 0 + with tarfile.open(fileobj=io.BytesIO(expanded), mode="r:") as archive: + for member in archive: + path = Path(member.name) + require(not path.is_absolute() and ".." not in path.parts, "unsafe archive path") + if member.isdir(): + continue + name = str(path) + require(member.isfile() and name in LOCK_FILES and name not in result, + f"unexpected or duplicate lock member: {name}") + size += member.size + require(size <= MAX_ARCHIVE_BYTES, "expanded artifact exceeds bounded lock size") + with archive.extractfile(member) as stream: + result[name] = stream.read() + require(set(result) == LOCK_FILES, "incomplete Go resolver artifact") + return result + + +def import_artifact(log, target): + target = Path(target).resolve() + default = ROOT / "locks/generated" + checkout = next((path for path in (ROOT, *ROOT.parents) if (path / ".git").exists()), ROOT) + require(target == default or not target.is_relative_to(checkout), + "alternate lock-review output must be outside the source checkout") + require(not target.exists(), "lock output already exists; review it rather than overwriting") + require(target.parent.is_dir(), "lock-review output parent directory must already exist") + files = decode_artifact(Path(log).read_text()) + with tempfile.TemporaryDirectory(prefix=".dex-lock-import-", dir=target.parent) as temporary: + stage = Path(temporary) + generated = stage / "locks/generated" + generated.mkdir(parents=True) + for name, data in files.items(): + path = generated / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(data) + for name in ("inputs.lock", "requests.txt"): + shutil.copyfile(ROOT / "locks" / name, stage / "locks" / name) + check_modules(stage) + generated.rename(target) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("log", type=Path) + parser.add_argument("--output", type=Path, default=ROOT / "locks/generated", + help="New review directory outside the checkout; existing qualified locks are never overwritten") + args = parser.parse_args() + import_artifact(args.log, args.output) + print("Imported active Go locks and archival .snapshot baselines. Review dependencies.patch and all selected modules before building.") + + +if __name__ == "__main__": + try: + main() + except (ValueError, OSError, EOFError, tarfile.TarError, zlib.error) as error: + raise SystemExit(str(error)) from None diff --git a/bridge/idp/scripts/notices.go b/bridge/idp/scripts/notices.go new file mode 100644 index 00000000..b1337b8a --- /dev/null +++ b/bridge/idp/scripts/notices.go @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// Collect notices from actual linked modules, not from the entire module cache. +package main + +import ( + "encoding/json" + "fmt" + "io" + "io/fs" + "os" + "path/filepath" + "runtime" + "sort" + "strings" +) + +type module struct { + Path, Version, Dir string + Main bool + Replace *module +} + +func runtimeModules(input io.Reader) (map[string]module, error) { + decoder := json.NewDecoder(input) + modules := map[string]module{ + "golang.org/toolchain@" + runtime.Version(): {Dir: runtime.GOROOT()}, + } + foundDex := false + for { + var pkg struct { + ImportPath string + Module *module + } + if err := decoder.Decode(&pkg); err != nil { + if err == io.EOF { + break + } + return nil, err + } + if pkg.ImportPath == "" { + return nil, fmt.Errorf("runtime package inventory contains a missing import path") + } + if pkg.ImportPath == "golang.org/x/crypto/openpgp" || + strings.HasPrefix(pkg.ImportPath, "golang.org/x/crypto/openpgp/") { + return nil, fmt.Errorf("forbidden compiled runtime package: %s (GO-2026-5932)", pkg.ImportPath) + } + if pkg.ImportPath == "github.com/dexidp/dex/cmd/dex" { + foundDex = true + } + if pkg.Module == nil || pkg.Module.Main { + continue + } + m := *pkg.Module + if m.Replace != nil { + m.Dir = m.Replace.Dir + } + modules[m.Path+"@"+m.Version] = m + } + if !foundDex { + return nil, fmt.Errorf("runtime package inventory does not include the Dex command") + } + return modules, nil +} + +func run() error { + if len(os.Args) != 3 { + return fmt.Errorf("usage: notices packages.json output-directory") + } + f, err := os.Open(os.Args[1]) + if err != nil { + return err + } + defer f.Close() + modules, err := runtimeModules(f) + if err != nil { + return err + } + keys := make([]string, 0, len(modules)) + for key := range modules { + keys = append(keys, key) + } + sort.Strings(keys) + for _, key := range keys { + m := modules[key] + rootLicense := false + err := filepath.WalkDir(m.Dir, func(path string, entry fs.DirEntry, err error) error { + if err != nil { + return err + } + name := strings.ToUpper(entry.Name()) + if entry.IsDir() { + return nil + } + if !strings.HasPrefix(name, "LICENSE") && !strings.HasPrefix(name, "LICENCE") && !strings.HasPrefix(name, "COPYING") && + !strings.HasPrefix(name, "NOTICE") && !strings.HasPrefix(name, "COPYRIGHT") && + name != "AUTHORS" && name != "PATENTS" { + return nil + } + rel, err := filepath.Rel(m.Dir, path) + if err != nil { + return err + } + if filepath.Dir(rel) == "." && (strings.HasPrefix(name, "LICENSE") || strings.HasPrefix(name, "LICENCE") || strings.HasPrefix(name, "COPYING")) { + rootLicense = true + } + dest := filepath.Join(os.Args[2], key, rel) + if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil { + return err + } + data, err := os.ReadFile(path) + if err != nil { + return err + } + return os.WriteFile(dest, data, 0644) + }) + if err != nil { + return fmt.Errorf("%s: %w", key, err) + } + // Dex's nested API is licensed by the upstream repository root. + if !rootLicense && m.Path == "github.com/dexidp/dex/api/v2" { + data, err := os.ReadFile("/src/dex/LICENSE") + if err != nil { + return err + } + dest := filepath.Join(os.Args[2], key) + if err := os.MkdirAll(dest, 0755); err != nil { + return err + } + if err := os.WriteFile(filepath.Join(dest, "LICENSE"), data, 0644); err != nil { + return err + } + rootLicense = true + } + if !rootLicense { + return fmt.Errorf("%s: missing root license; review upstream attribution before shipping", key) + } + } + return os.WriteFile(filepath.Join(os.Args[2], "MODULES"), []byte(strings.Join(keys, "\n")+"\n"), 0644) +} + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/bridge/idp/scripts/notices_test.go b/bridge/idp/scripts/notices_test.go new file mode 100644 index 00000000..2f83351b --- /dev/null +++ b/bridge/idp/scripts/notices_test.go @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package main + +import ( + "encoding/json" + "strings" + "testing" +) + +func packageInventory(paths ...string) string { + var inventory strings.Builder + encoder := json.NewEncoder(&inventory) + for _, path := range paths { + if err := encoder.Encode(map[string]string{"ImportPath": path}); err != nil { + panic(err) + } + } + return inventory.String() +} + +func TestRuntimeModulesRejectsOpenPGPAndEverySubpackage(t *testing.T) { + for _, suffix := range []string{"", "/packet", "/armor", "/clearsign", "/errors", "/elgamal", "/s2k", "/future/nested"} { + t.Run(suffix, func(t *testing.T) { + path := "golang.org/x/crypto/openpgp" + suffix + _, err := runtimeModules(strings.NewReader(packageInventory("github.com/dexidp/dex/cmd/dex", path))) + if err == nil || !strings.Contains(err.Error(), "forbidden compiled runtime package: "+path) { + t.Fatalf("expected fatal OpenPGP package rejection, got %v", err) + } + }) + } +} + +func TestRuntimeModulesKeepsOtherCryptoAndModuleEvidence(t *testing.T) { + inventory := packageInventory( + "crypto/rsa", "github.com/dexidp/dex/cmd/dex", "golang.org/x/crypto/bcrypt", + "golang.org/x/crypto/openpgpcompat", "github.com/ProtonMail/go-crypto/openpgp", + ) + `{"ImportPath":"github.com/Azure/go-ntlmssp","Module":{"Path":"github.com/Azure/go-ntlmssp","Version":"v0.1.1","Dir":"/verified/module"}}` + modules, err := runtimeModules(strings.NewReader(inventory)) + if err != nil { + t.Fatal(err) + } + if modules["github.com/Azure/go-ntlmssp@v0.1.1"].Dir != "/verified/module" { + t.Fatal("actual selected module evidence was not retained") + } +} + +func TestRuntimeModulesRejectsEmptyMalformedOrWrongTargetInventory(t *testing.T) { + for _, input := range []string{"", "{", "{}", "null", packageInventory("golang.org/x/crypto/bcrypt")} { + if _, err := runtimeModules(strings.NewReader(input)); err == nil { + t.Fatalf("invalid runtime inventory accepted: %q", input) + } + } +} diff --git a/bridge/idp/scripts/source-inventory.sh b/bridge/idp/scripts/source-inventory.sh new file mode 100644 index 00000000..ef624b91 --- /dev/null +++ b/bridge/idp/scripts/source-inventory.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +# Dependency manifests are verified separately against the generated Go locks. +find . -type f ! -path './go.mod' ! -path './go.sum' \ + ! -path './api/v2/go.mod' ! -path './api/v2/go.sum' \ + -print0 | LC_ALL=C sort -z | xargs -0 sha256sum diff --git a/bridge/idp/scripts/upstream-tests.sh b/bridge/idp/scripts/upstream-tests.sh new file mode 100644 index 00000000..500234af --- /dev/null +++ b/bridge/idp/scripts/upstream-tests.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +go test -list '^TestNewAuthenticateMessage_ChallengeTargetInfoOffsetOverflowNoPanics$' \ + github.com/Azure/go-ntlmssp > /out/doc/ntlm-test-list.txt +grep -Fx 'TestNewAuthenticateMessage_ChallengeTargetInfoOffsetOverflowNoPanics' /out/doc/ntlm-test-list.txt +if ! go test -json -count=1 -race github.com/Azure/go-ntlmssp/... > /out/doc/ntlm-tests.json; then + cat /out/doc/ntlm-tests.json + exit 1 +fi +cat /out/doc/ntlm-tests.json +if ! go test -json -count=1 -race ./... > /out/doc/upstream-tests.json; then + cat /out/doc/upstream-tests.json + exit 1 +fi +cd api/v2 +if ! go test -json -count=1 -race ./... > /out/doc/api-tests.json; then + cat /out/doc/api-tests.json + exit 1 +fi diff --git a/bridge/idp/scripts/verify-locks.sh b/bridge/idp/scripts/verify-locks.sh new file mode 100644 index 00000000..78ecb0a5 --- /dev/null +++ b/bridge/idp/scripts/verify-locks.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set -eu +. /packaging/locks/inputs.lock +(cd /locks && sha256sum --check --strict SHA256SUMS) +cmp /packaging/locks/inputs.lock /locks/inputs.lock +cmp /packaging/locks/requests.txt /locks/requests.txt +test "$(cat /locks/toolchain.txt)" = "go version $GO_VERSION linux/$(go env GOARCH)" +for file in go.mod go.sum api/v2/go.mod api/v2/go.sum; do + cmp "/packaging/upstream/$file.snapshot" "/locks/upstream/$file.snapshot" + cp "/locks/$file" "$file" +done +test "$(go list -m -f '{{.GoVersion}}')" = 1.26.0 +replacements="$(go list -m -f '{{if .Replace}}{{.Path}} => {{.Replace.Path}}{{end}}' all)" +test "$(printf '%s\n' "$replacements" | sed '/^$/d')" = 'github.com/dexidp/dex/api/v2 => ./api/v2' +while IFS=@ read -r module version; do + # Exact requests are the approved selection, not merely scanner floors. + test "$(go list -m -f '{{.Version}}' "$module")" = "$version" +done < /packaging/locks/requests.txt +( + cd api/v2 + test "$(go list -m -f '{{.GoVersion}}')" = 1.26.0 + test "$(go list -m -f '{{.Version}}' google.golang.org/grpc)" = v1.83.2 + replacements="$(go list -m -f '{{if .Replace}}{{.Path}}{{end}}' all)" + test -z "$(printf '%s\n' "$replacements" | sed '/^$/d')" +) +sha256sum --check --strict /packaging/source.sha256 > /dev/null diff --git a/bridge/idp/tests/contracts.py b/bridge/idp/tests/contracts.py new file mode 100644 index 00000000..ded87254 --- /dev/null +++ b/bridge/idp/tests/contracts.py @@ -0,0 +1,166 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import hashlib +import json +from pathlib import Path +import re + +BASE = ( + "mcr.microsoft.com/azurelinux/distroless/base:3.0@sha256:" + "4377af4aa7a810b7d59f691eae5066895a71aa3eee4cfb4eba527bbebff16479" +) +RPM_MANIFEST = "var/lib/rpmmanifest/container-manifest-2" +ACTIVE_LOCK_FILES = {"go.mod", "go.sum", "api/v2/go.mod", "api/v2/go.sum"} +BASELINE_SNAPSHOTS = {f"upstream/{name}.snapshot" for name in ACTIVE_LOCK_FILES} +LOCK_FILES = ACTIVE_LOCK_FILES | BASELINE_SNAPSHOTS | { + "modules.json", "api-modules.json", "graph.txt", "toolchain.txt", + "inputs.lock", "requests.txt", "dependencies.patch", "SHA256SUMS", +} + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def json_stream(text): + decoder = json.JSONDecoder() + while text.strip(): + text = text.lstrip() + value, end = decoder.raw_decode(text) + yield value + text = text[end:] + + +def module_inventory(text): + modules = {} + for module in json_stream(text): + require(isinstance(module, dict) and isinstance(module.get("Path"), str), + "invalid module inventory record") + require(not module.get("Error"), f"module resolver error: {module['Path']}") + require(module["Path"] not in modules, f"duplicate module inventory: {module['Path']}") + modules[module["Path"]] = module + return modules + + +def check_modules(root): + """Validate the reviewed resolver artifact, without inventing Go checksums.""" + root = Path(root) + generated = root / "locks/generated" + require(generated.is_dir(), "hosted generated locks are missing; runtime build is blocked") + require(not generated.is_symlink(), "lock artifact cannot be a symlink") + entries = list(generated.rglob("*")) + require(not any(path.is_symlink() for path in entries), "lock artifact cannot contain symlinks") + actual = {str(path.relative_to(generated)) for path in entries if path.is_file()} + require(actual == LOCK_FILES, "unexpected or missing lock artifact files") + for name in ("inputs.lock", "requests.txt"): + require((generated / name).read_bytes() == (root / "locks" / name).read_bytes(), + f"resolver input drift: {name}") + records = {} + for line in (generated / "SHA256SUMS").read_text().splitlines(): + digest, name = line.split(" ", 1) + require(re.fullmatch(r"[0-9a-f]{64}", digest), "invalid artifact SHA-256") + path = Path(name) + require(not path.is_absolute() and ".." not in path.parts, "unsafe checksum path") + require(name not in records, "duplicate checksum path") + records[name] = digest + require(hashlib.sha256((generated / path).read_bytes()).hexdigest() == digest, + f"artifact digest mismatch: {name}") + require({"./" + name for name in actual - {"SHA256SUMS"}} == set(records), + "artifact checksum coverage is incomplete") + require(re.fullmatch(r"go version go1\.26\.8 linux/(amd64|arm64)\n", + (generated / "toolchain.txt").read_text()), + "unexpected resolver toolchain") + inventories = {name: module_inventory((generated / name).read_text()) + for name in ("modules.json", "api-modules.json")} + selected = inventories["modules.json"] + for line in (root / "locks/requests.txt").read_text().splitlines(): + name, version = line.split("@") + require(selected.get(name, {}).get("Version") == version, f"unreviewed selection: {name}") + require("Replace" not in selected[name], f"unexpected replacement: {name}") + for name, modules in inventories.items(): + expected_main = "github.com/dexidp/dex" + ("/api/v2" if name == "api-modules.json" else "") + require([m["Path"] for m in modules.values() if m.get("Main")] == [expected_main], + f"unexpected main module in {name}") + for module in modules.values(): + if "Replace" in module: + require(name == "modules.json" and module["Path"] == "github.com/dexidp/dex/api/v2" and + module["Replace"]["Path"] == "./api/v2", + f"unexpected module replacement in {name}") + require(selected.get("github.com/dexidp/dex/api/v2", {}).get("Replace", {}).get("Path") == "./api/v2", + "upstream local API replacement is missing") + api = inventories["api-modules.json"] + require(api.get("google.golang.org/grpc", {}).get("Version") == "v1.83.2", "nested API gRPC is unpatched") + for name in ("go.mod", "api/v2/go.mod"): + manifest = (generated / name).read_text() + require("\ngo 1.26.0\n" in manifest, f"unexpected Go requirement: {name}") + # Go may omit a redundant toolchain directive; the pinned builder and + # GOTOOLCHAIN=local remain authoritative in that case. + directives = [line for line in manifest.splitlines() if line.startswith("toolchain ")] + require(not directives or directives == ["toolchain go1.26.8"], + f"unexpected automatic toolchain: {name}") + + +def check_rootfs(base, runtime, manifest): + # Docker injects these three per-container files during export. + injected = {"etc/hosts", "etc/hostname", "etc/resolv.conf"} + for name, record in base.items(): + if name not in injected: + require(runtime.get(name) == record, f"base file modified/removed: {name}") + require(len(manifest.strip().splitlines()) == 14, "expected 14 Azure Linux RPM inventory records") + require(RPM_MANIFEST in runtime, "RPM inventory missing") + require(any("ca-trust" in name or name.endswith("ca-certificates.crt") for name in base), + "base CA trust inventory missing") + for name in runtime.keys() - base.keys() - injected: + require(name == "usr/local/bin/dex" or + name.startswith(("srv/dex/web/", "usr/share/doc/dex/")), + f"unexpected runtime payload: {name}") + for name in ("usr/local/bin/docker-entrypoint", "usr/local/bin/gomplate", + "bin/sh", "bin/bash", "usr/bin/sh", "usr/bin/bash", + "usr/bin/tdnf", "usr/bin/npm", "usr/local/go/bin/go", "usr/bin/gcc"): + require(name not in runtime, f"shipping tool/unused entrypoint: {name}") + +def resolve_base_file(inventory, requested): + require(isinstance(requested, str) and requested.startswith("/") + and len(requested) <= 4096 and "\0" not in requested, "invalid ELF interpreter path") + pending = requested.split("/") + resolved = [] + links = 0 + while pending: + part = pending.pop(0) + if part in ("", "."): + continue + if part == "..": + require(resolved, "base link escapes image root") + resolved.pop() + continue + name = "/".join([*resolved, part]) + entry = inventory.get(name) + if entry is not None and entry[0] in ("symlink", "hardlink"): + links += 1 + require(links <= 32, "base link resolution exceeds its bound") + target = entry[2] + require(isinstance(target, str) and target and len(target) <= 4096 + and "\0" not in target, "invalid base link target") + if entry[0] == "hardlink" or target.startswith("/"): + resolved = [] + pending = target.split("/") + pending + else: + resolved.append(part) + name = "/".join(resolved) + require(inventory.get(name, (None,))[0] == "file", "ELF interpreter is not provided by pinned runtime") + return name + + +def check_scan(report): + require(report.get("Metadata", {}).get("OS", {}).get("Family") == "azurelinux", + "scanner failed to identify Azure Linux") + results = report.get("Results", []) + require(any(r.get("Type") == "gobinary" and r["Target"].lstrip("/") == "usr/local/bin/dex" + for r in results), "scanner failed to inventory the Dex Go binary") + for result in results: + require(not result.get("Vulnerabilities"), "HIGH/CRITICAL scan findings remain") + os_results = [r for r in results if r.get("Class") == "os-pkgs"] + packages = {p["Name"] for r in os_results for p in r.get("Packages", [])} + require(len(packages) == 14, "scanner did not inventory all 14 base RPM packages") diff --git a/bridge/idp/tests/probe.go b/bridge/idp/tests/probe.go new file mode 100644 index 00000000..a5ea32c5 --- /dev/null +++ b/bridge/idp/tests/probe.go @@ -0,0 +1,532 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// Hosted-only black-box checks against the actual distroless Dex container. +package main + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "math/big" + "net/http" + "net/http/cookiejar" + "net/url" + "os" + "path/filepath" + "strings" + "time" + + "golang.org/x/crypto/bcrypt" + "golang.org/x/net/html" +) + +const ( + clientID = "kars-packaging-probe" + email = "packaging-test@example.invalid" + callback = "http://127.0.0.1:18999/callback" +) + +type credentials struct { + Password string + Refresh string + Nonce string + IDToken string + SigningKey signingKeyIdentity +} + +type signingKeyIdentity struct { + Kid string + Modulus string + Exponent int +} + +type verifiedIDToken struct { + Subject string + SigningKey signingKeyIdentity +} + +type tokenSet struct { + Access string `json:"access_token"` + ID string `json:"id_token"` + Refresh string `json:"refresh_token"` + Type string `json:"token_type"` +} + +func randomToken() (string, error) { + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(b), nil +} + +func writeJSON(path string, value any, mode os.FileMode) error { + b, err := json.MarshalIndent(value, "", " ") + if err != nil { + return err + } + return os.WriteFile(path, b, mode) +} + +func configure(issuer, dir, storage string) error { + if storage != "memory" && storage != "sqlite3" { + return fmt.Errorf("unsupported test storage %q", storage) + } + password, err := randomToken() + if err != nil { + return err + } + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return err + } + store := map[string]any{"type": storage} + if storage == "sqlite3" { + store["config"] = map[string]any{"file": "/var/dex/dex.db"} + if err := os.Chown("/var/dex", 1001, 1001); err != nil { + return err + } + } + config := map[string]any{ + "issuer": issuer, "storage": store, + "web": map[string]any{"http": "0.0.0.0:5556"}, + "frontend": map[string]any{"dir": "/srv/dex/web"}, + "oauth2": map[string]any{"skipApprovalScreen": true}, + "staticClients": []any{map[string]any{ + "id": clientID, "name": "Ephemeral packaging test", + "secretEnv": "DEX_TEST_CLIENT_SECRET", "redirectURIs": []string{callback}, + }}, + "enablePasswordDB": true, + "staticPasswords": []any{map[string]any{ + "email": email, "hash": string(hash), "username": "packaging-test", + "userID": "286e3ba6-cfb5-47e1-a5ae-66b290626b66", + }}, + } + if err := writeJSON(filepath.Join(dir, "config.yaml"), config, 0644); err != nil { + return err + } + return writeJSON(filepath.Join(dir, "credentials.json"), credentials{Password: password}, 0600) +} + +func client() (*http.Client, error) { + jar, err := cookiejar.New(nil) + if err != nil { + return nil, err + } + return &http.Client{ + Jar: jar, Timeout: 10 * time.Second, + CheckRedirect: func(req *http.Request, via []*http.Request) error { + if strings.HasPrefix(req.URL.String(), callback+"?") { + return http.ErrUseLastResponse + } + if len(via) >= 10 { + return fmt.Errorf("too many redirects") + } + return nil + }, + }, nil +} + +func getJSON(c *http.Client, endpoint string, result any) error { + resp, err := c.Get(endpoint) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("GET %s returned %d", endpoint, resp.StatusCode) + } + return json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(result) +} + +func login(issuer, password, verifier, nonce string, shouldSucceed bool) (string, error) { + c, err := client() + if err != nil { + return "", err + } + state, err := randomToken() + if err != nil { + return "", err + } + challenge := sha256.Sum256([]byte(verifier)) + query := url.Values{ + "client_id": {clientID}, "redirect_uri": {callback}, "response_type": {"code"}, + "scope": {"openid profile email offline_access"}, "state": {state}, "nonce": {nonce}, + "code_challenge": {base64.RawURLEncoding.EncodeToString(challenge[:])}, + "code_challenge_method": {"S256"}, "connector_id": {"local"}, + } + resp, err := c.Get(issuer + "/auth?" + query.Encode()) + if err != nil { + return "", err + } + doc, parseErr := html.Parse(io.LimitReader(resp.Body, 1<<20)) + resp.Body.Close() + if parseErr != nil { + return "", parseErr + } + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("login page returned %d", resp.StatusCode) + } + action := "" + foundForm, foundPassword := false, false + fields := url.Values{} + var visit func(*html.Node) + visit = func(n *html.Node) { + attrs := map[string]string{} + for _, a := range n.Attr { + attrs[a.Key] = a.Val + } + if n.Type == html.ElementNode && n.Data == "form" { + action, foundForm = attrs["action"], true + } + if n.Type == html.ElementNode && n.Data == "input" { + if attrs["type"] == "hidden" { + fields.Set(attrs["name"], attrs["value"]) + } + if attrs["name"] == "password" { + foundPassword = true + } + } + for child := n.FirstChild; child != nil; child = child.NextSibling { + visit(child) + } + } + visit(doc) + if !foundForm || !foundPassword { + return "", fmt.Errorf("real password login form missing") + } + target, err := resp.Request.URL.Parse(action) + if err != nil { + return "", err + } + if target.Host != resp.Request.URL.Host || target.Scheme != resp.Request.URL.Scheme { + return "", fmt.Errorf("login form leaves issuer origin") + } + fields.Set("login", email) + fields.Set("password", password) + resp, err = c.PostForm(target.String(), fields) + if err != nil { + return "", err + } + defer resp.Body.Close() + location := resp.Header.Get("Location") + if !shouldSucceed { + if resp.StatusCode != http.StatusUnauthorized || strings.HasPrefix(location, callback) { + return "", fmt.Errorf("invalid password did not return its unauthorized login form (status %d)", resp.StatusCode) + } + body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return "", err + } + if !strings.Contains(string(body), `id="login-error"`) { + return "", fmt.Errorf("invalid password rejection missing") + } + return "", nil + } + if (resp.StatusCode != 302 && resp.StatusCode != 303) || !strings.HasPrefix(location, callback+"?") { + return "", fmt.Errorf("authorization did not redirect to registered callback: status %d", resp.StatusCode) + } + redirect, err := url.Parse(location) + if err != nil { + return "", err + } + if redirect.Query().Get("state") != state || redirect.Query().Get("code") == "" || redirect.Query().Get("error") != "" { + return "", fmt.Errorf("authorization code/state response invalid") + } + return redirect.Query().Get("code"), nil +} + +func exchange(issuer, secret string, form url.Values, shouldSucceed bool) (tokenSet, error) { + c, err := client() + if err != nil { + return tokenSet{}, err + } + req, err := http.NewRequest(http.MethodPost, issuer+"/token", strings.NewReader(form.Encode())) + if err != nil { + return tokenSet{}, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.SetBasicAuth(clientID, secret) + resp, err := c.Do(req) + if err != nil { + return tokenSet{}, err + } + defer resp.Body.Close() + if !shouldSucceed { + var rejection struct{ Error string } + if err := json.NewDecoder(resp.Body).Decode(&rejection); err != nil { + return tokenSet{}, err + } + if resp.StatusCode < 400 || resp.StatusCode >= 500 || rejection.Error == "" { + return tokenSet{}, fmt.Errorf("invalid token request was not rejected") + } + return tokenSet{}, nil + } + if resp.StatusCode != http.StatusOK { + return tokenSet{}, fmt.Errorf("token endpoint returned %d", resp.StatusCode) + } + var tokens tokenSet + if err := json.NewDecoder(resp.Body).Decode(&tokens); err != nil { + return tokens, err + } + if tokens.Access == "" || tokens.ID == "" || tokens.Refresh == "" || !strings.EqualFold(tokens.Type, "bearer") { + return tokens, fmt.Errorf("incomplete token response") + } + return tokens, nil +} + +func verifyIDToken(c *http.Client, issuer, nonce, idToken string) (verifiedIDToken, error) { + parts := strings.Split(idToken, ".") + if len(parts) != 3 { + return verifiedIDToken{}, fmt.Errorf("invalid ID token shape") + } + decode := base64.RawURLEncoding.DecodeString + headerBytes, err := decode(parts[0]) + if err != nil { + return verifiedIDToken{}, err + } + var header struct{ Alg, Kid string } + if err := json.Unmarshal(headerBytes, &header); err != nil { + return verifiedIDToken{}, err + } + if header.Alg != "RS256" || header.Kid == "" { + return verifiedIDToken{}, fmt.Errorf("unexpected JWT algorithm or missing kid") + } + var jwks struct{ Keys []struct{ Kty, Kid, N, E string } } + if err := getJSON(c, issuer+"/keys", &jwks); err != nil { + return verifiedIDToken{}, err + } + var key *rsa.PublicKey + for _, jwk := range jwks.Keys { + if jwk.Kid != header.Kid || jwk.Kty != "RSA" { + continue + } + n, err := decode(jwk.N) + if err != nil { + return verifiedIDToken{}, err + } + e, err := decode(jwk.E) + if err != nil { + return verifiedIDToken{}, err + } + exponent := new(big.Int).SetBytes(e) + if exponent.BitLen() > 31 || exponent.Int64() < 3 { + return verifiedIDToken{}, fmt.Errorf("invalid RSA exponent") + } + key = &rsa.PublicKey{N: new(big.Int).SetBytes(n), E: int(exponent.Int64())} + } + if key == nil || key.N.BitLen() < 2048 { + return verifiedIDToken{}, fmt.Errorf("matching strong JWKS signing key missing") + } + signature, err := decode(parts[2]) + if err != nil { + return verifiedIDToken{}, err + } + digest := sha256.Sum256([]byte(parts[0] + "." + parts[1])) + if err := rsa.VerifyPKCS1v15(key, crypto.SHA256, digest[:], signature); err != nil { + return verifiedIDToken{}, err + } + payload, err := decode(parts[1]) + if err != nil { + return verifiedIDToken{}, err + } + var claims struct { + Iss, Sub, Nonce, Email string + Aud json.RawMessage + Exp int64 + EmailVerified bool `json:"email_verified"` + } + if err := json.Unmarshal(payload, &claims); err != nil { + return verifiedIDToken{}, err + } + var audience string + var audiences []string + if err := json.Unmarshal(claims.Aud, &audience); err != nil { + if err := json.Unmarshal(claims.Aud, &audiences); err != nil { + return verifiedIDToken{}, err + } + if len(audiences) == 1 { + audience = audiences[0] + } + } + if claims.Iss != issuer || audience != clientID || claims.Nonce != nonce || + claims.Exp <= time.Now().Unix() || claims.Sub == "" || claims.Email != email || !claims.EmailVerified { + return verifiedIDToken{}, fmt.Errorf("signed ID token claims mismatch") + } + return verifiedIDToken{ + Subject: claims.Sub, + SigningKey: signingKeyIdentity{ + Kid: header.Kid, Modulus: base64.RawURLEncoding.EncodeToString(key.N.Bytes()), Exponent: key.E, + }, + }, nil +} + +func verify(issuer, nonce string, tokens tokenSet) (signingKeyIdentity, error) { + c, err := client() + if err != nil { + return signingKeyIdentity{}, err + } + verified, err := verifyIDToken(c, issuer, nonce, tokens.ID) + if err != nil { + return signingKeyIdentity{}, err + } + req, err := http.NewRequest(http.MethodGet, issuer+"/userinfo", nil) + if err != nil { + return signingKeyIdentity{}, err + } + req.Header.Set("Authorization", "Bearer "+tokens.Access) + resp, err := c.Do(req) + if err != nil { + return signingKeyIdentity{}, err + } + defer resp.Body.Close() + var user struct{ Sub, Email string } + if resp.StatusCode != 200 { + return signingKeyIdentity{}, fmt.Errorf("userinfo returned %d", resp.StatusCode) + } + if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { + return signingKeyIdentity{}, err + } + if user.Sub != verified.Subject || user.Email != email { + return signingKeyIdentity{}, fmt.Errorf("userinfo identity mismatch") + } + return verified.SigningKey, nil +} + +func check(issuer, dir, mode string) error { + c, err := client() + if err != nil { + return err + } + var discovery struct { + Issuer string + Auth string `json:"authorization_endpoint"` + Token string `json:"token_endpoint"` + JWKS string `json:"jwks_uri"` + PKCE []string `json:"code_challenge_methods_supported"` + } + var readyErr error + for attempt := 0; attempt < 60; attempt++ { + readyErr = getJSON(c, issuer+"/.well-known/openid-configuration", &discovery) + if readyErr == nil { + break + } + time.Sleep(time.Second) + } + if readyErr != nil { + return fmt.Errorf("discovery never became ready: %w", readyErr) + } + if discovery.Issuer != issuer || discovery.Auth != issuer+"/auth" || + discovery.Token != issuer+"/token" || discovery.JWKS != issuer+"/keys" || + !strings.Contains(strings.Join(discovery.PKCE, ","), "S256") { + return fmt.Errorf("OIDC discovery contract mismatch") + } + var creds credentials + data, err := os.ReadFile(filepath.Join(dir, "credentials.json")) + if err != nil { + return err + } + if err := json.Unmarshal(data, &creds); err != nil { + return err + } + secret := os.Getenv("DEX_TEST_CLIENT_SECRET") + if secret == "" { + return fmt.Errorf("ephemeral client secret missing") + } + if mode == "resume" { + if creds.IDToken == "" || creds.SigningKey.Kid == "" || creds.SigningKey.Modulus == "" || creds.SigningKey.Exponent == 0 { + return fmt.Errorf("pre-restart signing-key continuity evidence missing") + } + previous, err := verifyIDToken(c, issuer, creds.Nonce, creds.IDToken) + if err != nil { + return fmt.Errorf("pre-restart ID token verification failed: %w", err) + } + if previous.SigningKey != creds.SigningKey { + return fmt.Errorf("pre-restart signing-key identity changed") + } + tokens, err := exchange(issuer, secret, url.Values{ + "grant_type": {"refresh_token"}, "refresh_token": {creds.Refresh}, + }, true) + if err != nil { + return err + } + _, err = verify(issuer, creds.Nonce, tokens) + return err + } + verifier, err := randomToken() + if err != nil { + return err + } + creds.Nonce, err = randomToken() + if err != nil { + return err + } + if _, err := login(issuer, "deliberately-wrong", verifier, creds.Nonce, false); err != nil { + return err + } + for _, scenario := range []string{"wrong-pkce", "wrong-secret", "valid"} { + code, err := login(issuer, creds.Password, verifier, creds.Nonce, true) + if err != nil { + return err + } + form := url.Values{ + "grant_type": {"authorization_code"}, "redirect_uri": {callback}, + "code": {code}, "code_verifier": {verifier}, + } + useSecret := secret + if scenario == "wrong-pkce" { + form.Set("code_verifier", strings.Repeat("x", 43)) + } + if scenario == "wrong-secret" { + useSecret = "deliberately-wrong" + } + tokens, err := exchange(issuer, useSecret, form, scenario == "valid") + if err != nil { + return fmt.Errorf("%s: %w", scenario, err) + } + if scenario == "valid" { + signingKey, err := verify(issuer, creds.Nonce, tokens) + if err != nil { + return err + } + if _, err := exchange(issuer, secret, form, false); err != nil { + return fmt.Errorf("authorization code replay: %w", err) + } + creds.Refresh = tokens.Refresh + creds.IDToken = tokens.ID + creds.SigningKey = signingKey + } + } + return writeJSON(filepath.Join(dir, "credentials.json"), creds, 0600) +} + +func run() error { + if len(os.Args) < 4 { + return fmt.Errorf("usage: probe config|check|resume issuer config-directory [memory|sqlite3]") + } + switch os.Args[1] { + case "config": + if len(os.Args) != 5 { + return fmt.Errorf("config requires storage") + } + return configure(os.Args[2], os.Args[3], os.Args[4]) + case "check", "resume": + return check(os.Args[2], os.Args[3], os.Args[1]) + default: + return fmt.Errorf("unknown probe command") + } +} + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + fmt.Println("Dex packaging probe passed") +} diff --git a/bridge/idp/tests/probe_test.go b/bridge/idp/tests/probe_test.go new file mode 100644 index 00000000..9406e3e3 --- /dev/null +++ b/bridge/idp/tests/probe_test.go @@ -0,0 +1,305 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package main + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "slices" + "strings" + "sync" + "testing" + "time" +) + +type continuityJWK struct { + Kty string `json:"kty"` + Kid string `json:"kid"` + N string `json:"n"` + E string `json:"e"` +} + +func continuityKey(kid string, key *rsa.PrivateKey) continuityJWK { + return continuityJWK{ + Kty: "RSA", Kid: kid, + N: base64.RawURLEncoding.EncodeToString(key.N.Bytes()), + E: base64.RawURLEncoding.EncodeToString(big.NewInt(int64(key.E)).Bytes()), + } +} + +func TestInvalidPasswordResponse(t *testing.T) { + for _, tc := range []struct { + name string + status int + errorBox bool + redirect bool + wantOK bool + }{ + {name: "upstream unauthorized form", status: http.StatusUnauthorized, errorBox: true, wantOK: true}, + {name: "successful status is not rejection", status: http.StatusOK, errorBox: true}, + {name: "unrelated unauthorized response", status: http.StatusUnauthorized}, + {name: "bad request is not authentication rejection", status: http.StatusBadRequest, errorBox: true}, + {name: "callback redirect is not rejection", status: http.StatusFound, redirect: true}, + } { + t.Run(tc.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html") + switch { + case r.Method == http.MethodGet && r.URL.Path == "/dex/auth": + _, _ = w.Write([]byte(`
`)) + case r.Method == http.MethodPost && r.URL.Path == "/dex/login": + if err := r.ParseForm(); err != nil { + t.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + if r.Form.Get("login") != email || r.Form.Get("password") != "wrong-password" { + t.Error("probe did not submit the intended invalid credentials") + } + if tc.redirect { + w.Header().Set("Location", callback+"?code=unexpected-code") + } + w.WriteHeader(tc.status) + if tc.errorBox { + _, _ = w.Write([]byte(`
Invalid credentials.
`)) + } + default: + w.WriteHeader(http.StatusNotFound) + } + })) + defer server.Close() + code, err := login(server.URL+"/dex", "wrong-password", strings.Repeat("v", 43), "nonce", false) + if code != "" || (err == nil) != tc.wantOK { + t.Fatalf("invalid-password result: code present=%v, error=%v, want success=%v", code != "", err, tc.wantOK) + } + }) + } +} + +func continuityToken(t *testing.T, key *rsa.PrivateKey, issuer, kid, nonce string, expires time.Time) string { + t.Helper() + header, err := json.Marshal(map[string]string{"alg": "RS256", "kid": kid}) + if err != nil { + t.Fatal(err) + } + claims, err := json.Marshal(map[string]any{ + "iss": issuer, "aud": clientID, "sub": "continuity-subject", "nonce": nonce, + "exp": expires.Unix(), "email": email, "email_verified": true, + }) + if err != nil { + t.Fatal(err) + } + unsigned := base64.RawURLEncoding.EncodeToString(header) + "." + base64.RawURLEncoding.EncodeToString(claims) + digest := sha256.Sum256([]byte(unsigned)) + signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, digest[:]) + if err != nil { + t.Fatal(err) + } + return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature) +} + +func continuityJSON(t *testing.T, w http.ResponseWriter, value any) { + t.Helper() + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(value); err != nil { + t.Errorf("fixture JSON response: %v", err) + } +} + +func TestSigningKeyContinuity(t *testing.T) { + oldKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } + newKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } + const secret = "ephemeral-unit-test-client-secret" + const nonce = "pre-restart-nonce" + t.Setenv("DEX_TEST_CLIENT_SECRET", secret) + + for _, tc := range []struct { + name string + retainOldKey bool + sameKid bool + unchanged bool + changedIdentity bool + missingToken bool + missingIdentity bool + expiredToken bool + wrongUserinfo bool + wantError string + }{ + {name: "lost signing keys despite working refresh", wantError: "pre-restart ID token verification failed"}, + {name: "replacement key reuses old kid", sameKid: true, wantError: "pre-restart ID token verification failed"}, + {name: "rotation retains old verification key", retainOldKey: true}, + {name: "unchanged signing key", unchanged: true}, + {name: "saved key identity differs", retainOldKey: true, changedIdentity: true, wantError: "pre-restart signing-key identity changed"}, + {name: "missing old token", retainOldKey: true, missingToken: true, wantError: "continuity evidence missing"}, + {name: "missing verified key identity", retainOldKey: true, missingIdentity: true, wantError: "continuity evidence missing"}, + {name: "expired old token", retainOldKey: true, expiredToken: true, wantError: "signed ID token claims mismatch"}, + {name: "refresh still requires matching userinfo", retainOldKey: true, wrongUserinfo: true, wantError: "userinfo identity mismatch"}, + } { + t.Run(tc.name, func(t *testing.T) { + var mu sync.Mutex + var issuer string + var requests []string + keys := []continuityJWK{continuityKey("old-key", oldKey)} + var refreshed tokenSet + userSubject := "continuity-subject" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mu.Lock() + defer mu.Unlock() + requests = append(requests, r.URL.Path) + switch r.URL.Path { + case "/dex/.well-known/openid-configuration": + continuityJSON(t, w, map[string]any{ + "issuer": issuer, "authorization_endpoint": issuer + "/auth", + "token_endpoint": issuer + "/token", "jwks_uri": issuer + "/keys", + "code_challenge_methods_supported": []string{"S256"}, + }) + case "/dex/keys": + continuityJSON(t, w, map[string]any{"keys": keys}) + case "/dex/token": + id, password, ok := r.BasicAuth() + if r.Method != http.MethodPost || !ok || id != clientID || password != secret { + http.Error(w, "fixture client authentication failed", http.StatusUnauthorized) + return + } + if err := r.ParseForm(); err != nil || r.Form.Get("grant_type") != "refresh_token" || + r.Form.Get("refresh_token") != "persisted-refresh" { + http.Error(w, "fixture refresh request invalid", http.StatusBadRequest) + return + } + continuityJSON(t, w, refreshed) + case "/dex/userinfo": + if auth := r.Header.Get("Authorization"); auth != "Bearer old-access" && auth != "Bearer new-access" { + http.Error(w, "fixture access token invalid", http.StatusUnauthorized) + return + } + continuityJSON(t, w, map[string]string{"sub": userSubject, "email": email}) + default: + http.NotFound(w, r) + } + })) + defer server.Close() + mu.Lock() + issuer = server.URL + "/dex" + mu.Unlock() + + oldTokens := tokenSet{ + Access: "old-access", Refresh: "persisted-refresh", Type: "Bearer", + ID: continuityToken(t, oldKey, issuer, "old-key", nonce, time.Now().Add(time.Hour)), + } + identity, err := verify(issuer, nonce, oldTokens) + if err != nil { + t.Fatalf("pre-restart token verification: %v", err) + } + expectedIdentity := signingKeyIdentity{ + Kid: "old-key", Modulus: continuityKey("old-key", oldKey).N, Exponent: oldKey.E, + } + if identity != expectedIdentity { + t.Fatalf("verified signing-key identity = %+v, want %+v", identity, expectedIdentity) + } + creds := credentials{ + Password: "unused-by-resume", Refresh: oldTokens.Refresh, Nonce: nonce, + IDToken: oldTokens.ID, SigningKey: identity, + } + if tc.changedIdentity { + creds.SigningKey.Modulus = continuityKey("new-key", newKey).N + } + if tc.missingToken { + creds.IDToken = "" + } + if tc.missingIdentity { + creds.SigningKey = signingKeyIdentity{} + } + if tc.expiredToken { + creds.IDToken = continuityToken(t, oldKey, issuer, "old-key", nonce, time.Now().Add(-time.Hour)) + } + dir := t.TempDir() + path := filepath.Join(dir, "credentials.json") + if err := writeJSON(path, creds, 0600); err != nil { + t.Fatal(err) + } + info, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + if info.Mode().Perm() != 0600 { + t.Fatalf("private continuity credentials mode = %o, want 600", info.Mode().Perm()) + } + + activeKey, activeKid := newKey, "new-key" + if tc.sameKid { + activeKid = "old-key" + } + if tc.unchanged { + activeKey, activeKid = oldKey, "old-key" + } + newTokens := tokenSet{ + Access: "new-access", Refresh: "renewed-refresh", Type: "Bearer", + ID: continuityToken(t, activeKey, issuer, activeKid, nonce, time.Now().Add(time.Hour)), + } + mu.Lock() + keys = []continuityJWK{continuityKey(activeKid, activeKey)} + if tc.retainOldKey { + keys = append(keys, continuityKey("old-key", oldKey)) + } + refreshed = newTokens + mu.Unlock() + + // Prove the previous refresh-only check would pass, including when + // the old signing key has been lost or replaced under the same kid. + control, err := exchange(issuer, secret, url.Values{ + "grant_type": {"refresh_token"}, "refresh_token": {creds.Refresh}, + }, true) + if err != nil { + t.Fatalf("persisted refresh control: %v", err) + } + if _, err := verify(issuer, nonce, control); err != nil { + t.Fatalf("new-token/current-JWKS control: %v", err) + } + mu.Lock() + requests = nil + if tc.wrongUserinfo { + userSubject = "different-user" + } + mu.Unlock() + + err = check(issuer, dir, "resume") + if tc.wantError == "" { + if err != nil { + t.Fatalf("retained signing key must survive resume: %v", err) + } + } else if err == nil || !strings.Contains(err.Error(), tc.wantError) { + t.Fatalf("resume error = %v, want %q", err, tc.wantError) + } + mu.Lock() + gotRequests := append([]string(nil), requests...) + mu.Unlock() + wantRequests := []string{"/dex/.well-known/openid-configuration"} + if !tc.missingToken && !tc.missingIdentity { + wantRequests = append(wantRequests, "/dex/keys") + } + if tc.wantError == "" || tc.wrongUserinfo { + wantRequests = append(wantRequests, "/dex/token", "/dex/keys", "/dex/userinfo") + } + if !slices.Equal(gotRequests, wantRequests) { + t.Fatalf("request order = %v, want %v; old-token verification must precede refresh", gotRequests, wantRequests) + } + }) + } +} diff --git a/bridge/idp/tests/qualify.py b/bridge/idp/tests/qualify.py new file mode 100644 index 00000000..2c531d32 --- /dev/null +++ b/bridge/idp/tests/qualify.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Run only on a hosted native Linux Docker worker; no registry/cluster writes.""" + +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import secrets +import subprocess +import tarfile +import tempfile +import uuid + +from contracts import BASE, RPM_MANIFEST, check_modules, check_rootfs, check_scan, require, resolve_base_file + + +def run(*args, **kwargs): + return subprocess.run(args, check=True, text=True, capture_output=True, **kwargs).stdout + + +def export(image, directory, prefix): + container = run("docker", "create", "--entrypoint", "/usr/local/bin/dex", image).strip() + path = directory / (prefix + ".tar") + try: + run("docker", "export", "--output", str(path), container) + entries = {} + documents = {} + with tarfile.open(path) as archive: + for member in archive: + name = member.name.removeprefix("./") + if member.isfile(): + with archive.extractfile(member) as stream: + data = stream.read() + entries[name] = ("file", member.mode, hashlib.sha256(data).hexdigest()) + if name == RPM_MANIFEST or name.startswith("usr/share/doc/dex/elf-"): + documents[name] = data.decode() + elif member.issym(): + entries[name] = ("symlink", member.mode, member.linkname) + elif member.islnk(): + entries[name] = ("hardlink", member.mode, member.linkname) + return entries, documents + finally: + run("docker", "rm", container) + path.unlink(missing_ok=True) + + +def oidc(image, tools, storage, evidence): + suffix = uuid.uuid4().hex + network, config, data, name = (f"dex-test-{kind}-{suffix}" for kind in ("net", "config", "data", "server")) + created = [] + secret = "DEX_TEST_CLIENT_SECRET=" + secrets.token_urlsafe(32) + issuer = "http://dex:5556/dex" + try: + run("docker", "network", "create", "--internal", network) + created.append(("network", network)) + for volume in (config, data): + run("docker", "volume", "create", volume) + created.append(("volume", volume)) + probe = ["docker", "run", "--rm", "--network", network, "--env", secret, + "--mount", f"type=volume,src={config},dst=/config", + "--mount", f"type=volume,src={data},dst=/var/dex", tools] + run(*probe, "config", issuer, "/config", storage) + # This is the chart's direct invocation; no template-expanding wrapper. + run("docker", "create", "--name", name, "--network", network, + "--network-alias", "dex", "--read-only", "--cap-drop", "ALL", + "--security-opt", "no-new-privileges", "--user", "1001:1001", + "--tmpfs", "/tmp:rw,noexec,nosuid,size=16m", "--env", secret, + "--mount", f"type=volume,src={config},dst=/etc/dex,readonly", + "--mount", f"type=volume,src={data},dst=/var/dex", + "--entrypoint", "/usr/local/bin/dex", image, "serve", "/etc/dex/config.yaml") + created.append(("container", name)) + run("docker", "start", name) + output = run(*probe, "check", issuer, "/config") + if storage == "sqlite3": + run("docker", "restart", name) + output += run(*probe, "resume", issuer, "/config") + (evidence / f"{storage}-oidc.txt").write_text(output) + finally: + for kind, identifier in reversed(created): + if kind == "container": + run("docker", "rm", "--force", identifier) + else: + run("docker", kind, "rm", identifier) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--image", required=True) + parser.add_argument("--tools-image", required=True) + parser.add_argument("--evidence", required=True, type=Path) + parser.add_argument("--trivy", default="trivy") + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + check_modules(root) + args.evidence.mkdir(parents=True, exist_ok=False) + image = json.loads(run("docker", "image", "inspect", args.image))[0] + tools = json.loads(run("docker", "image", "inspect", args.tools_image))[0] + daemon_os, daemon_arch = run("docker", "info", "--format", "{{.OSType}}/{{.Architecture}}").strip().split("/") + daemon_arch = {"x86_64": "amd64", "aarch64": "arm64"}.get(daemon_arch, daemon_arch) + require(daemon_os == "linux" and daemon_arch == image["Architecture"], "native Linux worker required") + require(image["Os"] == "linux" and image["Architecture"] == tools["Architecture"], + "runtime/tools architecture mismatch") + # Resolve mutable local tags once. All subsequent checks address image IDs. + image_id, tools_id = image["Id"], tools["Id"] + (args.evidence / "image.json").write_text(json.dumps(image, indent=2)) + require(image["Config"]["User"] == "1001:1001", "unexpected runtime user") + require(image["Config"]["Entrypoint"] == ["/usr/local/bin/dex"], "unexpected entrypoint") + require(image["Config"]["Cmd"] == ["serve", "/etc/dex/config.yaml"], "unexpected command") + run("docker", "pull", "--platform", "linux/" + image["Architecture"], BASE) + with tempfile.TemporaryDirectory(prefix="dex-qualification-") as temporary: + scratch = Path(temporary) + base, _ = export(BASE, scratch, "base") + runtime, documents = export(image_id, scratch, "runtime") + check_rootfs(base, runtime, documents[RPM_MANIFEST]) + (args.evidence / "runtime-inventory.json").write_text(json.dumps(runtime, indent=2)) + for name, contents in documents.items(): + (args.evidence / Path(name).name).write_text(contents) + headers = documents["usr/share/doc/dex/elf-program-headers.txt"] + match = re.search(r"Requesting program interpreter: ([^\]]+)", headers) + require(match is not None, "CGO Dex must have a real runtime ELF interpreter") + loader = match.group(1) + provided = resolve_base_file(base, loader) + (args.evidence / "interpreter-origin.json").write_text(json.dumps({ + "requested": loader, "resolvedBaseFile": provided, "baseEntry": base[provided], + }, indent=2)) + linked = run("docker", "run", "--rm", "--network", "none", "--read-only", + "--cap-drop", "ALL", "--security-opt", "no-new-privileges", + "--entrypoint", loader, image_id, "--list", "/usr/local/bin/dex") + require("not found" not in linked and "libc.so.6" in linked, "native library closure failed") + (args.evidence / "runtime-linkage.txt").write_text(linked) + for storage in ("memory", "sqlite3"): + oidc(image_id, tools_id, storage, args.evidence) + environment = {k: v for k, v in os.environ.items() if not k.startswith("TRIVY_")} + version = run(args.trivy, "--version", env=environment) + require(re.search(r"Version: 0\.70\.0\b", version), "qualification requires Trivy 0.70.0") + empty_ignore = scratch / "empty.trivyignore" + empty_config = scratch / "empty.yaml" + empty_ignore.write_text("") + empty_config.write_text("{}\n") + cache = scratch / "trivy-cache" + common = [args.trivy, "--config", str(empty_config), "--cache-dir", str(cache), "image"] + run(*common, "--download-db-only", env=environment) + scan_path = args.evidence / "trivy-high-critical.json" + scan = subprocess.run( + [*common, "--image-src", "docker", "--scanners", "vuln", + "--ignorefile", str(empty_ignore), "--severity", "HIGH,CRITICAL", + "--list-all-pkgs", "--skip-db-update", "--exit-code", "1", + "--format", "json", "--output", str(scan_path), image_id], + text=True, capture_output=True, env=environment, + ) + (args.evidence / "trivy-stderr.txt").write_text(scan.stderr) + require(scan.returncode == 0, "final Trivy scan failed; see trivy-high-critical.json/stderr") + check_scan(json.loads(scan_path.read_text())) + (args.evidence / "trivy-version.txt").write_text(run(args.trivy, "--cache-dir", str(cache), + "--version", env=environment)) + (args.evidence / "runtime-passed.json").write_text(json.dumps({ + "image": image_id, "tools": tools_id, "base": BASE, + "checks": ["base-inventory-and-trust", "native-linkage", "memory-oidc", + "sqlite-oidc-and-refresh-after-restart", "latest-db-high-critical"], + "notCovered": ["upstream-service-integration-tests", "external-connector-enrollment", + "independent-rebuild-comparison", "deployment"], + }, indent=2)) + print("Runtime gates passed. Upstream suites, rebuild comparison and configured connector tests remain separate gates.") + + +if __name__ == "__main__": + try: + main() + except subprocess.CalledProcessError as error: + # Do not echo Docker command arguments containing ephemeral credentials. + raise SystemExit(f"Hosted command failed ({error.returncode}): {error.stderr or error.stdout}") from None + except (ValueError, OSError, KeyError) as error: + raise SystemExit(str(error)) from None diff --git a/bridge/idp/tests/test_baselines.py b/bridge/idp/tests/test_baselines.py new file mode 100644 index 00000000..2e2a81a2 --- /dev/null +++ b/bridge/idp/tests/test_baselines.py @@ -0,0 +1,110 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import base64 +import hashlib +import importlib.util +import io +from pathlib import Path +import tarfile +import unittest + +from contracts import ACTIVE_LOCK_FILES, BASELINE_SNAPSHOTS, LOCK_FILES + +ROOT = Path(__file__).resolve().parents[1] +GENERATED = ROOT / "locks/generated" +spec = importlib.util.spec_from_file_location("baseline_import_locks", ROOT / "scripts/import-locks.py") +import_locks = importlib.util.module_from_spec(spec) +spec.loader.exec_module(import_locks) + +# Captured from the verified chhp artifact before the path-only migration. +# A future dependency update requires a newly reviewed artifact, not rewriting +# these historical digests as part of a representation-only change. +CHHP_MANIFEST = """4a7bed6907c8f8918791e69539597405d6ad18f3f386788a81ed28f024113ac8 ./api-modules.json +e304bf72c1bf687cf777af1ca1c70d96e928a86bfb40bc6d5aeb8239baac24f6 ./api/v2/go.mod +3410f76108a083dc3a603327c354639a078ee8d917146aa7bf769e37cce0f208 ./api/v2/go.sum +7aab541b65a7246f95a919912582d909a8cfc09e9348a10e34afac1773c29644 ./dependencies.patch +34b7b1e48a6020a855741fc497f0782f226fa75a701cf925c52ccdd322d38046 ./go.mod +6e47d5b5c5cd6ff030ffe276d8707e41c67e88321a6bc81248f61c58271ec59b ./go.sum +e65265ab047188c71f6c5369a5be77d8cbbbefe26e307eb505775050ebece449 ./graph.txt +d5a430f8c8fea443ebc134cff29ddc0914bdc7acc1220fce9073c439e1a780d6 ./inputs.lock +2381158f636af5715561fca4208f4d89ca22a0e9c393bd53daa984a644ce5b72 ./modules.json +23d3448085a87cb3d242e196bb8ad7b571b63392c90871c2f5b26b1c5f0b6575 ./requests.txt +7e35a947feee25f89c2649aa041942db786be35c3d6c484ab2ba2da849e3dc00 ./toolchain.txt +181fc42a509297fe685e3470388d378a229e6efd36dd874eef809b6e06fe41e8 ./upstream/api/v2/go.mod +ccf35830330ac8058a4f009babbb417039aec728cf92625572abc53474c5dfca ./upstream/api/v2/go.sum +3390a3a2aa213fa80b7cb857ae52eb031e0f1941292f3536951092acb1db1501 ./upstream/go.mod +09fab6a9bedf5e220ee82f75f8fc7db4f52854012875082f24ba629020980d13 ./upstream/go.sum +""" + + +def artifact_log(files): + stream = io.BytesIO() + with tarfile.open(fileobj=stream, mode="w:gz") as archive: + for name, data in sorted(files.items()): + member = tarfile.TarInfo("./" + name) + member.size = len(data) + archive.addfile(member, io.BytesIO(data)) + payload = stream.getvalue() + return ("KARS_DEX_LOCKS_BASE64_BEGIN\n" + base64.b64encode(payload).decode() + + "\nKARS_DEX_LOCKS_BASE64_END\n" + hashlib.sha256(payload).hexdigest() + + " /tmp/dex-locks.tar.gz\n") + + +class BaselineRepresentationContracts(unittest.TestCase): + def test_archival_baselines_remain_immutable_across_reviewed_dependency_updates(self): + current_manifest = dict(line.split(" ", 1)[::-1] + for line in (GENERATED / "SHA256SUMS").read_text().splitlines()) + for line in CHHP_MANIFEST.splitlines(): + digest, original = line.split(" ", 1) + if not original.startswith("./upstream/"): + continue + renamed = original + ".snapshot" + self.assertEqual(hashlib.sha256((GENERATED / renamed).read_bytes()).hexdigest(), digest, renamed) + self.assertEqual(current_manifest[renamed], digest) + + def test_only_active_go_locks_keep_recognized_manifest_filenames(self): + expected_active = {"go.mod", "go.sum", "api/v2/go.mod", "api/v2/go.sum"} + self.assertEqual(ACTIVE_LOCK_FILES, expected_active) + recognized = {str(path.relative_to(GENERATED)) for path in GENERATED.rglob("*") + if path.is_file() and path.name in ("go.mod", "go.sum")} + self.assertEqual(recognized, expected_active) + self.assertEqual(BASELINE_SNAPSHOTS, {f"upstream/{name}.snapshot" for name in expected_active}) + for name in expected_active: + self.assertFalse((GENERATED / "upstream" / name).exists()) + self.assertTrue((GENERATED / "upstream" / (name + ".snapshot")).is_file()) + + def test_new_artifacts_import_without_altering_active_or_archival_bytes(self): + files = {name: (GENERATED / name).read_bytes() for name in LOCK_FILES} + imported = import_locks.decode_artifact(artifact_log(files)) + self.assertEqual(set(imported), LOCK_FILES) + for name, data in files.items(): + self.assertEqual(imported[name], data, name) + + def test_import_rejects_legacy_or_duplicate_active_looking_baselines(self): + files = {name: (GENERATED / name).read_bytes() for name in LOCK_FILES} + legacy = {name.removesuffix(".snapshot") if name in BASELINE_SNAPSHOTS else name: data + for name, data in files.items()} + legacy["SHA256SUMS"] = CHHP_MANIFEST.encode() + mixed = {**files, "upstream/go.mod": files["upstream/go.mod.snapshot"]} + for invalid in (legacy, mixed): + with self.assertRaisesRegex(ValueError, "unexpected or duplicate lock member"): + import_locks.decode_artifact(artifact_log(invalid)) + + def test_generator_validator_and_runtime_metadata_use_the_data_layout(self): + fetch = (ROOT / "scripts/fetch-source.sh").read_text() + self.assertIn('cp "$file" "/packaging/upstream/$file.snapshot"', fetch) + generator = (ROOT / "scripts/generate-locks.sh").read_text() + self.assertIn('cp -R /packaging/upstream /out/upstream', generator) + self.assertIn('"/packaging/upstream/$file.snapshot" "/out/$file"', generator) + self.assertIn('--label "upstream/$file" --label "kars/$file"', generator) + verifier = (ROOT / "scripts/verify-locks.sh").read_text() + self.assertIn('cmp "/packaging/upstream/$file.snapshot" "/locks/upstream/$file.snapshot"', verifier) + self.assertIn('cp "/locks/$file" "$file"', verifier) + self.assertNotIn('cp "/locks/upstream/', verifier) + self.assertIn('cp -R /locks /out/doc/locks', (ROOT / "scripts/build.sh").read_text()) + self.assertIn('COPY --from=build /out/doc/ /usr/share/doc/dex/', (ROOT / "Dockerfile").read_text()) + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/idp/tests/test_contracts.py b/bridge/idp/tests/test_contracts.py new file mode 100644 index 00000000..f50ba601 --- /dev/null +++ b/bridge/idp/tests/test_contracts.py @@ -0,0 +1,194 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import ast +import base64 +import gzip +import hashlib +import importlib.util +import io +from pathlib import Path +import tarfile +import unittest + +from contracts import BASE, LOCK_FILES, RPM_MANIFEST, check_modules, check_rootfs, check_scan, json_stream, module_inventory, resolve_base_file + +ROOT = Path(__file__).resolve().parents[1] +spec = importlib.util.spec_from_file_location("import_locks", ROOT / "scripts/import-locks.py") +import_locks = importlib.util.module_from_spec(spec) +spec.loader.exec_module(import_locks) + + +class SourceContracts(unittest.TestCase): + def test_json_stream(self): + self.assertEqual(list(json_stream('{"Path":"a"}\n{"Path":"b"}\n')), + [{"Path": "a"}, {"Path": "b"}]) + + def test_module_inventory_rejects_resolver_errors_and_duplicates(self): + self.assertEqual(module_inventory('{"Path":"module-a","Version":"v1.0.0"}'), + {"module-a": {"Path": "module-a", "Version": "v1.0.0"}}) + for bad in ('{"Path":"a"}\n{"Path":"a"}', '{"Path":"a","Error":{"Err":"unresolved"}}', + '{"Version":"v1.0.0"}', '[]'): + with self.assertRaises(ValueError): + module_inventory(bad) + + def test_runtime_recipe(self): + dockerfile = (ROOT / "Dockerfile").read_text() + runtime = dockerfile.split(f"FROM {BASE} AS runtime\n")[1] + self.assertNotIn("\nRUN ", runtime) + self.assertNotIn("--from=dependencies", runtime) + self.assertNotIn("COPY .", runtime) + self.assertIn('ENTRYPOINT ["/usr/local/bin/dex"]', runtime) + self.assertIn('CMD ["serve", "/etc/dex/config.yaml"]', runtime) + self.assertIn("COPY locks/generated/ /locks/", dockerfile) + self.assertIn("CGO_ENABLED=1", dockerfile) + self.assertIn("GOTOOLCHAIN=local", dockerfile) + self.assertNotIn("go get", (ROOT / "scripts/build.sh").read_text()) + + def test_resolver_is_separate_from_runtime_build(self): + runtime = (ROOT / "Dockerfile").read_text() + maintenance = (ROOT / "Dockerfile.locks").read_text() + self.assertNotIn("generate-locks", runtime) + self.assertNotIn("FROM lock-generation", runtime) + self.assertNotIn("lock-replay", runtime) + self.assertIn("FROM source AS lock-replay", maintenance) + self.assertIn("cmp SHA256SUMS /out/SHA256SUMS", maintenance) + def source(text): + return text[text.index("FROM golang:"):text.index("\nFROM source AS ")] + + self.assertEqual(source(runtime), source(maintenance)) + self.assertIn("!Dockerfile.locks", (ROOT / ".dockerignore").read_text()) + + def test_lock_artifact_and_readonly_replay_default_to_nonroot(self): + maintenance = (ROOT / "Dockerfile.locks").read_text() + artifact = maintenance.split("FROM scratch AS lock-artifact\n", 1)[1].split("\nFROM ", 1)[0] + replay = maintenance.split("FROM source AS lock-replay\n", 1)[1] + self.assertIn("COPY --from=lock-generation --chown=1001:1001 /out/ /", artifact) + self.assertEqual([line for line in artifact.splitlines() if line.startswith("USER ")], + ["USER 1001:1001"]) + self.assertNotIn("RUN ", artifact) + self.assertIn("COPY --from=lock-generation --chown=1001:1001 /out/ /out/", replay) + self.assertIn("COPY --chown=1001:1001 locks/generated/ /reviewed/", replay) + self.assertEqual([line for line in replay.splitlines() if line.startswith("USER ")], + ["USER 1001:1001"]) + self.assertLess(replay.index("USER 1001:1001"), replay.index("RUN ")) + self.assertIn('test "$(id -u)" = 1001 && test "$(id -g)" = 1001', replay) + self.assertIn("sha256sum --check --strict /reviewed/SHA256SUMS", replay) + self.assertNotIn("chmod", maintenance) + self.assertNotIn("go get", replay) + self.assertNotIn("go mod", replay) + self.assertNotIn("USER root", replay) + for path in (ROOT / "locks/generated").rglob("*"): + if path.is_file(): + self.assertTrue(path.stat().st_mode & 0o400, f"COPY owner cannot read {path}") + elif path.is_dir(): + self.assertTrue(path.stat().st_mode & 0o100, f"COPY owner cannot traverse {path}") + + def test_missing_locks_block_acceptance(self): + if (ROOT / "locks/generated").is_dir(): + check_modules(ROOT) + else: + with self.assertRaisesRegex(ValueError, "runtime build is blocked"): + check_modules(ROOT) + + def test_notice_collector_preserves_british_spelled_upstream_licences(self): + source = (ROOT / "scripts/notices.go").read_text() + self.assertEqual(source.count('strings.HasPrefix(name, "LICENCE")'), 2) + self.assertIn('strings.ToUpper(entry.Name())', source) + self.assertIn('missing root license; review upstream attribution before shipping', source) + self.assertIn('os.WriteFile(dest, data, 0644)', source) + + def test_base_inventory_must_survive(self): + base = {RPM_MANIFEST: ("file", 420, "manifest"), + "etc/pki/ca-trust/bundle.pem": ("file", 420, "trust")} + runtime = {**base, "usr/local/bin/dex": ("file", 493, "dex")} + manifest = "\n".join(f"rpm-{i}" for i in range(14)) + check_rootfs(base, runtime, manifest) + for name in base: + altered = dict(runtime) + altered[name] = ("file", 420, "changed") + with self.assertRaisesRegex(ValueError, "base file modified"): + check_rootfs(base, altered, manifest) + with self.assertRaisesRegex(ValueError, "14 Azure Linux RPM"): + check_rootfs(base, runtime, manifest + "\nunreviewed-rpm") + with self.assertRaisesRegex(ValueError, "unexpected runtime payload"): + check_rootfs(base, {**runtime, "usr/lib/libc.so": ("file", 493, "debian")}, manifest) + + def test_scanner_must_see_both_os_and_go(self): + report = { + "Metadata": {"OS": {"Family": "azurelinux"}}, + "Results": [ + {"Class": "os-pkgs", "Packages": [{"Name": f"rpm-{i}"} for i in range(14)]}, + {"Type": "gobinary", "Target": "/usr/local/bin/dex"}, + ], + } + check_scan(report) + report["Results"][1]["Vulnerabilities"] = [{"Severity": "HIGH"}] + with self.assertRaisesRegex(ValueError, "findings remain"): + check_scan(report) + report["Results"].pop() + with self.assertRaisesRegex(ValueError, "Dex Go binary"): + check_scan(report) + + def test_real_azure_linux_interpreter_links_resolve_only_to_base_files(self): + inventory = { + "lib64": ("symlink", 0o777, "usr/lib"), + "usr/lib64": ("symlink", 0o777, "lib"), + "usr/lib/ld-linux-x86-64.so.2": ("file", 0o755, "original-base-bytes"), + "usr/lib/absolute-loader": ("symlink", 0o777, "/lib64/ld-linux-x86-64.so.2"), + "usr/lib/hard-loader": ("hardlink", 0o755, "usr/lib/ld-linux-x86-64.so.2"), + } + for path in ("/lib64/ld-linux-x86-64.so.2", "/usr/lib64/ld-linux-x86-64.so.2", + "/usr/lib/absolute-loader", "/usr/lib/hard-loader"): + self.assertEqual(resolve_base_file(inventory, path), "usr/lib/ld-linux-x86-64.so.2") + self.assertEqual(inventory["lib64"][2], "usr/lib") + for path in ("/usr/share/doc/dex/not-in-base", "/lib64/missing", "relative/path"): + with self.assertRaises(ValueError): + resolve_base_file(inventory, path) + with self.assertRaisesRegex(ValueError, "bound"): + resolve_base_file({"cycle": ("symlink", 0o777, "cycle")}, "/cycle") + with self.assertRaisesRegex(ValueError, "escapes"): + resolve_base_file({"escape": ("symlink", 0o777, "../../host")}, "/escape") + + def test_python_syntax(self): + for file in ROOT.rglob("*.py"): + ast.parse(file.read_text(), filename=str(file)) + + def test_lock_archive_boundaries(self): + def log_for(names, checksum=None): + stream = io.BytesIO() + with tarfile.open(fileobj=stream, mode="w:gz") as archive: + for name in names: + member = tarfile.TarInfo("./" + name) + member.size = 4 + archive.addfile(member, io.BytesIO(b"test")) + payload = stream.getvalue() + checksum = checksum or hashlib.sha256(payload).hexdigest() + return ("KARS_DEX_LOCKS_BASE64_BEGIN\n" + + base64.b64encode(payload).decode() + + "\nKARS_DEX_LOCKS_BASE64_END\n" + + checksum + " /tmp/dex-locks.tar.gz\n") + + names = sorted(LOCK_FILES) + self.assertEqual(set(import_locks.decode_artifact(log_for(names))), set(names)) + for invalid in (names + ["go.mod"], names + ["../escape"], names[:-1]): + with self.assertRaises(ValueError): + import_locks.decode_artifact(log_for(invalid)) + with self.assertRaisesRegex(ValueError, "exactly one"): + import_locks.decode_artifact(log_for(names) + log_for(names)) + with self.assertRaisesRegex(ValueError, "transport SHA-256"): + import_locks.decode_artifact(log_for(names, "0" * 64)) + with self.assertRaisesRegex(ValueError, "transport SHA-256"): + import_locks.decode_artifact(log_for(names).replace("/tmp/dex-locks.tar.gz", "/tmp/wrong.tar.gz")) + + def test_archive_limit_includes_headers_and_padding(self): + payload = gzip.compress(b"\0" * (import_locks.MAX_ARCHIVE_BYTES + 1)) + log = ("KARS_DEX_LOCKS_BASE64_BEGIN\n" + base64.b64encode(payload).decode() + + "\nKARS_DEX_LOCKS_BASE64_END\n" + hashlib.sha256(payload).hexdigest() + + " /tmp/dex-locks.tar.gz\n") + with self.assertRaisesRegex(ValueError, "expanded artifact exceeds"): + import_locks.decode_artifact(log) + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/idp/tests/test_ntlm_update.py b/bridge/idp/tests/test_ntlm_update.py new file mode 100644 index 00000000..c68a7cf4 --- /dev/null +++ b/bridge/idp/tests/test_ntlm_update.py @@ -0,0 +1,83 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import hashlib +from pathlib import Path +import tempfile +import unittest + +from contracts import LOCK_FILES +from test_baselines import artifact_log, import_locks + +ROOT = Path(__file__).resolve().parents[1] +NTLM_REQUEST = "github.com/Azure/go-ntlmssp@v0.1.1" + + +class NTLMSecurityUpdateContracts(unittest.TestCase): + def test_exact_ntlm_update_does_not_change_crypto_or_other_pins(self): + requested = (ROOT / "locks/requests.txt").read_text().splitlines() + self.assertEqual(requested.count(NTLM_REQUEST), 1) + self.assertIn("golang.org/x/crypto@v0.56.0", requested) + self.assertIn("GO_VERSION=go1.26.8", (ROOT / "locks/inputs.lock").read_text()) + self.assertEqual(len(requested), len(set(requested))) + + def test_runtime_inventory_is_retained_and_checked_without_filtering_packages(self): + build = (ROOT / "scripts/build.sh").read_text() + self.assertIn("go list -deps -json=ImportPath,Module ./cmd/dex > /out/doc/runtime-packages.json", build) + self.assertIn("go run /packaging/scripts/notices.go /out/doc/runtime-packages.json /out/doc/third-party", build) + notice = (ROOT / "scripts/notices.go").read_text() + self.assertIn('pkg.ImportPath == "golang.org/x/crypto/openpgp"', notice) + self.assertIn('strings.HasPrefix(pkg.ImportPath, "golang.org/x/crypto/openpgp/")', notice) + self.assertIn('forbidden compiled runtime package: %s (GO-2026-5932)', notice) + self.assertIn('runtime package inventory does not include the Dex command', notice) + self.assertEqual(notice.count('strings.HasPrefix(name, "LICENCE")'), 2) + dockerfile = (ROOT / "Dockerfile").read_text() + self.assertIn("go test -count=1 /packaging/scripts/notices.go /packaging/scripts/notices_test.go", dockerfile) + self.assertIn("COPY --from=build /out/doc/ /usr/share/doc/dex/", dockerfile) + + def test_real_upstream_ntlm_overflow_regression_and_package_suite_are_required(self): + script = (ROOT / "scripts/upstream-tests.sh").read_text() + test = "TestNewAuthenticateMessage_ChallengeTargetInfoOffsetOverflowNoPanics" + self.assertIn(f"go test -list '^{test}$'", script) + self.assertIn(f"grep -Fx '{test}' /out/doc/ntlm-test-list.txt", script) + self.assertIn("go test -json -count=1 -race github.com/Azure/go-ntlmssp/...", script) + self.assertIn("cat /out/doc/ntlm-tests.json", script) + self.assertIn("go test -json -count=1 -race ./...", script) + self.assertNotIn("-vet=off", script) + + def test_review_import_never_overwrites_an_existing_output(self): + with tempfile.TemporaryDirectory(prefix="kars-ntlm-review-contract-") as temporary: + target = Path(temporary) / "reviewed" + target.mkdir() + marker = target / "keep" + marker.write_bytes(b"existing reviewed evidence") + with self.assertRaisesRegex(ValueError, "already exists"): + import_locks.import_artifact(Path(temporary) / "unused.log", target) + self.assertEqual(marker.read_bytes(), b"existing reviewed evidence") + + def test_review_import_rejects_stale_artifacts_without_touching_qualified_locks(self): + generated = ROOT / "locks/generated" + before = {name: hashlib.sha256((generated / name).read_bytes()).hexdigest() for name in LOCK_FILES} + files = {name: (generated / name).read_bytes() for name in LOCK_FILES} + files["requests.txt"] = "\n".join( + line for line in files["requests.txt"].decode().splitlines() if line != NTLM_REQUEST + ).encode() + b"\n" + with tempfile.TemporaryDirectory(prefix="kars-ntlm-staging-contract-") as temporary: + directory = Path(temporary) + log = directory / "stale.log" + log.write_text(artifact_log(files)) + target = directory / "reviewed" + with self.assertRaisesRegex(ValueError, "resolver input drift: requests.txt"): + import_locks.import_artifact(log, target) + self.assertFalse(target.exists()) + self.assertEqual(sorted(path.name for path in directory.iterdir()), ["stale.log"]) + after = {name: hashlib.sha256((generated / name).read_bytes()).hexdigest() for name in LOCK_FILES} + self.assertEqual(after, before) + + def test_alternate_review_output_cannot_create_more_active_manifests_in_checkout(self): + with self.assertRaisesRegex(ValueError, "outside the source checkout"): + import_locks.import_artifact("unused.log", ROOT / "locks/proposed-ntlm") + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/idp/tests/test_patches.py b/bridge/idp/tests/test_patches.py new file mode 100644 index 00000000..c998052a --- /dev/null +++ b/bridge/idp/tests/test_patches.py @@ -0,0 +1,194 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import hashlib +import io +import os +from pathlib import Path +import shutil +import subprocess +import tarfile +import tempfile +import unittest +import urllib.request +import xml.etree.ElementTree as ET + +ROOT = Path(__file__).resolve().parents[1] +MODIFIED = {"./server/oauth2.go", "./connector/saml/saml_test.go"} +ADDED = {"./server/kars_compat_test.go", "./connector/saml/kars_compat_test.go"} + + +def checksums(path): + result = {} + for line in path.read_text().splitlines(): + digest, name = line.split(" ", 1) + if name in result: + raise ValueError("duplicate checksum path") + result[name] = digest + return result + + +class PatchContracts(unittest.TestCase): + def test_all_reviewed_inputs_are_pinned(self): + patches = ROOT / "patches" + manifest = checksums(patches / "SHA256SUMS") + self.assertEqual(set(manifest), {p.name for p in patches.iterdir() if p.name != "SHA256SUMS"}) + for name, digest in manifest.items(): + self.assertEqual(hashlib.sha256((patches / name).read_bytes()).hexdigest(), digest, name) + self.assertEqual(set(checksums(patches / "upstream.sha256")), MODIFIED) + self.assertEqual(set(checksums(patches / "patched.sha256")), MODIFIED | ADDED) + self.assertEqual((patches / "series").read_text().splitlines(), [ + "0001-literal-oauth-error-descriptions.patch", + "0002-saml-fixture-validation-clock.patch", + ]) + + def test_production_delta_is_exactly_two_literal_format_callers(self): + lines = (ROOT / "patches/0001-literal-oauth-error-descriptions.patch").read_text().splitlines() + removed = [line[1:].strip() for line in lines if line.startswith("-") and not line.startswith("---")] + added = [line[1:].strip() for line in lines if line.startswith("+") and not line.startswith("+++")] + self.assertEqual(removed, [ + "return nil, newRedirectedErr(errInvalidRequest, description)", + "return nil, newRedirectedErr(errInvalidRequest, err)", + ]) + self.assertEqual(added, [ + 'return nil, newRedirectedErr(errInvalidRequest, "%s", description)', + 'return nil, newRedirectedErr(errInvalidRequest, "%s", err)', + ]) + + def test_fixture_clock_and_behavior_contracts_remain_test_only(self): + patch = (ROOT / "patches/0002-saml-fixture-validation-clock.patch").read_text() + self.assertEqual([line for line in patch.splitlines() if line.startswith("+++ ")], + ["+++ b/connector/saml/saml_test.go"]) + self.assertIn("runVerifyWithClock(t, ca, resp, shouldSucceed, nil)", patch) + self.assertIn("time.Date(2016, time.December, 12, 16, 54, 35, 0, time.UTC)", patch) + saml = (ROOT / "patches/saml_compat_test.go").read_text() + self.assertIn("cert.NotBefore.Add(-time.Second)", saml) + self.assertIn("cert.NotAfter.Add(time.Second)", saml) + self.assertIn("verifyResponseSig(validator, data)", saml) + self.assertIn("Cert is not valid at this time", saml) + oauth = (ROOT / "patches/server_compat_test.go").read_text() + self.assertIn('method: "%s%[1]s%%"', oauth) + self.assertIn("server.parseAuthorizationRequest(req)", oauth) + self.assertIn("redirected.Description != tc.description", oauth) + + def test_integrity_and_hosted_behavior_gates_are_wired(self): + script = (ROOT / "scripts/apply-source-patches.sh").read_text() + self.assertLess(script.index('source.upstream.sha256'), script.index("git apply --no-index --check")) + self.assertIn('git apply --no-index --whitespace=error-all "$patches/$name"', script) + self.assertNotIn("--unsafe-paths", script) + self.assertIn('"$patches/patched.sha256" "$packaging/source.upstream.sha256"', script) + self.assertIn('cmp "$packaging/source.sha256" "$packaging/source.actual.sha256"', script) + exclusions = (ROOT / "scripts/source-inventory.sh").read_text() + self.assertEqual(exclusions.count("! -path"), 4) + self.assertNotIn("oauth2.go", exclusions) + self.assertNotIn("saml_test.go", exclusions) + dockerfile = (ROOT / "Dockerfile").read_text() + self.assertIn("FROM build AS compatibility-tests", dockerfile) + self.assertIn("FROM compatibility-tests AS upstream-tests", dockerfile) + self.assertIn("TestKarsAuthorizationErrorDescriptionsLiteral", dockerfile) + self.assertIn("TestKarsSAMLFixtureCertificateValidity", dockerfile) + self.assertNotIn("-vet=off", dockerfile) + self.assertNotIn("-vet=off", (ROOT / "scripts/upstream-tests.sh").read_text()) + + +@unittest.skipUnless(os.environ.get("KARS_DEX_PATCH_NETWORK") == "1", + "opt in to bounded verified upstream download; no Go compilation") +class AppliedPatchContracts(unittest.TestCase): + @classmethod + def setUpClass(cls): + inputs = dict(line.split("=", 1) for line in (ROOT / "locks/inputs.lock").read_text().splitlines() + if line and not line.startswith("#")) + cls.commit = inputs["DEX_COMMIT"] + with urllib.request.urlopen(f"https://codeload.github.com/dexidp/dex/tar.gz/{cls.commit}", timeout=30) as response: + cls.archive = response.read(2 * 1024 * 1024 + 1) + if len(cls.archive) > 2 * 1024 * 1024: + raise ValueError("upstream archive exceeds bounded download size") + if hashlib.sha256(cls.archive).hexdigest() != inputs["DEX_ARCHIVE_SHA256"]: + raise ValueError("immutable upstream archive hash mismatch") + + def setUp(self): + temporary = tempfile.TemporaryDirectory(prefix=".patch-contract-", dir=ROOT) + self.addCleanup(temporary.cleanup) + self.directory = Path(temporary.name) + with tarfile.open(fileobj=io.BytesIO(self.archive), mode="r:gz") as archive: + self.assertLess(sum(member.size for member in archive), 16 * 1024 * 1024) + archive.extractall(self.directory, filter="data") + self.source = self.directory / ("dex-" + self.commit) + self.packaging = self.directory / "packaging" + shutil.copytree(ROOT / "patches", self.packaging / "patches") + (self.packaging / "scripts").mkdir() + for name in ("source-inventory.sh", "apply-source-patches.sh"): + shutil.copyfile(ROOT / "scripts" / name, self.packaging / "scripts" / name) + inventory = subprocess.run(["sh", str(self.packaging / "scripts/source-inventory.sh")], + cwd=self.source, check=True, capture_output=True, text=True) + (self.packaging / "source.upstream.sha256").write_text(inventory.stdout) + self.original = checksums(self.packaging / "source.upstream.sha256") + + def apply(self): + return subprocess.run(["sh", str(self.packaging / "scripts/apply-source-patches.sh"), str(self.packaging)], + cwd=self.source, capture_output=True, text=True) + + def test_exact_patch_application_and_complete_inventory(self): + original_oauth = (self.source / "server/oauth2.go").read_text() + self.assertIn("Description string", original_oauth) + module_paths = ["go.mod", "go.sum", "api/v2/go.mod", "api/v2/go.sum"] + modules = {name: (self.source / name).read_bytes() for name in module_paths} + result = self.apply() + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + expected = checksums(self.packaging / "source.sha256") + actual = checksums(self.packaging / "source.actual.sha256") + self.assertEqual(expected, actual) + self.assertEqual(set(expected) - set(self.original), ADDED) + self.assertEqual(set(self.original) - set(expected), set()) + self.assertEqual({name for name in self.original if self.original[name] != expected[name]}, MODIFIED) + self.assertEqual((self.source / "server/oauth2.go").read_text(), + original_oauth.replace("newRedirectedErr(errInvalidRequest, description)", + 'newRedirectedErr(errInvalidRequest, "%s", description)') + .replace("newRedirectedErr(errInvalidRequest, err)", + 'newRedirectedErr(errInvalidRequest, "%s", err)')) + for name, data in modules.items(): + self.assertEqual((self.source / name).read_bytes(), data) + self.assertEqual((ROOT / "locks/generated/upstream" / (name + ".snapshot")).read_bytes(), data) + fixture = ET.parse(self.source / "connector/saml/testdata/oam-resp.xml") + self.assertEqual(fixture.getroot().attrib["IssueInstant"], "2016-12-12T16:54:35Z") + self.assertEqual(self.original["./connector/saml/saml.go"], expected["./connector/saml/saml.go"]) + replay = self.apply() + self.assertNotEqual(replay.returncode, 0, "original-source verification must reject double application") + + def test_patch_tampering_fails_before_source_changes(self): + patch = self.packaging / "patches/0001-literal-oauth-error-descriptions.patch" + patch.write_text(patch.read_text() + "\n") + result = self.apply() + self.assertNotEqual(result.returncode, 0) + self.assertEqual(hashlib.sha256((self.source / "server/oauth2.go").read_bytes()).hexdigest(), + self.original["./server/oauth2.go"]) + + def test_original_source_drift_fails_before_patching(self): + source = self.source / "server/oauth2.go" + source.write_text(source.read_text() + "\n") + result = self.apply() + self.assertNotEqual(result.returncode, 0) + self.assertFalse((self.packaging / "source.sha256").exists()) + + def test_wrong_reviewed_post_hash_is_not_recomputed_from_output(self): + post = self.packaging / "patches/patched.sha256" + original_hash = checksums(post)["./server/oauth2.go"] + post.write_text(post.read_text().replace(original_hash, "0" * 64)) + manifest = self.packaging / "patches/SHA256SUMS" + old_pin = checksums(manifest)["patched.sha256"] + manifest.write_text(manifest.read_text().replace(old_pin, hashlib.sha256(post.read_bytes()).hexdigest())) + result = self.apply() + self.assertNotEqual(result.returncode, 0) + self.assertFalse((self.packaging / "source.sha256").exists()) + + def test_unreviewed_extra_source_is_rejected(self): + (self.source / "server/unreviewed.go").write_text("package server\n") + result = self.apply() + self.assertNotEqual(result.returncode, 0) + self.assertTrue((self.packaging / "source.actual.sha256").exists()) + self.assertNotEqual((self.packaging / "source.actual.sha256").read_bytes(), + (self.packaging / "source.sha256").read_bytes()) + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/tests/native-credentials/audit_evidence.py b/bridge/tests/native-credentials/audit_evidence.py new file mode 100644 index 00000000..5068bdd6 --- /dev/null +++ b/bridge/tests/native-credentials/audit_evidence.py @@ -0,0 +1,101 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Bounded metadata-only audit snapshots, including retained rotated files.""" + +import json +import re + +from native_api import BRIDGE, WRITER, CommandFailure, Failure, command, require, resource, until + +DIRECTORY = "/var/log/kars-native-audit" +CONTROL_PLANE = "bridge-native-control-plane" +MAX_BYTES = 80 * 1024 * 1024 +AUDIT_ID = re.compile(r"[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}") +NAME = re.compile(r"audit(?:-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}\.[0-9]{3})?\.log") + + +class AuditSnapshot(list): + def __init__(self, events, marker): + super().__init__(events) + self.marker = marker + + +class UnsettledInventory(Failure): + """The active log is between its rotation rename and recreation.""" + + +def paths(): + names = command("docker", "exec", CONTROL_PLANE, "find", DIRECTORY, + "-maxdepth", "1", "-type", "f", "-name", "audit*.log", + timeout=30).splitlines() + require(len(names) <= 3 and len(set(names)) == len(names) + and all(name.startswith(DIRECTORY + "/") and + NAME.fullmatch(name[len(DIRECTORY) + 1:]) for name in names), + "Native audit file inventory is unavailable or outside its bounded scope") + if DIRECTORY + "/audit.log" not in names: + raise UnsettledInventory("Native audit rotation has not published its active file") + return sorted(names) + + +def parse_events(raw, namespace=None): + require(len(raw.encode()) <= MAX_BYTES, "Native audit snapshot exceeds its bounded size") + unique = {} + for line in raw.splitlines(): + if not line: + continue + event = json.loads(line) + require(isinstance(event, dict), "Native audit contains an invalid record") + if event.get("stage") != "ResponseComplete" or event.get("user", {}).get("username") != ( + f"system:serviceaccount:{BRIDGE}:{WRITER}"): + continue + if namespace is not None and event.get("objectRef", {}).get("namespace") != namespace: + continue + audit_id = event.get("auditID") + require(isinstance(audit_id, str) and AUDIT_ID.fullmatch(audit_id), + "Native audit record omitted a valid request identity") + if audit_id in unique: + require(unique[audit_id] == event, "Native audit contains conflicting records for one request") + unique[audit_id] = event + return list(unique.values()) + + +def read(namespace=None): + for _ in range(3): + try: + before = paths() + raw = command("docker", "exec", CONTROL_PLANE, "cat", *before, timeout=30) + if before != paths(): + continue + return parse_events(raw, namespace) + except (CommandFailure, json.JSONDecodeError, UnsettledInventory): + # Rotation can retire a file between inventory and open. + continue + raise Failure("Native audit snapshot did not settle; no complete event proof is available") + + +def barrier(setup, actor, namespace): + marker = actor.audit_marker(resource(namespace, "karscredentialgrants", "workspace")) + + def observed(): + events = setup.audit(namespace) + matches = [event for event in events if event["auditID"] == marker] + if not matches: + return None + require(len(matches) == 1 and matches[0].get("verb") == "get" + and matches[0].get("objectRef", {}).get("resource") == "karscredentialgrants" + and matches[0]["objectRef"].get("name") == "workspace" + and matches[0].get("responseStatus", {}).get("code") == 200, + "Native audit barrier does not match its actual successful request") + return AuditSnapshot(events, marker) + + return until("actual metadata audit barrier", observed, 30) + + +def changes(before, after): + require(isinstance(before, AuditSnapshot) and isinstance(after, AuditSnapshot) + and before.marker != after.marker, "Native audit interval needs two distinct actual barriers") + ids = {event["auditID"] for event in before} + require(before.marker in ids and any(event["auditID"] == before.marker for event in after), + "Native audit interval lost its starting barrier; event coverage is incomplete") + return [event for event in after if event["auditID"] not in ids] diff --git a/bridge/tests/native-credentials/credential_cases.py b/bridge/tests/native-credentials/credential_cases.py index 57dfa89d..b32d3ac4 100644 --- a/bridge/tests/native-credentials/credential_cases.py +++ b/bridge/tests/native-credentials/credential_cases.py @@ -64,8 +64,8 @@ def paused_team(setup, namespace, name): def changes_since(setup, actor, namespace, before): - ids = {event["auditID"] for event in before} - return [event for event in setup.audit_barrier(actor, namespace) if event["auditID"] not in ids] + from audit_evidence import changes + return changes(before, setup.audit_barrier(actor, namespace)) class CredentialCases: @@ -122,7 +122,8 @@ def bootstrap(self): posts = [event for event in events if event["verb"] == "create" and event.get("objectRef", {}).get("resource") == "secrets" and event.get("responseStatus", {}).get("code") == 201] - require(len(posts) == 1, "Bootstrap did not use one exclusive native source CREATE") + require(len(posts) == 1, + f"Bootstrap requires exactly one native source CREATE; observed {len(posts)} in the complete audit interval") created_at = posts[0]["requestReceivedTimestamp"] gets = [event for event in events if event["verb"] == "get" and event.get("objectRef", {}).get("resource") == "secrets" diff --git a/bridge/tests/native-credentials/native_api.py b/bridge/tests/native-credentials/native_api.py index a2039537..c5281653 100644 --- a/bridge/tests/native-credentials/native_api.py +++ b/bridge/tests/native-credentials/native_api.py @@ -146,7 +146,7 @@ def __init__(self, server, context, token=None): self.server = server def request(self, method, path, body=None, expected=(200,), patch_type=None, *, - accept="application/json", timeout=15): + accept="application/json", timeout=15, audit_ids=None): headers = {"Accept": accept} if self.token: headers["Authorization"] = f"Bearer {self.token}" @@ -165,6 +165,12 @@ def request(self, method, path, body=None, expected=(200,), patch_type=None, *, if response.status not in expected: raise Failure( f"Kubernetes {method} {path.split('?')[0]} returned {response.status} ({status_detail(value)})") + if audit_ids is not None: + audit_id = response.getheader("Audit-Id") + require(isinstance(audit_id, str) and re.fullmatch( + r"[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}", audit_id), + "Actual Kubernetes response omitted a valid audit request identity") + audit_ids.append(audit_id) return response.status, value finally: connection.close() @@ -172,6 +178,11 @@ def request(self, method, path, body=None, expected=(200,), patch_type=None, *, def get(self, path): return self.request("GET", path)[1] + def audit_marker(self, path): + ids = [] + self.request("GET", path, audit_ids=ids) + return ids[0] + def optional(self, path): status, body = self.request("GET", path, expected=(200, 404)) return body if status == 200 else None @@ -246,17 +257,9 @@ def ready(): return until(f"current native grant and writer in {namespace}", ready) def audit(self, namespace=None): - raw = command("docker", "exec", "bridge-native-control-plane", - "cat", "/var/log/kars-native-audit/audit.log") - return [ - event for line in raw.splitlines() if line - for event in [json.loads(line)] - if event.get("stage") == "ResponseComplete" - and event.get("user", {}).get("username") == f"system:serviceaccount:{BRIDGE}:{WRITER}" - and (namespace is None or event.get("objectRef", {}).get("namespace") == namespace) - ] + from audit_evidence import read + return read(namespace) def audit_barrier(self, actor, namespace): - actor.get(resource(namespace, "karscredentialgrants", "workspace")) - time.sleep(1) - return self.audit(namespace) + from audit_evidence import barrier + return barrier(self, actor, namespace) diff --git a/bridge/tests/native-credentials/rollout_diagnostics.py b/bridge/tests/native-credentials/rollout_diagnostics.py new file mode 100644 index 00000000..69e05754 --- /dev/null +++ b/bridge/tests/native-credentials/rollout_diagnostics.py @@ -0,0 +1,222 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +"""Read-only failure evidence, including unready routers; never authorizes a probe.""" + +import json +import re +from urllib.parse import urlencode + +from native_api import CORE, command, core, require, resource +from observation_diagnostics import READ_ERRORS, VERSION, identity, owner +from observer_network_diagnostics import complete_inventory + +UNAVAILABLE = "Native rollout diagnostic unavailable" +REASONS = frozenset(""" +Completed Error OOMKilled ContainerCannotRun StartError CrashLoopBackOff +ImagePullBackOff ErrImagePull CreateContainerConfigError CreateContainerError +RunContainerError ContainerCreating PodInitializing +""".split()) +STARTUP = { + ("kars_inference_router", "kars Inference Router starting"): "starting", + ("kars_inference_router", "Registry topology"): "configuration-loaded", + ("kars_inference_router", "Listening on 0.0.0.0:8443"): "listener-planned", + ("kars_inference_router::service_observation_tls", + "Private observation listener stopped"): "observation-listener-stopped", +} + + +def bounded_integer(value, maximum): + require(type(value) is int and 0 <= value <= maximum, UNAVAILABLE) + return value + + +def container_state(value): + require(isinstance(value, dict) and len(value) <= 1, UNAVAILABLE) + if not value: + return {"phase": "absent"} + phase = next(iter(value)) + require(phase in ("running", "waiting", "terminated") + and isinstance(value[phase], dict), UNAVAILABLE) + state = value[phase] + result = {"phase": phase} + if phase != "running": + result["reason"] = state.get("reason") if state.get("reason") in REASONS else "Other" + if phase == "terminated": + result["exitCode"] = bounded_integer(state.get("exitCode"), 255) + if "signal" in state: + result["signal"] = bounded_integer(state["signal"], 64) + return result + + +def startup_records(raw): + require(isinstance(raw, str) and len(raw.encode()) <= 131072, UNAVAILABLE) + records = [] + error_records = 0 + for line in raw.splitlines()[-512:]: + try: + value = json.loads(line) + except (ValueError, TypeError): + continue + if not isinstance(value, dict) or not isinstance(value.get("fields"), dict): + continue + target, message = value.get("target"), value["fields"].get("message") + if not isinstance(target, str) or not isinstance(message, str): + continue + stage = STARTUP.get((target, message)) + if stage and (not records or records[-1] != stage): + records.append(stage) + if (target == "kars_inference_router" or target.startswith("kars_inference_router::")) \ + and value.get("level") == "ERROR": + error_records += 1 + return {"stages": records[-16:], "errorRecords": error_records, + "coverage": "bounded-process-log-tail", + "listenerReachabilityProved": False} + + +def read_logs(namespace, name, previous=False): + try: + raw = command("kubectl", "logs", "-n", namespace, name, "-c", "inference-router", + "--tail=512", "--limit-bytes=131072", "--request-timeout=10s", + *(["--previous"] if previous else []), timeout=15) + return {"available": True, **startup_records(raw)} + except READ_ERRORS: + return {"available": False, "category": "log-read-unavailable"} + + +def event_records(events, namespace, name, pod_uid): + records = [] + for event in complete_inventory(events, 128): + require(isinstance(event, dict), UNAVAILABLE) + ref, source = event.get("involvedObject", {}), event.get("source", {}) + require(isinstance(ref, dict) and isinstance(source, dict), UNAVAILABLE) + if (ref.get("kind") != "Pod" or ref.get("apiVersion") != "v1" + or ref.get("namespace") != namespace or ref.get("name") != name + or ref.get("uid") != pod_uid + or ref.get("fieldPath") != "spec.containers{inference-router}" + or source.get("component") != "kubelet"): + continue + message = event.get("message") + if event.get("reason") != "Unhealthy" or not isinstance(message, str): + continue + match = re.fullmatch(r"(Readiness|Liveness|Startup) probe (failed|errored): ([\s\S]*)", message) + if match is None: + continue + probe, outcome, detail = match.groups() + category = "other" + code = re.fullmatch(r"HTTP probe failed with statuscode: ([1-5][0-9]{2})", detail) + if code: + category = "http-response" + elif "connection refused" in detail: + category = "connection-refused" + elif any(text in detail for text in ( + "context deadline exceeded", "Client.Timeout", "i/o timeout")): + category = "timeout" + record = {"probe": probe.lower(), "outcome": outcome, "category": category, + "httpStatus": int(code[1]) if code else 0} + if record not in records: + records.append(record) + return {"coverage": "pod-lifetime-events-not-current-process", + "records": records[:24]} + + +def collect(setup, target): + result = {"diagnosticOnly": True, "available": False, "category": "target-unavailable"} + anchors = {} + try: + require(isinstance(target, dict) and target.get("workspace") == CORE + and isinstance(target.get("uid"), str) and target["uid"] + and isinstance(target.get("sandbox"), str) + and re.fullmatch(r"[a-z0-9][-a-z0-9]{0,62}", target["sandbox"]), UNAVAILABLE) + name, namespace = target["sandbox"], "kars-" + target["sandbox"] + + def read(path): + value = setup.admin.get(path) + identity(value) + if path in anchors: + require(identity(value) == identity(anchors[path]), UNAVAILABLE) + else: + anchors[path] = value + return value + + result["category"] = "authority-unavailable" + sandbox = read(resource(CORE, "karssandboxes", name)) + observed = sandbox.get("status", {}).get("serviceObservation", {}) + require(identity(sandbox)[0] == target["uid"] and isinstance(observed, dict) + and sandbox["metadata"].get("name") == name + and sandbox["metadata"].get("namespace") == CORE + and observed.get("phase") in ("Prepared", "Ready") + and isinstance(observed.get("version"), str) and observed["version"], UNAVAILABLE) + ns = read("/api/v1/namespaces/" + namespace) + deployment = read(resource(namespace, "deployments", name, "/apis/apps/v1")) + require(ns["metadata"].get("name") == namespace + and identity(ns)[0] == observed.get("namespaceUid") + and deployment["metadata"].get("namespace") == namespace + and deployment["metadata"].get("name") == name + and identity(deployment)[0] == observed.get("deploymentUid"), UNAVAILABLE) + template = deployment["spec"]["template"] + require(template["spec"].get("serviceAccountName") == "sandbox" + and template["metadata"]["labels"].get("kars.azure.com/sandbox") == name, UNAVAILABLE) + result["category"] = "consumer-unavailable" + pods = [] + candidates = [pod for pod in complete_inventory(setup.admin.get(core(namespace, "pods")), 32) + if pod["metadata"].get("labels", {}).get("kars.azure.com/sandbox") == name + and pod["metadata"].get("namespace") == namespace] + require(0 < len(candidates) <= 8, UNAVAILABLE) + for candidate in candidates: + require(candidate.get("kind") == "Pod" and candidate["spec"].get("serviceAccountName") == "sandbox", + UNAVAILABLE) + ref = owner(candidate, "ReplicaSet") + require(ref is not None, UNAVAILABLE) + replica = read(resource(namespace, "replicasets", ref["name"], "/apis/apps/v1")) + lineage = owner(replica, "Deployment") + require(identity(replica)[0] == ref["uid"] and lineage is not None + and replica["metadata"].get("namespace") == namespace + and replica["metadata"].get("name") == ref["name"] + and lineage["name"] == name and lineage["uid"] == identity(deployment)[0], + UNAVAILABLE) + pod_name = candidate["metadata"]["name"] + require(re.fullmatch(r"[a-z0-9][-a-z0-9]{0,252}", pod_name) is not None, UNAVAILABLE) + pod = read(core(namespace, "pods", pod_name)) + require(identity(pod) == identity(candidate), UNAVAILABLE) + statuses = [item for item in pod.get("status", {}).get("containerStatuses", []) + if item.get("name") == "inference-router"] + require(len(statuses) == 1, UNAVAILABLE) + status = statuses[0] + require(type(status.get("ready")) is bool, UNAVAILABLE) + restarts = bounded_integer(status.get("restartCount"), 1000000) + state = container_state(status.get("state", {})) + entry = { + "routerReady": status["ready"], "restartCount": restarts, + "state": state, "lastState": container_state(status.get("lastState", {})), + "observerVersionMatchesStatus": + pod["metadata"].get("annotations", {}).get(VERSION) == observed["version"], + "observerVersionMatchesTemplate": + pod["metadata"].get("annotations", {}).get(VERSION) + == template["metadata"].get("annotations", {}).get(VERSION), + "logs": {"available": False, "category": "no-running-process"}, + "previousLogs": {"available": False, "category": "no-previous-process"}, + } + if state["phase"] == "running" and isinstance(status.get("containerID"), str) and status["containerID"]: + entry["logs"] = read_logs(namespace, pod_name) + if restarts > 0 and entry["lastState"]["phase"] == "terminated": + entry["previousLogs"] = read_logs(namespace, pod_name, previous=True) + try: + events = setup.admin.get(core(namespace, "events") + "?" + urlencode({ + "fieldSelector": "involvedObject.uid=" + identity(pod)[0]})) + entry["probeEvents"] = { + "available": True, **event_records(events, namespace, pod_name, identity(pod)[0])} + except READ_ERRORS: + entry["probeEvents"] = {"available": False, "category": "event-read-unavailable"} + pods.append(entry) + require(bool(pods), UNAVAILABLE) + result["category"] = "snapshot-changed" + for path, before in anchors.items(): + current = setup.admin.get(path) + require(identity(current) == identity(before), UNAVAILABLE) + if before.get("kind") == "Pod": + require(current.get("status") == before.get("status"), UNAVAILABLE) + result.update(available=True, category="captured", pods=pods) + except READ_ERRORS: + return result + return result diff --git a/bridge/tests/native-credentials/run.py b/bridge/tests/native-credentials/run.py index 6f71f7fc..3e8ab50c 100644 --- a/bridge/tests/native-credentials/run.py +++ b/bridge/tests/native-credentials/run.py @@ -20,6 +20,7 @@ from observation_diagnostics import collect as observation_diagnostics from observer_network_diagnostics import collect as observer_network_diagnostics from rotation_diagnostics import collect as rotation_diagnostics +from rollout_diagnostics import collect as rollout_diagnostics from template_diagnostics import collect as template_diagnostics @@ -126,6 +127,8 @@ def case(name, operation, allowed=True): setup, observations.observer_target, report["cases"][name], started_at) save() if name == "private-bff-observer-and-fresh-privacy-rpc": + report["cases"][name]["routerRollout"] = rollout_diagnostics( + setup, observations.observer_target) report["cases"][name]["enrollmentTemplateDrift"] = template_diagnostics( setup, observations.enrollment_templates, report["cases"][name]["failure"]) report["cases"][name]["observationReadiness"] = observation_diagnostics( @@ -148,7 +151,8 @@ def case(name, operation, allowed=True): print(json.dumps({"nativeCase": name, **{key: value for key, value in report["cases"][name].items() if key not in ("metadataAtFailure", "observationReadiness", "actorApiOutcomes", "observerApiReachability", - "enrollmentTemplateDrift", "rotationFailureSnapshot")}}), flush=True) + "enrollmentTemplateDrift", "rotationFailureSnapshot", + "routerRollout")}}), flush=True) def passed(name): return report["cases"].get(name, {}).get("result") == "passed" diff --git a/bridge/tests/native-credentials/template_diagnostics.py b/bridge/tests/native-credentials/template_diagnostics.py index 6142235c..a64fb3b1 100644 --- a/bridge/tests/native-credentials/template_diagnostics.py +++ b/bridge/tests/native-credentials/template_diagnostics.py @@ -12,6 +12,14 @@ ACTORS = ("runtime", "controller", "bff") LIMIT = 2 * 1024 * 1024 UNAVAILABLE = "Native template comparison unavailable" +ANNOTATION_GROUPS = { + "privateEpochChanged": "kars.azure.com/private-epoch", + "servicesCredentialVersionChanged": "kars.azure.com/services-credential-version", + "credentialProjectionVersionChanged": "kars.azure.com/credential-projection-version", + "inferenceProvidersVersionChanged": "kars.azure.com/inference-providers-version", +} +RETIREMENT = "kars.azure.com/private-root-retirement" +PHASES = ("Pausing", "Retired", "Rotating", "Restoring", "Qualified") HASH_SCRIPT = """ import {readFileSync} from 'node:fs'; import {pathToFileURL} from 'node:url'; @@ -104,6 +112,18 @@ def project(before, current, review, before_digest, current_digest): } for key in ("labels", "annotations"): result[key + "Changed"] = encoded(baseline["metadata"].get(key)) != encoded(actual["metadata"].get(key)) + before_annotations = baseline["metadata"].get("annotations") + current_annotations = actual["metadata"].get("annotations") + require(all(value is None or isinstance(value, dict) + for value in (before_annotations, current_annotations)), UNAVAILABLE) + before_annotations = before_annotations or {} + current_annotations = current_annotations or {} + for label, key in ANNOTATION_GROUPS.items(): + result[label] = encoded(before_annotations.get(key)) != encoded(current_annotations.get(key)) + known = set(ANNOTATION_GROUPS.values()) + result["otherAnnotationsChanged"] = encoded({ + key: value for key, value in before_annotations.items() if key not in known + }) != encoded({key: value for key, value in current_annotations.items() if key not in known}) sections = ("containers", "initContainers", "volumes", "securityContext", "serviceAccountName") for key in sections: result[key + "Changed"] = encoded(baseline["spec"].get(key)) != encoded(actual["spec"].get(key)) @@ -114,6 +134,50 @@ def project(before, current, review, before_digest, current_digest): return result +def late_retirement(setup, scopes, runtime, current_digest): + """Report a stable receipt's phase/comparison, never claim to verify authority.""" + result = {"available": False, "category": "provenance-or-receipt-unavailable"} + try: + namespace, _, deployment_uid = identity(runtime) + matches = [scope for scope in scopes if scope["namespace"].get("name") == namespace] + require(len(matches) == 1 and isinstance(matches[0]["namespace"].get("uid"), str) + and matches[0]["namespace"]["uid"], UNAVAILABLE) + value = setup.admin.get("/api/v1/namespaces/" + namespace) + require(isinstance(value, dict) and isinstance(value.get("metadata"), dict), UNAVAILABLE) + meta = value.get("metadata", {}) + require(meta.get("name") == namespace and meta.get("uid") == matches[0]["namespace"]["uid"] + and isinstance(meta.get("resourceVersion"), str) and meta["resourceVersion"], UNAVAILABLE) + fields = meta.get("annotations") + require(fields is None or isinstance(fields, dict), UNAVAILABLE) + raw = (fields or {}).get(RETIREMENT) + if raw is None: + result = {"available": False, "category": "absent"} + else: + require(isinstance(raw, str) and len(raw.encode()) <= 131_072, UNAVAILABLE) + state = json.loads(raw) + require(isinstance(state, dict) and type(state.get("version")) is int + and state["version"] == 4 and state.get("phase") in PHASES + and isinstance(state.get("deployment"), dict), UNAVAILABLE) + result = { + "available": True, "reportedPhase": state["phase"], + "recordedDeploymentMatches": state["deployment"].get("uid") == deployment_uid, + "qualifiedTemplateRecorded": state.get("qualified") is not None, + "authorityVerified": False, + } + if result["qualifiedTemplateRecorded"]: + require(isinstance(state["qualified"], dict), UNAVAILABLE) + expected = state["qualified"].get("template") + require(isinstance(expected, str) and re.fullmatch(r"[a-f0-9]{64}", expected), UNAVAILABLE) + result["currentMatchesRecordedTemplate"] = current_digest == expected + again = setup.admin.get("/api/v1/namespaces/" + namespace) + require(isinstance(again, dict) and isinstance(again.get("metadata"), dict), UNAVAILABLE) + require(again["metadata"].get("uid") == meta["uid"] + and again["metadata"].get("resourceVersion") == meta["resourceVersion"], UNAVAILABLE) + return result + except READ_ERRORS: + return {"available": False, "category": "provenance-or-receipt-unavailable"} + + def collect(setup, baselines, failure): result = {"diagnosticOnly": True, "available": False, "category": "not-eligible"} if not isinstance(failure, str) or not any(failure.startswith(f"Native operator apply failed: {category} ") @@ -144,6 +208,8 @@ def collect(setup, baselines, failure): for consumer in scope["consumers"]) for scope in scopes), UNAVAILABLE) selected = [scope for scope in scopes if scope["namespace"]["name"] in namespaces] comparisons = {} + current_runtime = None + runtime_digest = None for actor in ACTORS: before = baselines[actor] namespace, name, uid = identity(before) @@ -159,7 +225,10 @@ def collect(setup, baselines, failure): and rechecked["metadata"]["resourceVersion"] == current["metadata"]["resourceVersion"], UNAVAILABLE) comparisons[actor] = project(before, current, matches[0], before_hash, current_hash) + if actor == "runtime": + current_runtime, runtime_digest = current, current_hash result.update(available=True, category="compared", actors=comparisons) + result["lateRetirement"] = late_retirement(setup, selected, current_runtime, runtime_digest) except READ_ERRORS: result["category"] = "provenance-or-comparison-unavailable" return result diff --git a/bridge/tests/native-credentials/test_audit_evidence.py b/bridge/tests/native-credentials/test_audit_evidence.py new file mode 100644 index 00000000..cda4918d --- /dev/null +++ b/bridge/tests/native-credentials/test_audit_evidence.py @@ -0,0 +1,127 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import copy +import json +import ssl +from types import SimpleNamespace +import unittest +from unittest.mock import Mock, patch + +import audit_evidence as audit +from native_api import Api, CommandFailure, Failure + + +def identifier(number): + return f"00000000-0000-4000-8000-{number:012d}" + + +def event(number, verb="get", resource="karscredentialgrants", code=200): + return {"auditID": identifier(number), "stage": "ResponseComplete", "verb": verb, + "user": {"username": f"system:serviceaccount:{audit.BRIDGE}:{audit.WRITER}"}, + "objectRef": {"namespace": "work", "resource": resource, "name": "workspace"}, + "responseStatus": {"code": code}} + + +class AuditEvidenceTests(unittest.TestCase): + def test_retained_rotation_file_is_read_and_duplicate_snapshot_records_are_not_double_counted(self): + old = audit.DIRECTORY + "/audit-2026-09-16T10-30-00.001.log" + active = audit.DIRECTORY + "/audit.log" + created = event(1, "create", "secrets", 201) + raw = "\n".join(json.dumps(value) for value in [created, created, event(2)]) + with patch.object(audit, "paths", return_value=[old, active]), \ + patch.object(audit, "command", return_value=raw) as command: + values = audit.read("work") + self.assertEqual(values, [created, event(2)]) + command.assert_called_once_with("docker", "exec", audit.CONTROL_PLANE, + "cat", old, active, timeout=30) + + def test_changed_rotation_inventory_retries_instead_of_returning_partial_coverage(self): + active = audit.DIRECTORY + "/audit.log" + first = [audit.DIRECTORY + "/audit-2026-09-16T10-30-00.001.log", active] + second = [audit.DIRECTORY + "/audit-2026-09-16T10-31-00.001.log", active] + with patch.object(audit, "paths", side_effect=[first, second, second, second]), \ + patch.object(audit, "command", side_effect=[json.dumps(event(1)), json.dumps(event(2))]): + self.assertEqual(audit.read("work"), [event(2)]) + + def test_rename_recreate_gap_retries_without_relaxing_path_validation(self): + old = audit.DIRECTORY + "/audit-2026-09-16T10-30-00.001.log" + healthy = old + "\n" + audit.DIRECTORY + "/audit.log" + with patch.object(audit, "command", side_effect=[ + old, healthy, json.dumps(event(1)), healthy, + ]) as command: + self.assertEqual(audit.read("work"), [event(1)]) + self.assertEqual(command.call_count, 4) + with patch.object(audit, "command", return_value=old), \ + self.assertRaisesRegex(Failure, "did not settle"): + audit.read("work") + + def test_distinct_creates_are_retained_and_conflicting_duplicate_ids_are_refused(self): + one, two = event(1, "create", "secrets", 201), event(2, "create", "secrets", 201) + self.assertEqual(len(audit.parse_events(json.dumps(one) + "\n" + json.dumps(two), "work")), 2) + bad = copy.deepcopy(one) + bad["responseStatus"]["code"] = 403 + with self.assertRaisesRegex(Failure, "conflicting"): + audit.parse_events(json.dumps(one) + "\n" + json.dumps(bad), "work") + + def test_scope_filtering_and_bounded_inventory_fail_closed(self): + other = event(1) + other["objectRef"]["namespace"] = "other" + self.assertEqual(audit.parse_events(json.dumps(other), "work"), []) + with patch.object(audit, "MAX_BYTES", 1), self.assertRaises(Failure): + audit.parse_events(json.dumps(event(1)), "work") + for paths in ("", audit.DIRECTORY + "/audit-private.log", "/elsewhere/audit.log"): + with patch.object(audit, "command", return_value=paths), self.assertRaises(Failure): + audit.paths() + with patch.object(audit, "command", side_effect=CommandFailure("docker", 1, "private")), \ + self.assertRaisesRegex(Failure, "did not settle"): + audit.read("work") + + def test_barrier_waits_for_its_exact_successful_response_complete_event(self): + marker = identifier(3) + actor = SimpleNamespace(audit_marker=Mock(return_value=marker)) + setup = SimpleNamespace(audit=Mock(side_effect=[[], [event(2), event(3)]])) + + def wait(description, check, timeout): + self.assertEqual(timeout, 30) + self.assertIsNone(check()) + return check() + + with patch.object(audit, "until", side_effect=wait): + result = audit.barrier(setup, actor, "work") + self.assertIsInstance(result, audit.AuditSnapshot) + self.assertEqual(result.marker, marker) + self.assertEqual(len(result), 2) + + def test_barrier_rejects_wrong_response_and_interval_requires_retained_start(self): + actor = SimpleNamespace(audit_marker=lambda path: identifier(1)) + setup = SimpleNamespace(audit=lambda namespace: [event(1, code=403)]) + with patch.object(audit, "until", side_effect=lambda description, check, timeout: check()), \ + self.assertRaisesRegex(Failure, "barrier"): + audit.barrier(setup, actor, "work") + before = audit.AuditSnapshot([event(1)], identifier(1)) + after = audit.AuditSnapshot([event(1), event(2), event(3)], identifier(3)) + self.assertEqual(audit.changes(before, after), [event(2), event(3)]) + with self.assertRaisesRegex(Failure, "starting barrier"): + audit.changes(before, audit.AuditSnapshot([event(3)], identifier(3))) + with self.assertRaisesRegex(Failure, "distinct"): + audit.changes(before, before) + + def test_actual_api_client_reads_the_server_audit_header_without_changing_its_return_contract(self): + response = Mock(status=200) + response.read.return_value = b'{"metadata":{"name":"workspace"}}' + response.getheader.return_value = identifier(7) + connection = Mock() + connection.getresponse.return_value = response + with patch("native_api.http.client.HTTPSConnection", return_value=connection): + api = Api("https://127.0.0.1:6443", ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)) + self.assertEqual(api.audit_marker("/fixture"), identifier(7)) + self.assertEqual(api.get("/fixture"), {"metadata": {"name": "workspace"}}) + response.getheader.return_value = "private-invalid-audit-header" + with self.assertRaisesRegex(Failure, "audit request identity") as failure: + api.audit_marker("/fixture") + self.assertNotIn("private-invalid", str(failure.exception)) + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/tests/native-credentials/test_rollout_diagnostics.py b/bridge/tests/native-credentials/test_rollout_diagnostics.py new file mode 100644 index 00000000..f0715371 --- /dev/null +++ b/bridge/tests/native-credentials/test_rollout_diagnostics.py @@ -0,0 +1,231 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import copy +import json +from types import SimpleNamespace +import unittest +from unittest.mock import patch + +from native_api import Failure +from observation_diagnostics import VERSION +from rollout_diagnostics import collect, container_state, event_records, startup_records +from test_observation_diagnostics import DEPLOYMENT, POD, REPLICA_SET, RUNTIME, SANDBOX, TARGET, Fixture + + +def event(**changes): + value = { + "involvedObject": {"kind": "Pod", "apiVersion": "v1", "namespace": RUNTIME, + "name": "agent-pod", "uid": "agent-pod-uid", + "fieldPath": "spec.containers{inference-router}"}, + "source": {"component": "kubelet"}, "reason": "Unhealthy", + "message": 'Readiness probe failed: Get "http://private-canary": connection refused', + } + value.update(changes) + return value + + +class RolloutFixture(Fixture): + def __init__(self): + super().__init__() + self.events = [event()] + self.objects[POD]["status"] = {"containerStatuses": [{ + "name": "inference-router", "ready": False, "restartCount": 3, + "containerID": "containerd://private-canary", "state": {"running": {"startedAt": "private-canary"}}, + "lastState": {"terminated": {"reason": "OOMKilled", "exitCode": 137, "signal": 9, + "message": "private-canary"}}, + }]} + + def get(self, path): + if "/events?" in path: + return {"items": copy.deepcopy(self.events)} + return super().get(path) + + +def log(message="kars Inference Router starting", **changes): + return json.dumps({"target": "kars_inference_router", "level": "INFO", + "fields": {"message": message, "token": "private-canary"}, **changes}) + + +class RolloutDiagnosticsTests(unittest.TestCase): + def capture(self, fixture=None, side_effect=None): + fixture = fixture or RolloutFixture() + with patch("rollout_diagnostics.command", return_value=log(), side_effect=side_effect) as call: + value = collect(SimpleNamespace(admin=fixture), {**TARGET, "uid": "sandbox-uid"}) + return value, call + + def test_unready_router_has_bounded_process_and_probe_evidence(self): + value, call = self.capture() + self.assertTrue(value["available"]) + self.assertTrue(value["diagnosticOnly"]) + pod = value["pods"][0] + self.assertFalse(pod["routerReady"]) + self.assertEqual(pod["restartCount"], 3) + self.assertEqual(pod["lastState"], {"phase": "terminated", "reason": "OOMKilled", + "exitCode": 137, "signal": 9}) + self.assertEqual(pod["logs"]["stages"], ["starting"]) + self.assertFalse(pod["logs"]["listenerReachabilityProved"]) + self.assertEqual(pod["probeEvents"]["records"], + [{"probe": "readiness", "outcome": "failed", + "category": "connection-refused", "httpStatus": 0}]) + self.assertNotIn("private-canary", json.dumps(value)) + self.assertEqual(call.call_count, 2) + self.assertIn("--limit-bytes=131072", call.call_args.args) + self.assertIn("--previous", call.call_args.args) + + def test_stale_observer_version_is_reported_not_treated_as_current_authority(self): + fixture = RolloutFixture() + fixture.objects[POD]["metadata"]["annotations"][VERSION] = "old:1" + value, _ = self.capture(fixture) + self.assertTrue(value["available"]) + self.assertFalse(value["pods"][0]["observerVersionMatchesStatus"]) + self.assertFalse(value["pods"][0]["observerVersionMatchesTemplate"]) + self.assertTrue(value["diagnosticOnly"]) + + def test_waiting_container_reads_only_its_previous_process_logs(self): + fixture = RolloutFixture() + fixture.objects[POD]["status"]["containerStatuses"][0]["state"] = { + "waiting": {"reason": "CrashLoopBackOff", "message": "private-canary"}} + value, call = self.capture(fixture) + self.assertTrue(value["available"]) + self.assertEqual(value["pods"][0]["state"]["phase"], "waiting") + self.assertFalse(value["pods"][0]["logs"]["available"]) + self.assertTrue(value["pods"][0]["previousLogs"]["available"]) + self.assertEqual(call.call_count, 1) + self.assertIn("--previous", call.call_args.args) + + def test_fixed_startup_markers_do_not_claim_bound_listener(self): + raw = "\n".join([log(), log("Registry topology"), log("Listening on 0.0.0.0:8443"), + log("unknown-private-canary", level="ERROR"), "Error: private-canary", + log([], level="ERROR"), "[]"]) + value = startup_records(raw) + self.assertEqual(value["stages"], ["starting", "configuration-loaded", "listener-planned"]) + self.assertEqual(value["errorRecords"], 1) + self.assertFalse(value["listenerReachabilityProved"]) + self.assertNotIn("canary", json.dumps(value)) + with self.assertRaises(Failure): + startup_records("x" * 131073) + + def test_probe_events_remain_pod_lifetime_and_foreign_events_are_ignored(self): + records = [event(), event(message="Liveness probe failed: HTTP probe failed with statuscode: 503"), + event(message="Startup probe failed: private-canary context deadline exceeded"), + event(message="Readiness probe failed: private-canary"), + event(message="Readiness probe errored: private-canary"), + event(involvedObject={"uid": "foreign"}), + event(source={"component": "private-canary"}), + event(involvedObject={**event()["involvedObject"], + "fieldPath": "spec.containers{openclaw}"})] + value = event_records({"items": records}, RUNTIME, "agent-pod", "agent-pod-uid") + self.assertEqual(value["coverage"], "pod-lifetime-events-not-current-process") + self.assertEqual([item["category"] for item in value["records"]], + ["connection-refused", "http-response", "timeout", "other", "other"]) + self.assertEqual(value["records"][1]["httpStatus"], 503) + self.assertEqual(value["records"][-1]["outcome"], "errored") + self.assertNotIn("canary", json.dumps(value)) + for metadata in ({"continue": "more"}, {"remainingItemCount": 1}): + with self.assertRaises(Failure): + event_records({"metadata": metadata, "items": records}, RUNTIME, "agent-pod", "agent-pod-uid") + + def test_changed_identity_revision_or_process_discards_projection(self): + for path in (SANDBOX, DEPLOYMENT, REPLICA_SET, POD): + for field in ("uid", "resourceVersion"): + with self.subTest(path=path, field=field): + fixture = RolloutFixture() + + def changed(*args, **kwargs): + fixture.objects[path]["metadata"][field] = "changed" + return log() + + value, _ = self.capture(fixture, changed) + self.assertFalse(value["available"]) + self.assertNotIn("pods", value) + fixture = RolloutFixture() + + def restarted(*args, **kwargs): + fixture.objects[POD]["status"]["containerStatuses"][0]["restartCount"] += 1 + return log() + + value, _ = self.capture(fixture, restarted) + self.assertFalse(value["available"]) + self.assertNotIn("pods", value) + + def test_foreign_or_incomplete_authority_never_reads_logs(self): + for path, change in ( + (SANDBOX, lambda item: item["metadata"].update(uid="foreign")), + (DEPLOYMENT, lambda item: item["metadata"].update(uid="foreign")), + (REPLICA_SET, lambda item: item["metadata"]["ownerReferences"][0].update(uid="foreign")), + (POD, lambda item: item["metadata"].update(deletionTimestamp="terminating")), + ): + with self.subTest(path=path): + fixture = RolloutFixture() + change(fixture.objects[path]) + value, call = self.capture(fixture) + self.assertFalse(value["available"]) + call.assert_not_called() + + def test_shared_replicaset_retains_its_first_snapshot_across_pods(self): + for changed_field in (None, "uid", "resourceVersion"): + with self.subTest(changed_field=changed_field): + fixture = RolloutFixture() + second = copy.deepcopy(fixture.objects[POD]) + second["metadata"].update(name="agent-pod-2", uid="agent-pod-2-uid") + fixture.objects[POD + "-2"] = second + original = fixture.get + replica_reads = 0 + + def changing(path): + nonlocal replica_reads + if path == REPLICA_SET: + replica_reads += 1 + if replica_reads == 2 and changed_field: + fixture.objects[path]["metadata"][changed_field] = "changed-private-canary" + return original(path) + + fixture.get = changing + value, _ = self.capture(fixture) + self.assertEqual(value["available"], changed_field is None) + if changed_field is None: + self.assertEqual(len(value["pods"]), 2) + self.assertEqual(replica_reads, 3) + else: + self.assertNotIn("pods", value) + self.assertEqual(replica_reads, 2) + self.assertNotIn("canary", json.dumps(value)) + + def test_errors_are_explicit_and_value_free(self): + value, _ = self.capture(side_effect=OSError("private-canary")) + self.assertTrue(value["available"]) + self.assertFalse(value["pods"][0]["logs"]["available"]) + self.assertFalse(value["pods"][0]["previousLogs"]["available"]) + self.assertEqual(value["pods"][0]["logs"]["category"], "log-read-unavailable") + self.assertNotIn("canary", json.dumps(value)) + + def test_event_read_error_preserves_stable_process_evidence(self): + fixture = RolloutFixture() + original = fixture.get + + def failing(path): + if "/events?" in path: + raise OSError("private-canary") + return original(path) + + fixture.get = failing + value, _ = self.capture(fixture) + self.assertTrue(value["available"]) + self.assertTrue(value["pods"][0]["logs"]["available"]) + self.assertEqual(value["pods"][0]["probeEvents"], + {"available": False, "category": "event-read-unavailable"}) + self.assertNotIn("canary", json.dumps(value)) + + def test_state_types_and_values_are_bounded(self): + for value in ({"terminated": {"exitCode": True}}, {"terminated": {"exitCode": 256}}, + {"running": {}, "waiting": {}}, {"private-canary": {}}, []): + with self.subTest(value=value): + with self.assertRaises(Failure): + container_state(value) + self.assertEqual(container_state({"waiting": {"reason": "private-canary"}}), + {"phase": "waiting", "reason": "Other"}) + + +if __name__ == "__main__": + unittest.main() diff --git a/bridge/tests/native-credentials/test_template_diagnostics.py b/bridge/tests/native-credentials/test_template_diagnostics.py index 064785f3..2f075eeb 100644 --- a/bridge/tests/native-credentials/test_template_diagnostics.py +++ b/bridge/tests/native-credentials/test_template_diagnostics.py @@ -88,6 +88,24 @@ def test_section_comparisons_preserve_types_and_cover_other_pod_fields(self): with self.assertRaises(Failure): diagnostics.project(value, current, review(before), "a" * 64, "b" * 64) + def test_annotation_groups_retain_only_fixed_booleans_including_unknown_changes(self): + before = deployment("runtime") + for label, key in diagnostics.ANNOTATION_GROUPS.items(): + current = copy.deepcopy(before) + current["spec"]["template"]["metadata"]["annotations"] = {key: PRIVATE} + facts = diagnostics.project(before, current, review(before), *fixture_hashes([before, current])) + self.assertTrue(facts[label]) + self.assertTrue(facts["annotationsChanged"]) + self.assertFalse(facts["otherAnnotationsChanged"]) + self.assertTrue(all(type(value) is bool for value in facts.values())) + self.assertNotIn(PRIVATE, json.dumps(facts)) + self.assertNotIn(key, json.dumps(facts)) + current["spec"]["template"]["metadata"]["annotations"] = {PRIVATE: PRIVATE} + facts = diagnostics.project(before, current, review(before), *fixture_hashes([before, current])) + self.assertTrue(facts["otherAnnotationsChanged"]) + self.assertTrue(all(not facts[key] for key in diagnostics.ANNOTATION_GROUPS)) + self.assertNotIn(PRIVATE, json.dumps(facts)) + def test_wrong_namespaces_owners_and_review_shapes_are_refused(self): before = deployment("runtime") for key in ("namespace", "name"): @@ -100,12 +118,14 @@ def test_wrong_namespaces_owners_and_review_shapes_are_refused(self): with self.assertRaises(Failure): diagnostics.project(before, before, invalid, "a" * 64, "b" * 64) - def collect(self, *, mutate_review=None, changed_on_recheck=False, unavailable_hashes=False, failure=FAILURE): + def collect(self, *, mutate_review=None, changed_on_recheck=False, unavailable_hashes=False, + failure=FAILURE, receipt=None, namespace_changed=False): baselines = {actor: deployment(actor) for actor in diagnostics.ACTORS} document = {"apiVersion": "kars.azure.com/v1alpha1", "kind": "KarsCredentialGrant", "metadata": {"name": "workspace", "namespace": "kars-system"}, "spec": {"privateActivation": {"phase": "reviewed", "namespaces": [ - {"namespace": {"name": "work"}, "consumers": [review(value) for value in baselines.values()]} + {"namespace": {"name": "work", "uid": "work-uid"}, + "consumers": [review(value) for value in baselines.values()]} ]}}} if mutate_review: mutate_review(document) @@ -113,6 +133,10 @@ def collect(self, *, mutate_review=None, changed_on_recheck=False, unavailable_h def get(path): reads.append(path) + if path == "/api/v1/namespaces/work": + return {"metadata": {"name": "work", "uid": "work-uid", + "resourceVersion": "2" if namespace_changed and reads.count(path) == 2 else "1", + "annotations": {} if receipt is None else {diagnostics.RETIREMENT: json.dumps(receipt)}}} value = copy.deepcopy(baselines[path.rsplit("/", 1)[-1]]) if changed_on_recheck and len(reads) % 2 == 0: value["metadata"]["resourceVersion"] = "2" @@ -138,13 +162,39 @@ def test_complete_collector_rechecks_all_three_exact_deployments(self): self.assertTrue(result["available"]) self.assertTrue(result["diagnosticOnly"]) self.assertEqual(set(result["actors"]), set(diagnostics.ACTORS)) - self.assertEqual(len(reads), 6) + self.assertEqual(len(reads), 8) self.assertTrue(all(value["currentMatchesReview"] for value in result["actors"].values())) + self.assertEqual(result["lateRetirement"], {"available": False, "category": "absent"}) def test_writer_restoration_refusal_also_gets_value_free_template_comparisons(self): result, reads = self.collect(failure="Native operator apply failed: writer-runtime-transition (source=unavailable)") self.assertTrue(result["available"]) - self.assertEqual(len(reads), 6) + self.assertEqual(len(reads), 8) + + def test_stable_late_receipt_reports_phase_and_comparison_without_publishing_hashes(self): + expected = fixture_hashes([deployment("runtime")])[0] + receipt = {"version": 4, "phase": "Restoring", "deployment": {"uid": "runtime-uid"}, + "qualified": {"template": expected}, "private": PRIVATE} + result, _ = self.collect(receipt=receipt) + facts = result["lateRetirement"] + self.assertEqual(facts, {"available": True, "reportedPhase": "Restoring", + "recordedDeploymentMatches": True, "qualifiedTemplateRecorded": True, + "authorityVerified": False, "currentMatchesRecordedTemplate": True}) + self.assertNotIn(expected, json.dumps(result)) + self.assertNotIn(PRIVATE, json.dumps(result)) + receipt["qualified"]["template"] = "f" * 64 + result, _ = self.collect(receipt=receipt) + self.assertFalse(result["lateRetirement"]["currentMatchesRecordedTemplate"]) + + def test_unstable_or_invalid_receipt_does_not_erase_valid_deployment_comparisons(self): + receipt = {"version": 4, "phase": "Pausing", "deployment": {"uid": "runtime-uid"}} + for options in ({"receipt": receipt, "namespace_changed": True}, + {"receipt": {**receipt, "phase": PRIVATE}}, + {"receipt": {**receipt, "qualified": {"template": PRIVATE}}}): + result, _ = self.collect(**options) + self.assertTrue(result["available"]) + self.assertFalse(result["lateRetirement"]["available"]) + self.assertNotIn(PRIVATE, json.dumps(result)) def test_changed_resource_or_failed_hashing_never_returns_partial_comparisons(self): for options in ({"changed_on_recheck": True}, {"unavailable_hashes": True}): diff --git a/ci/bridge_component_results.py b/ci/bridge_component_results.py index 6ebdab41..bcb85342 100644 --- a/ci/bridge_component_results.py +++ b/ci/bridge_component_results.py @@ -8,7 +8,7 @@ REQUIRED_JOBS = frozenset({ - "addon", "bff", "dependencies", "lockfiles", + "addon", "bff", "dependencies", "idp", "lockfiles", "rust-dependencies", "secrets", "security", "web", }) diff --git a/ci/copyright-coverage.json b/ci/copyright-coverage.json index a855aa91..0c93e7a2 100644 --- a/ci/copyright-coverage.json +++ b/ci/copyright-coverage.json @@ -93,6 +93,136 @@ "reason": "Generated dependency lockfile; no dependency/checksum changes for copyright policy.", "notice": "LICENSE" }, + "bridge/idp/LICENSE": { + "category": "legal", + "reason": "Kars packaging license document; preserve the legal text rather than prepending a source header.", + "notice": "NOTICE" + }, + "bridge/idp/NOTICE": { + "category": "legal", + "reason": "Scoped Dex upstream and Kars patch attribution; preserve original ownership and license distinctions.", + "notice": "NOTICE" + }, + "bridge/idp/locks/inputs.lock": { + "category": "repository-license", + "reason": "Reviewed immutable resolver inputs are copied and checksum-bound in the generated artifact; preserve exact bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/requests.txt": { + "category": "repository-license", + "reason": "Machine-read exact Go module resolution requests; comments would become module arguments and change the verified artifact.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/go.mod": { + "category": "generated", + "reason": "Actual hosted Go resolver output with disclosed Dex dependency patches; preserve the checksum-bound module file.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/go.sum": { + "category": "generated", + "reason": "Actual Go module checksums; do not rewrite generated integrity data for source-header policy.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/api/v2/go.mod": { + "category": "generated", + "reason": "Actual hosted nested API module resolver output; preserve the checksum-bound dependency contract.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/api/v2/go.sum": { + "category": "generated", + "reason": "Actual nested API Go module checksums; preserve original generated bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/upstream/go.mod.snapshot": { + "category": "third-party", + "reason": "Exact pinned upstream Dex module snapshot under Apache-2.0, not Microsoft-authored source.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/upstream/go.sum.snapshot": { + "category": "third-party", + "reason": "Exact pinned upstream Dex dependency checksums retained for comparison and attribution.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/upstream/api/v2/go.mod.snapshot": { + "category": "third-party", + "reason": "Exact pinned upstream Dex API module snapshot; preserve upstream ownership and bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/upstream/api/v2/go.sum.snapshot": { + "category": "third-party", + "reason": "Exact pinned upstream Dex API dependency checksum snapshot; preserve upstream data.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/modules.json": { + "category": "generated", + "reason": "Go-generated selected-module inventory verified against requests and checksums; preserve its machine-readable bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/api-modules.json": { + "category": "generated", + "reason": "Go-generated nested API module inventory; preserve its machine-readable, checksum-bound bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/graph.txt": { + "category": "generated", + "reason": "Actual go mod graph output retained for reproducibility and dependency review.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/toolchain.txt": { + "category": "generated", + "reason": "Actual hosted compiler identity output; comments would invalidate its exact verification contract.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/inputs.lock": { + "category": "generated", + "reason": "Resolver-emitted exact input snapshot, compared byte-for-byte with reviewed inputs.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/requests.txt": { + "category": "generated", + "reason": "Resolver-emitted exact module request snapshot; preserve checksummed data.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/dependencies.patch": { + "category": "generated", + "reason": "Actual resolver diff against pinned Apache-2.0 upstream module files; preserve patch and attribution bytes.", + "notice": "NOTICE" + }, + "bridge/idp/locks/generated/SHA256SUMS": { + "category": "generated", + "reason": "Complete generated artifact integrity inventory; headers must not alter digest verification.", + "notice": "NOTICE" + }, + "bridge/idp/patches/0001-literal-oauth-error-descriptions.patch": { + "category": "third-party", + "reason": "Reviewed narrow diff against pinned Apache-2.0 Dex source with disclosed Kars changes; preserve exact patch bytes and upstream attribution.", + "notice": "NOTICE" + }, + "bridge/idp/patches/0002-saml-fixture-validation-clock.patch": { + "category": "third-party", + "reason": "Reviewed test-only diff against pinned Apache-2.0 Dex fixtures; preserve exact signed-source patch inputs.", + "notice": "NOTICE" + }, + "bridge/idp/patches/SHA256SUMS": { + "category": "repository-license", + "reason": "Reviewed patch integrity inventory, not commentable source; exact bytes bind patch application.", + "notice": "NOTICE" + }, + "bridge/idp/patches/upstream.sha256": { + "category": "repository-license", + "reason": "Pinned pre-patch upstream source identities; preserve exact integrity metadata.", + "notice": "NOTICE" + }, + "bridge/idp/patches/patched.sha256": { + "category": "repository-license", + "reason": "Reviewed post-patch source identities; preserve exact integrity metadata rather than recomputing or rewriting it.", + "notice": "NOTICE" + }, + "bridge/idp/patches/series": { + "category": "repository-license", + "reason": "Ordered machine-read patch names; comments would change the checked patch application sequence.", + "notice": "NOTICE" + }, ".agt-sdk/.keep": { "category": "repository-license", "reason": "Empty directory marker; preserve emptiness.", diff --git a/ci/copyright_headers.py b/ci/copyright_headers.py index a330758e..7c193436 100644 --- a/ci/copyright_headers.py +++ b/ci/copyright_headers.py @@ -31,7 +31,7 @@ "handlebars": f"{{{{!-- {COPYRIGHT}\n{LICENSE} --}}}}", } SUFFIX_STYLES = { - **dict.fromkeys((".rs", ".ts", ".tsx", ".js", ".mjs", ".bicep"), "slash"), + **dict.fromkeys((".rs", ".go", ".ts", ".tsx", ".js", ".mjs", ".bicep"), "slash"), **dict.fromkeys((".sh", ".py", ".toml", ".yaml", ".yml"), "hash"), ".md": "html", ".css": "css", diff --git a/ci/tests/bridge_contracts_test.py b/ci/tests/bridge_contracts_test.py index 74aa7bf7..b6bcad22 100644 --- a/ci/tests/bridge_contracts_test.py +++ b/ci/tests/bridge_contracts_test.py @@ -5,8 +5,11 @@ import json import os from pathlib import Path +import re import runpy import subprocess +import tempfile +import textwrap import unittest from git_fixture import GitFixture @@ -92,13 +95,116 @@ def test_sparse_core_checkout_really_removes_only_bridge(self): class ContractAggregateTests(unittest.TestCase): components = ( - "addon", "bff", "dependencies", "lockfiles", + "addon", "bff", "dependencies", "idp", "lockfiles", "rust-dependencies", "secrets", "security", "web", ) def component_success(self): return {name: {"result": "success"} for name in self.components} + def workflow_job(self, name): + workflow = (CI.parent / ".github/workflows/bridge-ci.yml").read_text() + match = re.search(rf"(?ms)^ {re.escape(name)}:\n(.*?)(?=^ \S|\Z)", workflow) + self.assertIsNotNone(match, name) + return match.group(1) + + def test_idp_is_required_by_the_exact_component_graph(self): + aggregate = self.workflow_job("bridge-required-gates") + needs = re.search(r"(?m)^ needs: \[([^\]]+)\]$", aggregate) + self.assertIsNotNone(needs) + self.assertEqual({name.strip() for name in needs.group(1).split(",")}, set(self.components)) + self.assertIn("idp", self.components) + self.assertIn(" if: always()", aggregate) + self.assertEqual(runpy.run_path(str(CI / "bridge_component_results.py"))["REQUIRED_JOBS"], + frozenset(self.components)) + + def test_idp_job_requires_real_hosted_images_reports_runtime_and_scans(self): + job = self.workflow_job("idp") + self.assertNotIn("runner.", job.split(" steps:", 1)[0]) + self.assertIn('export IDP_EVIDENCE_DIR="$RUNNER_TEMP/bridge-idp-evidence"', job) + self.assertIn('printf \'IDP_EVIDENCE_DIR=%s\\n\' "$IDP_EVIDENCE_DIR" >> "$GITHUB_ENV"', job) + for required in ( + "runs-on: ubuntu-24.04", "permissions:\n contents: read", + 'test "$(uname -m)" = x86_64', "persist-credentials: false", + "KARS_DEX_PATCH_NETWORK=1", 'check_modules("bridge/idp")', + "--target upstream-tests", "--target test-tools", "--target runtime", + "--platform linux/amd64", "--file bridge/idp/Dockerfile bridge/idp", + "docker create kars-bridge-idp-upstream-tests:latest", + 'trap \'docker rm "$container"\' EXIT', + "$container:/out/doc/upstream-tests.json", "$container:/out/doc/api-tests.json", + "aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25", + "version: v0.70.0", "ignore-unfixed: false", "exit-code: '1'", + 'trivy_path="$(command -v trivy)"', 'test -x "$trivy_path"', + "python3 bridge/idp/tests/qualify.py", '--trivy "$trivy_path"', + '--evidence "$IDP_EVIDENCE_DIR/runtime"', + "if: ${{ !cancelled() && steps.idp_runtime.outcome == 'success' }}", + "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a", + "if-no-files-found: error", "runtime-qualification.log", "step-outcomes.json", + ): + self.assertIn(required, job, required) + self.assertNotIn("continue-on-error", job) + self.assertNotIn("|| true", job) + self.assertNotIn(": write", job) + self.assertNotRegex(job, r"\b(docker push|docker login|az acr|kubectl)\b") + self.assertNotIn("secrets.", job) + self.assertGreaterEqual(job.count("if: always()"), 2) + self.assertIn("set -euo pipefail", job) + + def report_summary(self, root_events, api_events): + block = self.workflow_job("idp").split("python3 - <<'PY'\n", 1)[1] + script = textwrap.dedent(block.split("\n PY", 1)[0]) + with tempfile.TemporaryDirectory(prefix="idp-report-contract-") as temporary: + evidence = Path(temporary) + for name, events in (("upstream-tests.json", root_events), ("api-tests.json", api_events)): + (evidence / name).write_text("".join(json.dumps(event) + "\n" for event in events)) + result = subprocess.run( + ["python3", "-c", script], text=True, capture_output=True, timeout=10, + env={**os.environ, "IDP_EVIDENCE_DIR": temporary, + "GITHUB_STEP_SUMMARY": str(evidence / "step-summary.md")}, + ) + summary_file = evidence / "upstream-summary.json" + summary = json.loads(summary_file.read_text()) if summary_file.exists() else None + return result, summary + + def upstream_report_fixtures(self): + root = [ + {"Action": "start", "Package": "example/root"}, + {"Action": "pass", "Package": "example/root", "Test": "TestUnit"}, + {"Action": "skip", "Package": "example/root", "Test": "TestUnconfiguredLDAP"}, + {"Action": "pass", "Package": "example/root"}, + ] + api = [ + {"Action": "start", "Package": "example/api"}, + {"Action": "output", "Package": "example/api", "Output": "[no test files]\n"}, + {"Action": "skip", "Package": "example/api"}, + ] + return root, api + + def test_upstream_summary_discloses_skips_without_inventing_api_tests(self): + result, summary = self.report_summary(*self.upstream_report_fixtures()) + self.assertEqual(result.returncode, 0, result.stderr) + self.assertEqual(summary["root"]["testActions"], {"pass": 1, "skip": 1}) + self.assertEqual(summary["root"]["skipped"], + [{"package": "example/root", "test": "TestUnconfiguredLDAP"}]) + self.assertEqual(summary["api"]["testActions"], {}) + self.assertEqual(summary["api"]["packageActions"], {"skip": 1}) + self.assertIn("not runtime-qualified", summary["coverageLimit"]) + + def test_upstream_summary_rejects_failure_or_incomplete_proof(self): + root, api = self.upstream_report_fixtures() + for root_events, api_events in ( + (root[:-1], api), (root, []), + (root + [{"Action": "fail", "Package": "example/root", "Test": "TestFailure"}], api), + (root, api + [{"Action": "build-fail", "ImportPath": "example/api"}]), + ([{"Action": "start", "Package": "example/root"}, + {"Action": "skip", "Package": "example/root"}], api), + (root + [None], api), + ): + with self.subTest(root=root_events, api=api_events): + result, summary = self.report_summary(root_events, api_events) + self.assertNotEqual(result.returncode, 0) + self.assertIsNone(summary) + def test_component_aggregate_rejects_missing_failed_or_skipped_jobs(self): check = runpy.run_path(str(CI / "bridge_component_results.py"))["require_success"] check(self.component_success()) @@ -125,10 +231,12 @@ def test_component_aggregate_rejects_missing_failed_or_skipped_jobs(self): def test_component_workflow_entrypoint_requires_complete_results(self): partial = self.component_success() del partial["security"] + without_idp = self.component_success() + del without_idp["idp"] environment = {key: value for key, value in os.environ.items() if key != "COMPONENT_RESULTS"} for payload, expected in ((json.dumps(self.component_success()), 0), - (json.dumps(partial), 1), ("not-json", 1), + (json.dumps(partial), 1), (json.dumps(without_idp), 1), ("not-json", 1), ("null", 1), (None, 1)): with self.subTest(payload=payload): result = subprocess.run( diff --git a/ci/tests/copyright_headers_test.py b/ci/tests/copyright_headers_test.py index 8e09b4d2..ea2a3c9c 100644 --- a/ci/tests/copyright_headers_test.py +++ b/ci/tests/copyright_headers_test.py @@ -53,6 +53,7 @@ def apply(self, name, data, expected_offset=None): def test_all_commentable_formats(self): fixtures = { "a.rs": b"//! Crate docs\nfn main() {}\n", + "a.go": b"package fixture\n\nfunc Value() int { return 1 }\n", "a.ts": b"/// \nexport {};\n", "a.tsx": b"'use client';\nexport const A = () =>

;\n", "a.js": b'"use strict";\nconst x = 1;', @@ -101,6 +102,20 @@ def test_shebangs_and_encoding_cookies(self): # declaration; the header must still precede the executable statement. self.apply("a.py", b"x = 1\n# coding: utf-8\n", 0) + def test_dex_integrity_data_has_exact_coverage_without_exempting_source_directories(self): + for name in ("bridge/idp/locks/generated/go.sum", + "bridge/idp/locks/generated/upstream/api/v2/go.mod.snapshot", + "bridge/idp/patches/0001-literal-oauth-error-descriptions.patch", + "bridge/idp/patches/SHA256SUMS"): + rule = headers.classification(name, self.policy) + self.assertNotEqual(rule["category"], "header") + self.assertEqual(rule["notice"], "NOTICE") + for name in ("bridge/idp/scripts/new.go", "bridge/idp/patches/new.go"): + self.assertEqual(headers.classification(name, self.policy), + {"category": "header", "style": "slash"}) + with self.assertRaises(headers.CoverageError): + headers.classification("bridge/idp/locks/generated/unreviewed.lock", self.policy) + def test_bom_crlf_and_no_final_newline(self): for body in ( codecs.BOM_UTF8 + b'"use client";\r\nexport {};', @@ -440,13 +455,20 @@ def test_output_directory_names_never_imply_generated_coverage(self): self.apply(nested, b"export const value = 1;\n", 0) def test_generated_coverage_requires_exact_reviewed_paths(self): - expected = {"tools/headlamp-plugin/dist/main.js", "tools/headlamp-plugin/dist/package.json"} + headlamp = {"tools/headlamp-plugin/dist/main.js", "tools/headlamp-plugin/dist/package.json"} + dex = {"bridge/idp/locks/generated/" + name for name in ( + "go.mod", "go.sum", "api/v2/go.mod", "api/v2/go.sum", "modules.json", + "api-modules.json", "graph.txt", "toolchain.txt", "inputs.lock", "requests.txt", + "dependencies.patch", "SHA256SUMS", + )} + expected = headlamp | dex generated = {p for p, r in self.policy["files"].items() if r["category"] == "generated"} self.assertEqual(generated, expected) for name in expected: rule = headers.classification(name, self.policy) self.assertEqual(rule["notice"], "NOTICE") - self.assertIn("tools/headlamp-plugin/package.json", rule["reason"]) + if name in headlamp: + self.assertIn("tools/headlamp-plugin/package.json", rule["reason"]) for name in ( "tools/headlamp-plugin/dist/authored.ts", "tools/headlamp-plugin/dist/authored.d.ts", diff --git a/docs/security-audits/2026-09-16-curated-dex-runtime.md b/docs/security-audits/2026-09-16-curated-dex-runtime.md new file mode 100644 index 00000000..2ec1dd00 --- /dev/null +++ b/docs/security-audits/2026-09-16-curated-dex-runtime.md @@ -0,0 +1,134 @@ + + +# Curated Dex runtime: bounded delegated source review + +Base: `b413f340d8d41aa3227538deee13569ca62d3981`. +Reviewed source: `f7cc7df8ef1cdfce9d4d92159a4e0ade5153bc1f`. + +Status: **Source-approved for hosted qualification, not runtime publication or +deployment approval.** The final distroless runtime, OIDC/SQLite, linkage and +image-scan job must actually pass before acceptance. + +## T1: New surface and reason for the change + +This is a security rebuild of the existing optional Dex IdP, not a second +authentication framework or a new credential authority. The latest official +stable v2.45.1 image was scanned before use and rejected with 128 High and five +Critical findings. It was not mirrored or deployed. Moving its registry +reference alone would not repair its contents. + +The recipe pins upstream application source at +`11d2eeb52b42e1980e14cb91e69dd9e3faab2076`, its archive hash, the Go 1.26.8 +builder and Microsoft Azure Linux 3 distroless base. Real Go-generated root +and nested API module locks are committed with their source/input, checksum +and module inventories. The normal build uses those locks read-only; it +cannot run the separate dependency-resolution recipe implicitly. + +No configuration, credentials, default issuer or user account ships in the +runtime. The existing chart's direct `dex serve` invocation remains supported. +Unused upstream template-expansion wrappers are not included. CGO and real +SQLite remain enabled; other upstream connector/storage code is retained, +not replaced by stubs. Unconfigured backend integrations remain unqualified. + +## T2: Security-control and compatibility changes + +The dependency selections close the recorded Go/library advisories. A new +advisory can still reject the final image; selection alone is not a clean scan. +Two disclosed production call-site patches use constant `"%s"` formats for +already-formatted OAuth errors rather than disabling vet. A historical SAML +test fixture uses its signed time through the library's test clock. Production +certificate validation and signed fixture bytes remain unchanged. + +Patch application verifies original source, reviewed patch bytes, expected +post-patch files and the complete final source inventory. It does not ignore +changed application files or regenerate expected hashes from arbitrary output. +Git check/apply uses the existing builder toolchain with strict whitespace +checking and no unsafe-path option. + +The shipping filesystem preserves the pinned Microsoft base, its CA trust +and RPM inventory. It adds the application, web assets and explicit source, +dependency and legal notices, not Debian libraries or build tools. Authentic +upstream `LICENCE` files are collected alongside `LICENSE`; missing licenses +still fail rather than being relabeled or skipped. + +The runtime probe verifies the saved, unexpired ID token and its original +key identity against the restarted SQLite-backed server **before** refresh. +It rejects lost/replaced keys, including reuse of a key ID, while permitting +rotation that retains the previous verification key. Existing refresh, +userinfo, nonce, issuer, audience and negative authentication checks remain. +Test credentials stay in private ephemeral fixtures, not shipping layers. + +## T3: Qualification and retained limits + +Actual no-push hosted generation produced the committed Go lock artifact. +Its transport/member hashes, source inputs, toolchain and selected graph were +verified on import. Actual hosted execution subsequently passed the focused +compatibility tests, upstream root/API race-suite commands, nine signing-key +continuity scenarios and probe compilation. The upstream reports were retained +in the test image; successful command exit is not an invented test count or +proof of skipped external-service integrations. + +Earlier failures remain recorded: a license filename was not recognized; +newer vet checks rejected two call sites; a historical signed fixture expired; +and the builder lacked the first selected patch utility. Each was corrected +without changing an enforcement expectation or disabling security checks. + +Twenty pinned-source application/integrity regressions passed with zero skips. +The parent also checked CI aggregate/report contracts and precise licensing +classification. Go wrappers use normal source headers; only enumerated legal, +generated integrity and upstream snapshot files have non-header coverage. +Unknown source files in those directories remain checked. Literal unified-diff +context whitespace is preserved and validated by patch/integrity tests rather +than corrupting the checksum-bound patch data. + +The mandatory new IdP component job builds the actual runtime and tools, +collects upstream reports, invokes the memory/SQLite/old-key/linkage/inventory +harness and scans the final OS and Go binary with pinned Trivy and a fresh DB. +High/Critical findings, including unfixed findings, remain fatal. Evidence is +retained even on failure. Existing component jobs, cancellation policy, native +requirements and read-only workflow permissions remain unchanged. + +Independent contexts reviewed the packaging/dependency/source boundary, +closed the old-key-continuity finding and compatibility patches, and reviewed +the CI execution path. No residual source finding remains within those scopes. +This does not establish final-image qualification, independent rebuild +reproducibility, enterprise connector compatibility or live beta acceptance. +No cluster or main-branch mutation is authorized by this record. + +## Delegation and verdict + +### Subsequent security discussion follow-up + +Candidate `369aa8616a239cfab7b4612f99188e99441596d2` passed the complete +technical checks, including actual final-image OIDC/SQLite, linkage and +High/Critical scans. Guarded merge nevertheless stopped before any write on +two unresolved GHAS conversations. These were not waived because the image +threshold passed. + +CVE-2026-32952 is a real Medium-severity issue in the selected +`github.com/Azure/go-ntlmssp` version. A new hosted Go resolver output selects +v0.1.1. The parent verified that this is the only changed module selection, +with the nested API and archived baseline bytes unchanged; the previous +qualified artifact remains retained separately. Checksums were generated by +Go, not transcribed. The upstream overflow regression and package race suite +must execute on the new candidate. + +GO-2026-5932 concerns the `golang.org/x/crypto/openpgp` package and its +subpackages, not every use of the crypto module. The build now retains its +actual `go list -deps` inventory and rejects those package paths. That guard +must execute and its evidence must be reviewed before resolving the note. +There is no module-wide scanner exception or unsupported fixed-version claim. + +The prior binary/runtime evidence does not qualify this changed dependency +selection. Fresh source review and all current-head build/runtime/security +requirements remain mandatory; this follow-up does not itself approve merge. + +This uses the maintainer's explicit +[publication-review delegation](https://github.com/Azure/kars/pull/551#issuecomment-5615522306). +The implementation, independent AI review and parent composition are disclosed +as such, not two human reviews. Accept this bounded source for qualification; +all current-head technical/security and deployment gates remain required. + +Signed-off-by: pallakatos (author source attestation through explicit maintainer-delegated AI review, not a claim of personal code review) <191481949+pallakatos@users.noreply.github.com> +Signed-off-by: GitHub Copilot (independent-context delegated AI source review, not a second human) <223556219+Copilot@users.noreply.github.com> diff --git a/tests/e2e/budget-api-kubectl.mjs b/tests/e2e/budget-api-kubectl.mjs index 5efdb9e5..a5dd3643 100644 --- a/tests/e2e/budget-api-kubectl.mjs +++ b/tests/e2e/budget-api-kubectl.mjs @@ -7,6 +7,20 @@ import { fileURLToPath } from "node:url"; const root = fileURLToPath(new URL("../../", import.meta.url)); export const context = "kind-kars-budget-api"; +class BudgetApiCommandFailure extends Error { + constructor(error) { + super("Disposable budget API assertion command failed", { cause: undefined }); + const message = String(error.stderr ?? ""); + this.budgetTokenPolicyDenied = error.status === 1 + && /(?:^|\n)The serviceaccounts ["']untrusted["'] is invalid:/.test(message) + && /ValidatingAdmissionPolicy ['"]kars-inference-budget-token['"] with binding ['"]kars-inference-budget-token['"] denied request: Only kubelet node identities may obtain a Pod-bound governed-inference audience token(?:$|[\s"])/.test(message); + } +} + +export function isBudgetTokenPolicyDenial(error) { + return error instanceof BudgetApiCommandFailure && error.budgetTokenPolicyDenied; +} + export function kubectl(args, input, publicSchema = false) { try { return execFileSync("kubectl", ["--context", context, "--request-timeout=20s", ...args], { @@ -15,9 +29,9 @@ export function kubectl(args, input, publicSchema = false) { }); } catch (error) { if (publicSchema) { - // Only public CRD/VAP creation and CRD readiness opt in, never Secret/token commands. + // Public schemas/readiness and synthetic authorization reviews only, never Secret/token commands. console.error(String(error.stderr ?? "").slice(0, 12_000)); } - throw new Error("Disposable budget API assertion command failed", { cause: undefined }); + throw new BudgetApiCommandFailure(error); } } diff --git a/tests/e2e/budget-api-kubectl.test.mjs b/tests/e2e/budget-api-kubectl.test.mjs index e8b762f2..eef00cc7 100644 --- a/tests/e2e/budget-api-kubectl.test.mjs +++ b/tests/e2e/budget-api-kubectl.test.mjs @@ -2,11 +2,13 @@ // Licensed under the MIT License. import assert from "node:assert/strict"; +import { execFile } from "node:child_process"; import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { createServer } from "node:http"; import { tmpdir } from "node:os"; import { join } from "node:path"; import test from "node:test"; -import { context, kubectl } from "./budget-api-kubectl.mjs"; +import { context, kubectl, isBudgetTokenPolicyDenial } from "./budget-api-kubectl.mjs"; function fixture(t, { stderr = "", stdout = "", status = 0 } = {}) { const directory = mkdtempSync(join(tmpdir(), "kars-budget-command-")); @@ -61,6 +63,17 @@ test("Secret and TokenRequest failures never expose input, stderr or an underlyi assert.deepEqual(state.errors, []); }); +test("synthetic authorization review can expose bounded public diagnostics without token bodies", (t) => { + const diagnostic = "Error from server (Forbidden): synthetic fixture permission review rejected"; + const state = fixture(t, { stderr: diagnostic, status: 1 }); + const review = { apiVersion: "authorization.k8s.io/v1", kind: "SelfSubjectAccessReview", + spec: { resourceAttributes: { namespace: "budget-api-fixture", verb: "create", + resource: "serviceaccounts", subresource: "token", name: "untrusted" } } }; + assert.throws(() => kubectl(["create", "-f", "-"], review, true), commandFailed); + assert.deepEqual(state.errors, [diagnostic]); + assert(!state.request().input.includes("audiences")); +}); + test("successful public and private commands preserve their output without diagnostic logging", (t) => { const output = '{"metadata":{"uid":"fixture-uid"}}\n'; const state = fixture(t, { stdout: output }); @@ -71,10 +84,91 @@ test("successful public and private commands preserve their output without diagn assert.deepEqual(state.errors, []); }); +test("real kubectl sends the built-in permission review without CRD discovery or relaxed validation", { timeout: 20_000 }, async (t) => { + const directory = mkdtempSync(join(tmpdir(), "kars-budget-raw-review-")); + t.after(() => rmSync(directory, { recursive: true, force: true })); + const path = "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews"; + const principal = "system:serviceaccount:budget-api-fixture:untrusted"; + const review = { apiVersion: "authorization.k8s.io/v1", kind: "SelfSubjectAccessReview", + spec: { resourceAttributes: { namespace: "budget-api-fixture", verb: "create", + group: "", version: "v1", resource: "serviceaccounts", subresource: "token", name: "untrusted" } } }; + const requests = []; + const server = createServer(async (req, res) => { + let body = ""; + for await (const chunk of req) body += chunk; + requests.push({ method: req.method, path: new URL(req.url, "http://localhost").pathname, + actor: req.headers["impersonate-user"], body }); + res.setHeader("Content-Type", "application/json"); + if (req.method !== "POST" || new URL(req.url, "http://localhost").pathname !== path) { + res.writeHead(403); + res.end(JSON.stringify({ kind: "Status", status: "Failure", reason: "Forbidden", code: 403 })); + return; + } + res.end(JSON.stringify({ ...review, status: { allowed: true } })); + }); + await new Promise(resolve => server.listen(0, "127.0.0.1", resolve)); + t.after(() => new Promise(resolve => server.close(resolve))); + const config = join(directory, "config.json"); + writeFileSync(config, JSON.stringify({ apiVersion: "v1", kind: "Config", + clusters: [{ name: "fixture", cluster: { server: `http://127.0.0.1:${server.address().port}` } }], + users: [{ name: "fixture", user: {} }], + contexts: [{ name: context, context: { cluster: "fixture", user: "fixture" } }], + "current-context": context }), { mode: 0o600 }); + const output = await new Promise((resolve, reject) => { + const child = execFile("kubectl", ["--kubeconfig", config, "--context", context, + "--request-timeout=5s", "create", "--raw", path, "-f", "-", "--as", principal], + { encoding: "utf8", timeout: 10_000 }, (error, stdout) => error ? reject(error) : resolve(stdout)); + child.stdin.end(JSON.stringify(review)); + }); + assert.equal(JSON.parse(output).status.allowed, true); + assert.deepEqual(requests, [{ method: "POST", path, actor: principal, body: JSON.stringify(review) }]); +}); + +test("private audience denial requires the exact policy and binding without exposing error contents", (t) => { + const marker = "do-not-publish-token-material"; + const stderr = 'The serviceaccounts "untrusted" is invalid: : Invalid value: "": ' + + "ValidatingAdmissionPolicy 'kars-inference-budget-token' with binding " + + "'kars-inference-budget-token' denied request: " + + `Only kubelet node identities may obtain a Pod-bound governed-inference audience token\n${marker}`; + const state = fixture(t, { stderr, status: 1 }); + assert.throws(() => kubectl(["create", "--raw", "/fixture/token"], { private: marker }), (error) => { + commandFailed(error); + assert.equal(isBudgetTokenPolicyDenial(error), true); + assert(!JSON.stringify(error).includes(marker)); + assert(!error.stack.includes(marker)); + return true; + }); + assert.deepEqual(state.errors, []); +}); + +for (const stderr of [ + 'Error from server (Forbidden): User "untrusted" cannot create resource "serviceaccounts/token"', + 'The serviceaccounts "untrusted" is invalid: ValidatingAdmissionPolicy \'another-policy\' with binding \'kars-inference-budget-token\' denied request: Only kubelet node identities may obtain a Pod-bound governed-inference audience token', + 'The serviceaccounts "untrusted" is invalid: ValidatingAdmissionPolicy \'kars-inference-budget-token\' with binding \'another-binding\' denied request: Only kubelet node identities may obtain a Pod-bound governed-inference audience token', + 'The serviceaccounts "untrusted" is invalid: ValidatingAdmissionPolicy \'kars-inference-budget-token\' with binding \'kars-inference-budget-token\' denied request: expression resulted in an evaluation error', + "Error from server (Forbidden): ValidatingAdmissionPolicy 'kars-inference-budget-token' with binding 'kars-inference-budget-token' denied request: Only kubelet node identities may obtain a Pod-bound governed-inference audience token", + "Unable to connect to the server: connection refused", +]) { + test(`non-policy failure never qualifies private-audience denial: ${stderr}`, (t) => { + const state = fixture(t, { stderr, status: 1 }); + assert.throws(() => kubectl(["create", "--raw", "/fixture/token"], {}), (error) => { + commandFailed(error); + assert.equal(isBudgetTokenPolicyDenial(error), false); + return true; + }); + assert.deepEqual(state.errors, []); + }); +} + test("the actual preflight opts only its public CRD wait into schema diagnostics", () => { const source = readFileSync(new URL("./inference-budget-api.mjs", import.meta.url), "utf8"); assert.equal(context, "kind-kars-budget-api"); - assert.ok(source.includes('import { context, kubectl } from "./budget-api-kubectl.mjs";')); + assert.ok(source.includes('import { context, kubectl, isBudgetTokenPolicyDenial } from "./budget-api-kubectl.mjs";')); assert.ok(source.includes("root, context, kubectl, until, namespace, controller, principal,")); assert.ok(source.includes('kubectl(["wait", "--for=condition=Established", `crd/${definition.metadata.name}`, "--timeout=60s"], undefined, true);')); + assert(source.indexOf("kind: \"SelfSubjectAccessReview\"") < source.indexOf("const ordinaryToken =")); + assert.ok(source.includes('"/apis/authorization.k8s.io/v1/selfsubjectaccessreviews", "-f", "-", "--as", principal]')); + assert(!source.includes("--validate=false")); + assert(source.indexOf("const ordinaryToken =") < source.indexOf("assert.throws(() => kubectl(tokenArgs, tokenRequest)")); + assert.ok(source.includes("isBudgetTokenPolicyDenial,")); }); diff --git a/tests/e2e/inference-budget-api.mjs b/tests/e2e/inference-budget-api.mjs index 31b36469..2c1b1f36 100644 --- a/tests/e2e/inference-budget-api.mjs +++ b/tests/e2e/inference-budget-api.mjs @@ -9,7 +9,7 @@ import { readFileSync } from "node:fs"; import { createRequire } from "node:module"; import { fileURLToPath } from "node:url"; import { runWorkloadProof } from "./budget-workload-cases.mjs"; -import { context, kubectl } from "./budget-api-kubectl.mjs"; +import { context, kubectl, isBudgetTokenPolicyDenial } from "./budget-api-kubectl.mjs"; const require = createRequire(new URL("../../cli/package.json", import.meta.url)); const { parseAllDocuments } = require("yaml"); @@ -128,8 +128,24 @@ assert.throws(() => kubectl(["replace", "-f", "-"], changedScope)); const tokenRequest = { apiVersion: "authentication.k8s.io/v1", kind: "TokenRequest", spec: { audiences: [audience], expirationSeconds: 600 } }; -assert.throws(() => kubectl(["create", "--raw", - `/api/v1/namespaces/${namespace}/serviceaccounts/untrusted/token`, "-f", "-", "--as", principal], tokenRequest)); +await until(() => { + const review = JSON.parse(kubectl(["create", "--raw", + "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews", "-f", "-", "--as", principal], + { apiVersion: "authorization.k8s.io/v1", kind: "SelfSubjectAccessReview", + spec: { resourceAttributes: { namespace, verb: "create", group: "", version: "v1", + resource: "serviceaccounts", subresource: "token", name: "untrusted" } } }, true)); + assert(!review.status?.evaluationError, "Fixture TokenRequest authorization evaluator failed"); + return review.status?.allowed === true; +}, "fixture principal is actually authorized for TokenRequest"); +const tokenArgs = ["create", "--raw", + `/api/v1/namespaces/${namespace}/serviceaccounts/untrusted/token`, "-f", "-", "--as", principal]; +const ordinaryAudience = structuredClone(tokenRequest); +ordinaryAudience.spec.audiences = ["kars.azure.com/budget-fixture-public"]; +const ordinaryToken = JSON.parse(kubectl(tokenArgs, ordinaryAudience)); +assert(typeof ordinaryToken.status?.token === "string" && ordinaryToken.status.token.length > 0, + "Same principal must be able to request an ordinary audience before testing private admission"); +assert.throws(() => kubectl(tokenArgs, tokenRequest), isBudgetTokenPolicyDenial, + "The private audience must be rejected by its exact admission policy, not RBAC or a transport failure"); const projection = { apiVersion: "v1", kind: "ConfigMap", metadata: { name: "kars-inference-budget-ca", namespace }, data: { "ca.crt": "public-test-only" } };