Merge pull request #1 from dexidp/master

Update fork to head
This commit is contained in:
Misha Bragin
2026-04-03 11:02:49 +02:00
committed by GitHub
258 changed files with 35871 additions and 3027 deletions
+3 -3
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
@@ -35,13 +35,13 @@ jobs:
publish_results: true
- name: Upload results as artifact
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: OpenSSF Scorecard results
path: results.sarif
retention-days: 5
- name: Upload results to GitHub Security tab
uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # v3.29.5
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
with:
sarif_file: results.sarif
+53 -22
View File
@@ -51,19 +51,21 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-tags: true
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Set up Syft
uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
- name: Install cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
- name: Set image name
id: image-name
@@ -71,7 +73,7 @@ jobs:
- name: Gather build metadata
id: meta
uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: |
${{ steps.image-name.outputs.value }}
@@ -90,6 +92,12 @@ jobs:
labels: |
org.opencontainers.image.documentation=https://dexidp.io/docs/
# Multiple exporters are not supported yet
# See https://github.com/moby/buildkit/pull/2760
- name: Get version from git-version script
id: version
run: echo "value=$(bash ./scripts/git-version)" >> "$GITHUB_OUTPUT"
# Multiple exporters are not supported yet
# See https://github.com/moby/buildkit/pull/2760
- name: Determine build output
@@ -101,7 +109,7 @@ jobs:
if_false: type=oci,dest=image.tar
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -109,7 +117,7 @@ jobs:
if: inputs.publish
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
@@ -117,17 +125,18 @@ jobs:
- name: Build and push image
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
tags: ${{ steps.meta.outputs.tags }}
build-args: |
BASE_IMAGE=${{ matrix.variant }}
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
VERSION=${{ steps.version.outputs.value }}
COMMIT_HASH=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
BUILD_DATE=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
labels: ${{ steps.meta.outputs.labels }}
labels: |
${{ steps.meta.outputs.labels }}
# cache-from: type=gha
# cache-to: type=gha,mode=max
outputs: ${{ steps.build-output.outputs.value }}
@@ -154,10 +163,21 @@ jobs:
# path: image.tar
- name: Extract OCI tarball
id: extract-oci
run: |
mkdir -p image
tar -xf image.tar -C image
image_name=$(jq -r '.manifests[0].annotations["io.containerd.image.name"]' image/index.json)
image_tag=$(jq -r '.manifests[0].annotations["org.opencontainers.image.ref.name"]' image/index.json)
echo "Copying $image_tag -> $image_name"
skopeo copy "oci:image:$image_tag" "docker-daemon:$image_name"
echo "value=$image_name" >> "$GITHUB_OUTPUT"
if: ${{ !inputs.publish }}
# - name: List tags
# run: skopeo --insecure-policy list-tags oci:image
#
@@ -177,20 +197,28 @@ jobs:
# TODO: uncomment when the action is working for non ghcr.io pushes. GH Issue: https://github.com/actions/attest-build-provenance/issues/80
# - name: Generate build provenance attestation
# uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
# uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
# with:
# subject-name: dexidp/dex
# subject-digest: ${{ steps.build.outputs.digest }}
# push-to-registry: true
- name: Generate build provenance attestation
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
if: inputs.publish
- name: Prepare image fs for scanning
run: |
image_ref=${{ steps.extract-oci.outputs.value != '' && steps.extract-oci.outputs.value || steps.image-ref.outputs.value }}
docker export $(docker create --rm $image_ref) -o docker-image.tar
mkdir -p docker-image
tar -xf docker-image.tar -C docker-image
## Use cache for the trivy-db to avoid the TOOMANYREQUESTS error https://github.com/aquasecurity/trivy-action/pull/397
## To avoid the trivy-db becoming outdated, we save the cache for one day
- name: Get data
@@ -198,25 +226,25 @@ jobs:
run: echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT
- name: Restore trivy cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: cache/db
key: trivy-cache-${{ steps.date.outputs.date }}
restore-keys: trivy-cache-
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0
with:
input: image
input: docker-image
format: sarif
output: trivy-results.sarif
scan-type: "fs"
scan-type: "rootfs"
scan-ref: "."
cache-dir: "./cache"
# Disable skipping trivy cache for now
# env:
# TRIVY_SKIP_DB_UPDATE: true
# TRIVY_SKIP_JAVA_DB_UPDATE: true
env:
TRIVY_SKIP_DB_UPDATE: true
TRIVY_SKIP_JAVA_DB_UPDATE: true
## Trivy-db uses `0600` permissions.
## But `action/cache` use `runner` user by default
@@ -224,8 +252,11 @@ jobs:
- name: change permissions for trivy.db
run: sudo chmod 0644 ./cache/db/trivy.db
- name: Check Trivy sarif
run: cat trivy-results.sarif
- name: Upload Trivy scan results as artifact
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: "[${{ github.job }}] Trivy scan results"
path: trivy-results.sarif
@@ -233,6 +264,6 @@ jobs:
overwrite: true
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # v3.29.5
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
with:
sarif_file: trivy-results.sarif
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Check minimum labels
uses: mheap/github-action-required-labels@8afbe8ae6ab7647d0c9f0cfa7c2f939650d22509 # v5.5
uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5
with:
mode: minimum
count: 1
+60 -7
View File
@@ -48,6 +48,24 @@ jobs:
- 3306
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
mysql8:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: dex
ports:
- 3306
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
mysql8-ent:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: dex
ports:
- 3306
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
etcd:
image: gcr.io/etcd-development/etcd:v3.5.0
ports:
@@ -64,12 +82,30 @@ jobs:
- 35357
options: --health-cmd "curl --fail http://localhost:5000/v3" --health-interval 10s --health-timeout 5s --health-retries 5
vault:
image: hashicorp/vault:1.21
ports:
- 8200
env:
VAULT_DEV_ROOT_TOKEN_ID: root-token
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
options: --health-cmd "vault status -address=http://localhost:8200 || exit 1" --health-interval 10s --health-timeout 5s --health-retries 5
openbao:
image: quay.io/openbao/openbao:2.5
ports:
- 8210
env:
BAO_DEV_ROOT_TOKEN_ID: root-token
BAO_DEV_LISTEN_ADDRESS: "0.0.0.0:8210"
options: --health-cmd "bao status -address=http://localhost:8210 || exit 1" --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.25"
@@ -86,7 +122,7 @@ jobs:
run: docker compose -f docker-compose.test.yaml up -d
- name: Create kind cluster
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
with:
version: "v0.17.0"
node_image: "kindest/node:v1.25.3@sha256:cd248d1438192f7814fbca8fede13cfe5b9918746dfa12583976158a834fd5c5"
@@ -106,6 +142,18 @@ jobs:
DEX_MYSQL_ENT_HOST: 127.0.0.1
DEX_MYSQL_ENT_PORT: ${{ job.services.mysql-ent.ports[3306] }}
DEX_MYSQL8_DATABASE: dex
DEX_MYSQL8_USER: root
DEX_MYSQL8_PASSWORD: root
DEX_MYSQL8_HOST: 127.0.0.1
DEX_MYSQL8_PORT: ${{ job.services.mysql8.ports[3306] }}
DEX_MYSQL8_ENT_DATABASE: dex
DEX_MYSQL8_ENT_USER: root
DEX_MYSQL8_ENT_PASSWORD: root
DEX_MYSQL8_ENT_HOST: 127.0.0.1
DEX_MYSQL8_ENT_PORT: ${{ job.services.mysql8-ent.ports[3306] }}
DEX_POSTGRES_DATABASE: postgres
DEX_POSTGRES_USER: postgres
DEX_POSTGRES_PASSWORD: postgres
@@ -129,6 +177,11 @@ jobs:
DEX_KEYSTONE_ADMIN_USER: demo
DEX_KEYSTONE_ADMIN_PASS: DEMO_PASS
DEX_VAULT_ADDR: http://localhost:${{ job.services.vault.ports[8200] }}
DEX_VAULT_TOKEN: root-token
DEX_OPENBAO_ADDR: http://localhost:${{ job.services.openbao.ports[8210] }}
DEX_OPENBAO_TOKEN: root-token
DEX_KUBERNETES_CONFIG_PATH: ~/.kube/config
lint:
@@ -137,10 +190,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.25"
@@ -172,7 +225,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Dependency Review
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
+4 -1
View File
@@ -7,6 +7,9 @@ on:
- cron: '0 0 * * *' # Run daily at midnight UTC
workflow_dispatch: # Allow manual triggering
permissions:
contents: read
jobs:
update-trivy-db:
runs-on: ubuntu-latest
@@ -33,7 +36,7 @@ jobs:
rm javadb.tar.gz
- name: Cache DBs
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ github.workspace }}/.cache/trivy
key: cache-trivy-${{ steps.date.outputs.date }}
+1
View File
@@ -6,3 +6,4 @@
/docker-compose.override.yaml
/var/
/vendor/
*.db
+161
View File
@@ -0,0 +1,161 @@
# Contributing to Dex
Dex is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub pull requests.
This document outlines how to contribute to the project.
- [Code of Conduct](#code-of-conduct)
- [Finding something to work on](#finding-something-to-work-on)
- [Setting up a development environment](#setting-up-a-development-environment)
- [Making changes](#making-changes)
- [Running the example app](#running-the-example-app)
- [Committing your changes](#committing-your-changes)
- [Submitting a pull request](#submitting-a-pull-request)
- [Enhancement proposals](#enhancement-proposals)
- [Getting help](#getting-help)
## Code of Conduct
This project follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
## Finding something to work on
If you have a bug fix or a small improvement, go ahead and open a pull request.
For larger changes, please open a [discussion](https://github.com/dexidp/dex/discussions/new?category=Ideas) first
to align with the community and avoid unnecessary work. Major features or significant architectural
changes should go through the [Enhancement Proposal](#enhancement-proposals) process.
If you're looking for something to work on, check:
- Issues labeled with [good first issue](https://github.com/dexidp/dex/labels/good%20first%20issue)
- Issues labeled with [help wanted](https://github.com/dexidp/dex/labels/help%20wanted)
Please comment on the issue to claim it before starting work to avoid duplicated efforts.
## Setting up a development environment
For the best developer experience, install [Nix](https://builtwithnix.org/) and [direnv](https://direnv.net/).
This will automatically set up all required tools (Go, golangci-lint, protobuf compiler, kind, etc.).
Alternatively, you can set up the environment manually:
1. Install [Go](https://go.dev/doc/install) (see the version in [go.mod](go.mod)).
2. Install [Docker](https://docs.docker.com/get-started/).
3. Install development dependencies:
```shell
make deps
```
This installs `golangci-lint`, `gotestsum`, `protoc`, `protoc-gen-go`, `protoc-gen-go-grpc`, and `kind`.
You can also [use Gitpod](https://gitpod.io/#https://github.com/dexidp/dex) for a ready-to-code cloud environment.
## Making changes
Run `make help` to see all available commands. The key ones for contributors:
```shell
make deps # Install development dependencies
make build # Build Dex binaries
make testall # Run all tests (includes race detection)
make lint # Run linter
make generate # Regenerate protobuf, ent, and go mod tidy
```
## Running the example app
To test the login flow locally, run Dex with the dev config and the example OIDC client app.
**Terminal 1** — start Dex:
```shell
make build
./bin/dex serve config.dev.yaml
```
**Terminal 2** — start the example app:
```shell
make examples
./bin/example-app
```
Open http://127.0.0.1:5555 in your browser, click "Login", and authenticate with:
- **Email:** `admin@example.com`
- **Password:** `password`
After successful login, the example app displays the ID token claims returned by Dex.
## Committing your changes
The project follows [Conventional Commits](https://www.conventionalcommits.org/) style:
```
<type>[optional scope]: <description>
[optional body]
Signed-off-by: First Last <email@example.com>
```
Common types: `feat`, `fix`, `build`, `chore`, `docs`, `refactor`, `test`.
Examples from the project:
```
feat: use protobuf for session cookie (#4675)
fix: non-constant format string in call to newRedirectedErr (#4671)
build(deps): bump github/codeql-action from 4.33.0 to 4.34.1 (#4679)
```
### Developer Certificate of Origin
As a CNCF project, Dex requires all contributors to sign the [Developer Certificate of Origin (DCO)](https://developercertificate.org/).
This certifies that you have the right to submit your contribution under the project's open source license.
You must add a `Signed-off-by` line to every commit. Use git's `-s` flag to do this automatically:
```shell
git commit -s -m "feat: add new feature"
```
The DCO check will fail on pull requests with unsigned commits.
## Submitting a pull request
1. Fork the repository and create your branch from `master`.
2. Make your changes, following the guidelines above.
3. Ensure all tests pass (`make testall`) and the linter is clean (`make lint`).
4. Ensure generated code is up to date (`make generate`).
5. Push your branch and open a pull request.
When opening a pull request:
- Fill in the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) with an overview and explanation of the change.
- After opening a PR, a maintainer will add least one [release note label](https://github.com/dexidp/dex/labels?q=release-note) to the PR.
Valid labels include: `kind/feature`, `kind/enhancement`, `kind/bug`, `release-note/new-feature`,
`release-note/enhancement`, `release-note/bug-fix`, `release-note/breaking-change`,
`release-note/deprecation`, `release-note/ignore`, `area/dependencies`, `release-note/dependency-update`.
- If the PR is still in progress, use GitHub's [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) feature.
All CI checks (tests, linting, DCO, release label) must pass before the PR can be merged.
## Enhancement proposals
Significant features or architectural changes require a [Dex Enhancement Proposal (DEP)](docs/enhancements/README.md).
The process:
1. Search existing [issues](https://github.com/dexidp/dex/issues), [discussions](https://github.com/dexidp/dex/discussions), and [DEPs](https://github.com/dexidp/dex/tree/master/docs/enhancements).
2. Open a [discussion](https://github.com/dexidp/dex/discussions/new?category=Ideas) to get initial feedback.
3. Fork the repo and copy the [DEP template](docs/enhancements/_title-YYYY-MM-DD-#issue.md) with an appropriate name.
4. Fill in all sections and submit a PR for review.
## Getting help
- For bugs and feature requests, file an [issue](https://github.com/dexidp/dex/issues).
- For general discussion, open a [discussion](https://github.com/dexidp/dex/discussions) or join [#dexidp](https://cloud-native.slack.com/messages/dexidp) on the CNCF Slack.
- Mailing list (as a backup): [dex-dev](https://groups.google.com/forum/#!forum/dex-dev).
- For security vulnerabilities, see the [security policy](.github/SECURITY.md).
+15 -7
View File
@@ -2,7 +2,7 @@ ARG BASE_IMAGE=alpine
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.9.0@sha256:c64defb9ed5a91eacb37f96ccc3d4cd72521c4bd18d5442905b95e2226b0e707 AS xx
FROM --platform=$BUILDPLATFORM golang:1.25.5-alpine3.22@sha256:3587db7cc96576822c606d119729370dbf581931c5f43ac6d3fa03ab4ed85a10 AS builder
FROM --platform=$BUILDPLATFORM golang:1.26.1-alpine3.22@sha256:07e91d24f6330432729082bb580983181809e0a48f0f38ecde26868d4568c6ac AS builder
COPY --from=xx / /
@@ -35,27 +35,31 @@ RUN make release-binary
RUN xx-verify /go/bin/dex && xx-verify /go/bin/docker-entrypoint
FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS stager
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS stager
RUN mkdir -p /var/dex
RUN mkdir -p /etc/dex
COPY config.docker.yaml /etc/dex/
FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS gomplate
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS gomplate
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
ENV GOMPLATE_VERSION=v4.3.3
ENV GOMPLATE_VERSION=v5.0.0
RUN wget -O /usr/local/bin/gomplate \
"https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_${TARGETOS:-linux}-${TARGETARCH:-amd64}${TARGETVARIANT}" \
&& chmod +x /usr/local/bin/gomplate
# For Dependabot to detect base image versions
FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS alpine
FROM gcr.io/distroless/static-debian12:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4 AS distroless
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS alpine
FROM alpine AS user-setup
RUN addgroup -g 1001 -S dex && adduser -u 1001 -S -G dex -D -H -s /sbin/nologin dex
FROM gcr.io/distroless/static-debian13:nonroot@sha256:e3f945647ffb95b5839c07038d64f9811adf17308b9121d8a2b87b6a22a80a39 AS distroless
FROM $BASE_IMAGE
@@ -66,6 +70,10 @@ FROM $BASE_IMAGE
# See https://go.dev/src/crypto/x509/root_linux.go for Go root CA bundle locations.
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# Ensure the dex user/group exist before setting ownership or switching to them.
COPY --from=user-setup /etc/passwd /etc/passwd
COPY --from=user-setup /etc/group /etc/group
COPY --from=stager --chown=1001:1001 /var/dex /var/dex
COPY --from=stager --chown=1001:1001 /etc/dex /etc/dex
@@ -79,7 +87,7 @@ COPY --from=builder /usr/local/src/dex/web /srv/dex/web
COPY --from=gomplate /usr/local/bin/gomplate /usr/local/bin/gomplate
USER 1001:1001
USER dex:dex
ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
CMD ["dex", "serve", "/etc/dex/config.docker.yaml"]
-6
View File
@@ -1,6 +0,0 @@
Joel Speed <Joel.speed@hotmail.co.uk> (@JoelSpeed)
Maksim Nabokikh <max.nabokih@gmail.com> (@nabokihms)
Mark Sagi-Kazar <mark.sagikazar@gmail.com> (@sagikazarmark)
Nandor Kracser <bonifaido@gmail.com> (@bonifaido)
Rithu John <rithujohn191@gmail.com> (@rithujohn191)
Stephen Augustus <foo@auggie.dev> (@justaugustus)
+25
View File
@@ -0,0 +1,25 @@
# Dex Maintainers
The current Maintainers Group for the Dex Project consists of:
| Name | GitHub | Employer | Responsibilities |
| ---- | ------ | -------- | ---------------- |
| Maksim Nabokikh | [@nabokihms](https://github.com/nabokihms) | [Palark GmbH](https://palark.de/) | ALL |
| Márk Sági-Kazár | [@sagikazarmark](https://github.com/sagikazarmark) | <!-- TODO: employer --> | ALL |
This list must be kept in sync with the [CNCF Project Maintainers list](https://github.com/cncf/foundation/blob/master/project-maintainers.csv).
<!-- TODO (nabokihms): Add the Governance
See [the project Governance](./GOVERNANCE.md) for how maintainers are selected and replaced.
-->
## Emeritus Maintainers
We are grateful to our former maintainers for their contributions to the Dex project.
- [@ericchiang](https://github.com/ericchiang) - Eric Chiang
- [@JoelSpeed](https://github.com/JoelSpeed) - Joel Speed
- [@bonifaido](https://github.com/bonifaido) - Nandor Kracser
- [@rithujohn191](https://github.com/rithujohn191) - Rithu John
- [@justaugustus](https://github.com/justaugustus) - Stephen Augustus
- [@srenatus](https://github.com/srenatus) - Stephan Renatus
+25 -5
View File
@@ -35,6 +35,10 @@ build: bin/dex ## Build Dex binaries.
examples: bin/grpc-client bin/example-app ## Build example app.
.PHONY: update-gomplate
update-gomplate: ## Check and update gomplate version in Dockerfile.
@./scripts/update-gomplate
.PHONY: release-binary
release-binary: LD_FLAGS = "-w -X main.version=$(VERSION) -extldflags \"-static\""
release-binary: ## Build release binaries (used to build a final container image).
@@ -123,12 +127,28 @@ verify-go-mod: go-mod-tidy ## Check that go.mod and go.sum formatted according t
deps: bin/gotestsum bin/golangci-lint bin/protoc bin/protoc-gen-go bin/protoc-gen-go-grpc bin/kind ## Install dev dependencies.
.PHONY: test testrace testall
test: ## Test go code.
@go test -v ./...
# Detect if we're running in GitHub Actions
ifdef GITHUB_ACTIONS
GOTESTSUM_FORMAT = github-actions
else
GOTESTSUM_FORMAT = testname
GOTESTSUM_FORMAT_ICONS = hivis
endif
testrace: ## Test go code and check for possible race conditions.
@go test -v --race ./...
.PHONY: test testrace testall
test: bin/gotestsum ## Test go code.
ifdef GOTESTSUM_FORMAT_ICONS
@gotestsum --format $(GOTESTSUM_FORMAT) --format-icons $(GOTESTSUM_FORMAT_ICONS) -- -v ./...
else
@gotestsum --format $(GOTESTSUM_FORMAT) -- -v ./...
endif
testrace: bin/gotestsum ## Test go code and check for possible race conditions.
ifdef GOTESTSUM_FORMAT_ICONS
@gotestsum --format $(GOTESTSUM_FORMAT) --format-icons $(GOTESTSUM_FORMAT_ICONS) -- -v --race ./...
else
@gotestsum --format $(GOTESTSUM_FORMAT) -- -v --race ./...
endif
testall: testrace ## Run all tests for go code.
+185 -163
View File
@@ -23,16 +23,17 @@ const (
// Client represents an OAuth2 client.
type Client struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"`
RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"`
TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"`
Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"`
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"`
RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"`
TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"`
Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"`
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"`
AllowedConnectors []string `protobuf:"bytes,8,rep,name=allowed_connectors,json=allowedConnectors,proto3" json:"allowed_connectors,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Client) Reset() {
@@ -114,6 +115,13 @@ func (x *Client) GetLogoUrl() string {
return ""
}
func (x *Client) GetAllowedConnectors() []string {
if x != nil {
return x.AllowedConnectors
}
return nil
}
// CreateClientReq is a request to make a client.
type CreateClientReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -305,14 +313,15 @@ func (x *DeleteClientResp) GetNotFound() bool {
// UpdateClientReq is a request to update an existing client.
type UpdateClientReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"`
TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"`
TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"`
AllowedConnectors []string `protobuf:"bytes,6,rep,name=allowed_connectors,json=allowedConnectors,proto3" json:"allowed_connectors,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpdateClientReq) Reset() {
@@ -380,6 +389,13 @@ func (x *UpdateClientReq) GetLogoUrl() string {
return ""
}
func (x *UpdateClientReq) GetAllowedConnectors() []string {
if x != nil {
return x.AllowedConnectors
}
return nil
}
// UpdateClientResp returns the response from updating a client.
type UpdateClientResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -1326,7 +1342,7 @@ var File_api_api_proto protoreflect.FileDescriptor
var file_api_api_proto_rawDesc = string([]byte{
0x0a, 0x0d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x03, 0x61, 0x70, 0x69, 0x22, 0xc1, 0x01, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
0x03, 0x61, 0x70, 0x69, 0x22, 0xf0, 0x01, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x69, 0x72,
@@ -1338,155 +1354,161 @@ var file_api_api_proto_rawDesc = string([]byte{
0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a,
0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x22, 0x36, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x06, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x22, 0x5e, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f,
0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c,
0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x22, 0x21, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x69, 0x64, 0x22, 0x2f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66,
0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46,
0x6f, 0x75, 0x6e, 0x64, 0x22, 0x9a, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x69,
0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x23, 0x0a,
0x0d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x03,
0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x65, 0x65,
0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75,
0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72,
0x6c, 0x22, 0x2f, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75,
0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75,
0x6e, 0x64, 0x22, 0x69, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14,
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x3e, 0x0a,
0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52,
0x65, 0x71, 0x12, 0x29, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3b, 0x0a,
0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52,
0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f,
0x77, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x08,
0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x36, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22,
0x5e, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65,
0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x72,
0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x67, 0x0a, 0x11, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12,
0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x68, 0x61, 0x73,
0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x48, 0x61, 0x73, 0x68,
0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74,
0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f,
0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x29, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65,
0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69,
0x6c, 0x22, 0x31, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77,
0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22,
0x21, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x69, 0x64, 0x22, 0x2f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f,
0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f,
0x75, 0x6e, 0x64, 0x22, 0xc9, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x69, 0x72,
0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c,
0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x23, 0x0a, 0x0d,
0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20,
0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72,
0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75, 0x72,
0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c,
0x12, 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c,
0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22,
0x2f, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64,
0x22, 0x69, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61,
0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x3e, 0x0a, 0x11, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71,
0x12, 0x29, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3b, 0x0a, 0x12, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73,
0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69,
0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61,
0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x67, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a,
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
0x61, 0x69, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21,
0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
0x65, 0x22, 0x31, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66,
0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46,
0x6f, 0x75, 0x6e, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x22, 0x3f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x09, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x09, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x22, 0x37, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a,
0x03, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x70, 0x69, 0x22,
0x7a, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52,
0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12,
0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20,
0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b,
0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a,
0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x66,
0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73,
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65,
0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x22, 0x30, 0x0a, 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75,
0x6f, 0x75, 0x6e, 0x64, 0x22, 0x29, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61,
0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22,
0x31, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75,
0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75,
0x6e, 0x64, 0x22, 0x45, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x65, 0x72,
0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12,
0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e,
0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0xc7, 0x05, 0x0a, 0x03, 0x44, 0x65, 0x78,
0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12,
0x3d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d,
0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a,
0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12,
0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70,
0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65,
0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d,
0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x14, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a,
0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12,
0x3a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x13,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x52,
0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x15, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a,
0x0e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12,
0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65,
0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70,
0x22, 0x00, 0x42, 0x2f, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73,
0x2e, 0x64, 0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x19, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f,
0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x52, 0x65, 0x71, 0x22, 0x3f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x09, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x09, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x22, 0x37, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61,
0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x70, 0x69, 0x22, 0x7a, 0x0a,
0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a,
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x09,
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
0x08, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75,
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73,
0x65, 0x72, 0x49, 0x64, 0x22, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65,
0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x52, 0x65, 0x66, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65,
0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49,
0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x30,
0x0a, 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52,
0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64,
0x22, 0x45, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66,
0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a,
0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74,
0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f,
0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0xc7, 0x05, 0x0a, 0x03, 0x44, 0x65, 0x78, 0x12, 0x3d,
0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a,
0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0c,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00,
0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52,
0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a,
0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x4c, 0x69,
0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65,
0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x47, 0x65,
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3a, 0x0a,
0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x13, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65,
0x71, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x52, 0x65, 0x76,
0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65,
0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65,
0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x56,
0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69,
0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00,
0x42, 0x2f, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2e, 0x64,
0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x19, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x61, 0x70,
0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
+2
View File
@@ -14,6 +14,7 @@ message Client {
bool public = 5;
string name = 6;
string logo_url = 7;
repeated string allowed_connectors = 8;
}
// CreateClientReq is a request to make a client.
@@ -45,6 +46,7 @@ message UpdateClientReq {
repeated string trusted_peers = 3;
string name = 4;
string logo_url = 5;
repeated string allowed_connectors = 6;
}
// UpdateClientResp returns the response from updating a client.
+565 -426
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -14,6 +14,8 @@ message Client {
bool public = 5;
string name = 6;
string logo_url = 7;
repeated string allowed_connectors = 8;
repeated string sso_shared_with = 9;
}
// ClientInfo represents an OAuth2 client without sensitive information.
@@ -24,6 +26,8 @@ message ClientInfo {
bool public = 4;
string name = 5;
string logo_url = 6;
repeated string allowed_connectors = 7;
repeated string sso_shared_with = 8;
}
// GetClientReq is a request to retrieve client details.
@@ -66,6 +70,8 @@ message UpdateClientReq {
repeated string trusted_peers = 3;
string name = 4;
string logo_url = 5;
repeated string allowed_connectors = 6;
repeated string sso_shared_with = 7;
}
// UpdateClientResp returns the response from updating a client.
@@ -140,6 +146,7 @@ message Connector {
string type = 2;
string name = 3;
bytes config = 4;
repeated string grant_types = 5;
}
// CreateConnectorReq is a request to make a connector.
@@ -152,6 +159,12 @@ message CreateConnectorResp {
bool already_exists = 1;
}
// GrantTypes wraps a list of grant types to distinguish between
// "not specified" (no update) and "empty list" (unrestricted).
message GrantTypes {
repeated string grant_types = 1;
}
// UpdateConnectorReq is a request to modify an existing connector.
message UpdateConnectorReq {
// The id used to lookup the connector. This field cannot be modified
@@ -159,6 +172,10 @@ message UpdateConnectorReq {
string new_type = 2;
string new_name = 3;
bytes new_config = 4;
// If set, updates the connector's allowed grant types.
// An empty grant_types list means unrestricted (all grant types allowed).
// If not set (null), grant types are not modified.
GrantTypes new_grant_types = 5;
}
// UpdateConnectorResp returns the response from modifying an existing connector.
+7 -7
View File
@@ -1,15 +1,15 @@
module github.com/dexidp/dex/api/v2
go 1.24.0
go 1.25.0
require (
google.golang.org/grpc v1.77.0
google.golang.org/protobuf v1.36.10
google.golang.org/grpc v1.79.3
google.golang.org/protobuf v1.36.11
)
require (
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
)
+24 -22
View File
@@ -1,3 +1,5 @@
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=
@@ -10,27 +12,27 @@ 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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
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.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
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-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/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=
+298 -31
View File
@@ -1,6 +1,7 @@
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
@@ -10,10 +11,12 @@ import (
"os"
"strings"
"github.com/go-jose/go-jose/v4"
"golang.org/x/crypto/bcrypt"
"github.com/dexidp/dex/pkg/featureflags"
"github.com/dexidp/dex/server"
"github.com/dexidp/dex/server/signer"
"github.com/dexidp/dex/storage"
"github.com/dexidp/dex/storage/ent"
"github.com/dexidp/dex/storage/etcd"
@@ -22,6 +25,15 @@ import (
"github.com/dexidp/dex/storage/sql"
)
func configUnmarshaller(b []byte, v interface{}) error {
if !featureflags.ConfigDisallowUnknownFields.Enabled() {
return json.Unmarshal(b, v)
}
dec := json.NewDecoder(bytes.NewReader(b))
dec.DisallowUnknownFields()
return dec.Decode(v)
}
// Config is the config format for the main application.
type Config struct {
Issuer string `json:"issuer"`
@@ -35,6 +47,9 @@ type Config struct {
Frontend server.WebConfig `json:"frontend"`
// Signer configuration controls signing of JWT tokens issued by Dex.
Signer Signer `json:"signer"`
// StaticConnectors are user defined connectors specified in the ConfigMap
// Write operations, like updating a connector, will fail.
StaticConnectors []Connector `json:"connectors"`
@@ -51,6 +66,23 @@ type Config struct {
// querying the storage. Cannot be specified without enabling a passwords
// database.
StaticPasswords []password `json:"staticPasswords"`
// Sessions holds authentication session configuration.
// Requires DEX_SESSIONS_ENABLED=true feature flag.
Sessions *Sessions `json:"sessions"`
// MFA holds multi-factor authentication configuration.
MFA MFAConfig `json:"mfa"`
}
// MFAConfig holds multi-factor authentication settings.
type MFAConfig struct {
// Authenticators defines MFA providers available for clients to reference.
Authenticators []MFAAuthenticator `json:"authenticators"`
// DefaultMFAChain is the default ordered list of authenticator IDs applied
// to clients that don't specify their own mfaChain. Empty means no MFA by default.
DefaultMFAChain []string `json:"defaultMFAChain"`
}
// Validate the configuration
@@ -85,9 +117,63 @@ func (c Config) Validate() error {
checkErrors = append(checkErrors, check.errMsg)
}
}
if len(checkErrors) != 0 {
return fmt.Errorf("invalid Config:\n\t-\t%s", strings.Join(checkErrors, "\n\t-\t"))
}
if c.Sessions != nil && !featureflags.SessionsEnabled.Enabled() {
return fmt.Errorf("sessions config requires sessions to be enabled (DEX_SESSIONS_ENABLED=true)")
}
if err := c.validateMFA(); err != nil {
return err
}
return nil
}
func (c Config) validateMFA() error {
mfa := c.MFA
if len(mfa.Authenticators) == 0 && len(mfa.DefaultMFAChain) == 0 {
return nil
}
if !featureflags.SessionsEnabled.Enabled() {
return fmt.Errorf("mfa requires sessions to be enabled (DEX_SESSIONS_ENABLED=true)")
}
knownTypes := map[string]bool{"TOTP": true, "WebAuthn": true}
ids := make(map[string]bool, len(mfa.Authenticators))
for _, auth := range mfa.Authenticators {
if auth.ID == "" {
return fmt.Errorf("mfa.authenticators: authenticator must have an id")
}
if ids[auth.ID] {
return fmt.Errorf("mfa.authenticators: duplicate authenticator id %q", auth.ID)
}
ids[auth.ID] = true
if !knownTypes[auth.Type] {
return fmt.Errorf("mfa.authenticators: unknown type %q for authenticator %q", auth.Type, auth.ID)
}
}
for _, authID := range mfa.DefaultMFAChain {
if !ids[authID] {
return fmt.Errorf("mfa.defaultMFAChain: references unknown authenticator %q", authID)
}
}
for _, client := range c.StaticClients {
for _, authID := range client.MFAChain {
if !ids[authID] {
return fmt.Errorf("staticClients: client %q references unknown MFA authenticator %q", client.ID, authID)
}
}
}
return nil
}
@@ -95,19 +181,27 @@ type password storage.Password
func (p *password) UnmarshalJSON(b []byte) error {
var data struct {
Email string `json:"email"`
Username string `json:"username"`
UserID string `json:"userID"`
Hash string `json:"hash"`
HashFromEnv string `json:"hashFromEnv"`
Email string `json:"email"`
Username string `json:"username"`
Name string `json:"name"`
PreferredUsername string `json:"preferredUsername"`
EmailVerified *bool `json:"emailVerified"`
UserID string `json:"userID"`
Hash string `json:"hash"`
HashFromEnv string `json:"hashFromEnv"`
Groups []string `json:"groups"`
}
if err := json.Unmarshal(b, &data); err != nil {
if err := configUnmarshaller(b, &data); err != nil {
return err
}
*p = password(storage.Password{
Email: data.Email,
Username: data.Username,
UserID: data.UserID,
Email: data.Email,
Username: data.Username,
Name: data.Name,
PreferredUsername: data.PreferredUsername,
EmailVerified: data.EmailVerified,
UserID: data.UserID,
Groups: data.Groups,
})
if len(data.Hash) == 0 && len(data.HashFromEnv) > 0 {
data.Hash = os.Getenv(data.HashFromEnv)
@@ -149,6 +243,16 @@ type OAuth2 struct {
AlwaysShowLoginScreen bool `json:"alwaysShowLoginScreen"`
// This is the connector that can be used for password grant
PasswordConnector string `json:"passwordConnector"`
// PKCE configuration
PKCE PKCE `json:"pkce"`
}
// PKCE holds the PKCE (Proof Key for Code Exchange) configuration.
type PKCE struct {
// If true, PKCE is required for all authorization code flows.
Enforce bool `json:"enforce"`
// Supported code challenge methods. Defaults to ["S256", "plain"].
CodeChallengeMethodsSupported []string `json:"codeChallengeMethodsSupported"`
}
// Web is the config format for the HTTP server.
@@ -275,12 +379,12 @@ var (
_ StorageConfig = (*ent.MySQL)(nil)
)
func getORMBasedSQLStorage(normal, entBased StorageConfig) func() StorageConfig {
func getORMBasedSQLStorage(normal, entBased func() StorageConfig) func() StorageConfig {
return func() StorageConfig {
if featureflags.EntEnabled.Enabled() {
return entBased
return entBased()
}
return normal
return normal()
}
}
@@ -309,9 +413,9 @@ var storages = map[string]func() StorageConfig{
"etcd": func() StorageConfig { return new(etcd.Etcd) },
"kubernetes": func() StorageConfig { return new(kubernetes.Config) },
"memory": func() StorageConfig { return new(memory.Config) },
"sqlite3": getORMBasedSQLStorage(&sql.SQLite3{}, &ent.SQLite3{}),
"postgres": getORMBasedSQLStorage(&sql.Postgres{}, &ent.Postgres{}),
"mysql": getORMBasedSQLStorage(&sql.MySQL{}, &ent.MySQL{}),
"sqlite3": getORMBasedSQLStorage(func() StorageConfig { return new(sql.SQLite3) }, func() StorageConfig { return new(ent.SQLite3) }),
"postgres": getORMBasedSQLStorage(func() StorageConfig { return new(sql.Postgres) }, func() StorageConfig { return new(ent.Postgres) }),
"mysql": getORMBasedSQLStorage(func() StorageConfig { return new(sql.MySQL) }, func() StorageConfig { return new(ent.MySQL) }),
}
// UnmarshalJSON allows Storage to implement the unmarshaler interface to
@@ -321,7 +425,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
Type string `json:"type"`
Config json.RawMessage `json:"config"`
}
if err := json.Unmarshal(b, &store); err != nil {
if err := configUnmarshaller(b, &store); err != nil {
return fmt.Errorf("parse storage: %v", err)
}
f, ok := storages[store.Type]
@@ -334,7 +438,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
data := []byte(store.Config)
if featureflags.ExpandEnv.Enabled() {
var rawMap map[string]interface{}
if err := json.Unmarshal(store.Config, &rawMap); err != nil {
if err := configUnmarshaller(store.Config, &rawMap); err != nil {
return fmt.Errorf("unmarshal config for env expansion: %v", err)
}
@@ -351,7 +455,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
data = expandedData
}
if err := json.Unmarshal(data, storageConfig); err != nil {
if err := configUnmarshaller(data, storageConfig); err != nil {
return fmt.Errorf("parse storage config: %v", err)
}
}
@@ -362,6 +466,90 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
return nil
}
// Signer holds app's signer configuration.
type Signer struct {
Type string `json:"type"`
Config SignerConfig `json:"config"`
}
// SignerConfig is a configuration that can create a signer.
type SignerConfig interface{}
var (
_ SignerConfig = (*signer.LocalConfig)(nil)
_ SignerConfig = (*signer.VaultConfig)(nil)
)
var signerConfigs = map[string]func() SignerConfig{
"local": func() SignerConfig { return new(signer.LocalConfig) },
"vault": func() SignerConfig { return new(signer.VaultConfig) },
}
// UnmarshalJSON allows Signer to implement the unmarshaler interface to
// dynamically determine the type of the signer config.
func (s *Signer) UnmarshalJSON(b []byte) error {
var signerData struct {
Type string `json:"type"`
Config json.RawMessage `json:"config"`
}
if err := json.Unmarshal(b, &signerData); err != nil {
return fmt.Errorf("parse signer: %v", err)
}
f, ok := signerConfigs[signerData.Type]
if !ok {
return fmt.Errorf("unknown signer type %q", signerData.Type)
}
signerConfig := f()
if len(signerData.Config) != 0 {
data := []byte(signerData.Config)
if featureflags.ExpandEnv.Enabled() {
var rawMap map[string]interface{}
if err := json.Unmarshal(signerData.Config, &rawMap); err != nil {
return fmt.Errorf("unmarshal config for env expansion: %v", err)
}
// Recursively expand environment variables in the map
expandEnvInMap(rawMap)
// Marshal the expanded map back to JSON
expandedData, err := json.Marshal(rawMap)
if err != nil {
return fmt.Errorf("marshal expanded config: %v", err)
}
data = expandedData
}
if err := json.Unmarshal(data, signerConfig); err != nil {
return fmt.Errorf("parse signer config: %v", err)
}
}
if localConfig, ok := signerConfig.(*signer.LocalConfig); ok {
if err := normalizeLocalSignerConfig(localConfig); err != nil {
return fmt.Errorf("parse signer config: %v", err)
}
}
*s = Signer{
Type: signerData.Type,
Config: signerConfig,
}
return nil
}
func normalizeLocalSignerConfig(c *signer.LocalConfig) error {
if c.Algorithm == "" {
c.Algorithm = jose.RS256
return nil
}
if c.Algorithm == jose.RS256 || c.Algorithm == jose.ES256 {
return nil
}
return fmt.Errorf("unsupported local signer algorithm %q", c.Algorithm)
}
// Connector is a magical type that can unmarshal YAML dynamically. The
// Type field determines the connector type, which is then customized for Config.
type Connector struct {
@@ -369,7 +557,8 @@ type Connector struct {
Name string `json:"name"`
ID string `json:"id"`
Config server.ConnectorConfig `json:"config"`
Config server.ConnectorConfig `json:"config"`
GrantTypes []string `json:"grantTypes"`
}
// UnmarshalJSON allows Connector to implement the unmarshaler interface to
@@ -380,9 +569,10 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
Name string `json:"name"`
ID string `json:"id"`
Config json.RawMessage `json:"config"`
Config json.RawMessage `json:"config"`
GrantTypes []string `json:"grantTypes"`
}
if err := json.Unmarshal(b, &conn); err != nil {
if err := configUnmarshaller(b, &conn); err != nil {
return fmt.Errorf("parse connector: %v", err)
}
f, ok := server.ConnectorsConfig[conn.Type]
@@ -395,7 +585,7 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
data := []byte(conn.Config)
if featureflags.ExpandEnv.Enabled() {
var rawMap map[string]interface{}
if err := json.Unmarshal(conn.Config, &rawMap); err != nil {
if err := configUnmarshaller(conn.Config, &rawMap); err != nil {
return fmt.Errorf("unmarshal config for env expansion: %v", err)
}
@@ -412,16 +602,17 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
data = expandedData
}
if err := json.Unmarshal(data, connConfig); err != nil {
if err := configUnmarshaller(data, connConfig); err != nil {
return fmt.Errorf("parse connector config: %v", err)
}
}
*c = Connector{
Type: conn.Type,
Name: conn.Name,
ID: conn.ID,
Config: connConfig,
Type: conn.Type,
Name: conn.Name,
ID: conn.ID,
Config: connConfig,
GrantTypes: conn.GrantTypes,
}
return nil
}
@@ -434,10 +625,11 @@ func ToStorageConnector(c Connector) (storage.Connector, error) {
}
return storage.Connector{
ID: c.ID,
Type: c.Type,
Name: c.Name,
Config: data,
ID: c.ID,
Type: c.Type,
Name: c.Name,
Config: data,
GrantTypes: c.GrantTypes,
}, nil
}
@@ -466,6 +658,12 @@ type Logger struct {
// Format specifies the format to be used for logging.
Format string `json:"format"`
// ExcludeFields specifies log attribute keys that should be dropped from all
// log output. This is useful for suppressing PII fields like email, username,
// preferred_username, or groups in environments subject to GDPR or similar
// data-handling constraints.
ExcludeFields []string `json:"excludeFields"`
}
type RefreshToken struct {
@@ -474,3 +672,72 @@ type RefreshToken struct {
AbsoluteLifetime string `json:"absoluteLifetime"`
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
}
// Sessions holds authentication session configuration.
type Sessions struct {
// CookieName is the name of the session cookie. Defaults to "dex_session".
CookieName string `json:"cookieName"`
// AbsoluteLifetime is the maximum session lifetime from creation. Defaults to "24h".
AbsoluteLifetime string `json:"absoluteLifetime"`
// ValidIfNotUsedFor is the idle timeout. Defaults to "1h".
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
// RememberMeCheckedByDefault controls the default state of the "remember me" checkbox.
RememberMeCheckedByDefault *bool `json:"rememberMeCheckedByDefault"`
// CookieEncryptionKey is the AES key for encrypting session cookies.
// Must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256.
// If empty, cookies are not encrypted.
CookieEncryptionKey string `json:"cookieEncryptionKey"`
// SSOSharedWithDefault is the default SSO sharing policy for clients without explicit ssoSharedWith.
// "all" = share with all clients, "none" = share with no one (default: "none").
SSOSharedWithDefault string `json:"ssoSharedWithDefault"`
}
// MFAAuthenticator defines a multi-factor authentication provider.
type MFAAuthenticator struct {
ID string `json:"id"`
Type string `json:"type"`
Config json.RawMessage `json:"config"`
// ConnectorTypes limits this authenticator to specific connector types (e.g., "ldap", "oidc", "saml").
// If empty, the authenticator applies to all connector types.
ConnectorTypes []string `json:"connectorTypes"`
}
// TOTPConfig holds configuration for a TOTP authenticator.
type TOTPConfig struct {
// Issuer is the name of the service shown in the authenticator app.
Issuer string `json:"issuer"`
}
// WebAuthnConfig holds configuration for a WebAuthn authenticator.
type WebAuthnConfig struct {
// RPDisplayName is the human-readable relying party name shown in the browser
// dialog during key registration and authentication (e.g., "My Company SSO").
RPDisplayName string `json:"rpDisplayName"`
// RPID is the relying party identifier — must match the domain in the browser
// address bar. If empty, derived from the issuer URL hostname.
// Example: "auth.example.com"
RPID string `json:"rpID"`
// RPOrigins is the list of allowed origins for WebAuthn ceremonies.
// If empty, derived from the issuer URL (scheme + host).
// Example: ["https://auth.example.com"]
RPOrigins []string `json:"rpOrigins"`
// AttestationPreference controls what attestation data the authenticator should provide:
// "none" — don't request attestation (simpler, more private)
// "indirect" — authenticator may anonymize attestation (default)
// "direct" — request full attestation (for enterprise key model verification)
AttestationPreference string `json:"attestationPreference"`
// UserVerification controls whether PIN or biometric verification is required:
// "required" — always require (PIN, fingerprint, etc.)
// "preferred" — request if the authenticator supports it (default)
// "discouraged" — skip verification, presence check only
UserVerification string `json:"userVerification"`
// AuthenticatorAttachment restricts which authenticator types are allowed:
// "platform" — built-in only (Touch ID, Windows Hello)
// "cross-platform" — external only (YubiKey, USB security keys)
// "" — any authenticator (default)
AuthenticatorAttachment string `json:"authenticatorAttachment"`
// Timeout is the duration allowed for the browser WebAuthn ceremony
// (registration or login). Defaults to "60s".
Timeout string `json:"timeout"`
}
+227 -4
View File
@@ -1,22 +1,30 @@
package main
import (
"encoding/json"
"log/slog"
"os"
"strings"
"testing"
"github.com/ghodss/yaml"
"github.com/go-jose/go-jose/v4"
"github.com/kylelemons/godebug/pretty"
"github.com/dexidp/dex/connector/mock"
"github.com/dexidp/dex/connector/oidc"
"github.com/dexidp/dex/server"
"github.com/dexidp/dex/server/signer"
"github.com/dexidp/dex/storage"
"github.com/dexidp/dex/storage/sql"
)
var _ = yaml.YAMLToJSON
func boolPtr(v bool) *bool {
return &v
}
func TestValidConfiguration(t *testing.T) {
configuration := Config{
Issuer: "http://127.0.0.1:5556/dex",
@@ -101,6 +109,9 @@ connectors:
- type: mockCallback
id: mock
name: Example
grantTypes:
- authorization_code
- "urn:ietf:params:oauth:grant-type:token-exchange"
- type: oidc
id: google
name: Google
@@ -116,6 +127,12 @@ staticPasswords:
# bcrypt hash of the string "password"
hash: "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
username: "admin"
name: "Admin User"
emailVerified: false
preferredUsername: "admin-public"
groups:
- "team-a"
- "team-a/admins"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
- email: "foo@example.com"
# base64'd value of the same bcrypt hash above. We want to be able to parse both of these
@@ -190,6 +207,10 @@ additionalFeatures: [
ID: "mock",
Name: "Example",
Config: &mock.CallbackConfig{},
GrantTypes: []string{
"authorization_code",
"urn:ietf:params:oauth:grant-type:token-exchange",
},
},
{
Type: "oidc",
@@ -206,10 +227,17 @@ additionalFeatures: [
EnablePasswordDB: true,
StaticPasswords: []password{
{
Email: "admin@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "admin",
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
Email: "admin@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "admin",
Name: "Admin User",
EmailVerified: boolPtr(false),
PreferredUsername: "admin-public",
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
Groups: []string{
"team-a",
"team-a/admins",
},
},
{
Email: "foo@example.com",
@@ -452,3 +480,198 @@ logger:
t.Errorf("got!=want: %s", diff)
}
}
func TestSignerConfigUnmarshal(t *testing.T) {
tests := []struct {
name string
config string
wantErr bool
errContains string
check func(*Config) error
}{
{
name: "local signer with rotation period",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
signer:
type: local
config:
keysRotationPeriod: 6h
enablePasswordDB: true
`,
wantErr: false,
check: func(c *Config) error {
if c.Signer.Type != "local" {
t.Errorf("expected signer type 'local', got %q", c.Signer.Type)
}
if localConfig, ok := c.Signer.Config.(*signer.LocalConfig); !ok {
t.Error("expected LocalConfig")
} else {
if localConfig.KeysRotationPeriod != "6h" {
t.Errorf("expected keys rotation period '6h', got %q", localConfig.KeysRotationPeriod)
}
if localConfig.Algorithm != jose.RS256 {
t.Errorf("expected default algorithm 'RS256', got %q", localConfig.Algorithm)
}
}
return nil
},
},
{
name: "local signer with ES256 algorithm",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
signer:
type: local
config:
keysRotationPeriod: 6h
algorithm: ES256
enablePasswordDB: true
`,
wantErr: false,
check: func(c *Config) error {
localConfig, ok := c.Signer.Config.(*signer.LocalConfig)
if !ok {
t.Error("expected LocalConfig")
return nil
}
if localConfig.Algorithm != jose.ES256 {
t.Errorf("expected algorithm 'ES256', got %q", localConfig.Algorithm)
}
return nil
},
},
{
name: "local signer with invalid algorithm",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
signer:
type: local
config:
keysRotationPeriod: 6h
algorithm: ES512
enablePasswordDB: true
`,
wantErr: true,
errContains: `parse signer config: unsupported local signer algorithm "ES512"`,
},
{
name: "local signer without config",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
signer:
type: local
enablePasswordDB: true
`,
wantErr: false,
check: func(c *Config) error {
localConfig, ok := c.Signer.Config.(*signer.LocalConfig)
if !ok {
t.Error("expected LocalConfig")
return nil
}
if localConfig.Algorithm != jose.RS256 {
t.Errorf("expected default algorithm 'RS256', got %q", localConfig.Algorithm)
}
return nil
},
},
{
name: "vault signer",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
signer:
type: vault
config:
addr: http://localhost:8200
token: test-token
keyName: test-key
enablePasswordDB: true
`,
wantErr: false,
check: func(c *Config) error {
if c.Signer.Type != "vault" {
t.Errorf("expected signer type 'vault', got %q", c.Signer.Type)
}
if vaultConfig, ok := c.Signer.Config.(*signer.VaultConfig); !ok {
t.Error("expected VaultConfig")
} else {
if vaultConfig.Addr != "http://localhost:8200" {
t.Errorf("expected addr 'http://localhost:8200', got %q", vaultConfig.Addr)
}
if vaultConfig.Token != "test-token" {
t.Errorf("expected token 'test-token', got %q", vaultConfig.Token)
}
if vaultConfig.KeyName != "test-key" {
t.Errorf("expected keyName 'test-key', got %q", vaultConfig.KeyName)
}
}
return nil
},
},
{
name: "default to local when no signer specified",
config: `
issuer: http://127.0.0.1:5556/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
enablePasswordDB: true
`,
wantErr: false,
check: func(c *Config) error {
if c.Signer.Type != "" {
t.Errorf("expected signer type '', got %q", c.Signer.Type)
}
return nil
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var c Config
data, err := yaml.YAMLToJSON([]byte(tt.config))
if err != nil {
t.Fatalf("failed to convert yaml to json: %v", err)
}
err = json.Unmarshal(data, &c)
if (err != nil) != tt.wantErr {
t.Errorf("Unmarshal() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.errContains != "" && (err == nil || !strings.Contains(err.Error(), tt.errContains)) {
t.Errorf("Unmarshal() error = %v, want substring %q", err, tt.errContains)
return
}
if err == nil && tt.check != nil {
if err := tt.check(&c); err != nil {
t.Errorf("check failed: %v", err)
}
}
})
}
}
+56
View File
@@ -0,0 +1,56 @@
package main
import (
"context"
"log/slog"
)
// excludingHandler is an slog.Handler wrapper that drops log attributes
// whose keys match a configured set. This allows PII fields like email,
// username, or groups to be redacted at the logger level rather than
// requiring per-callsite suppression logic.
type excludingHandler struct {
inner slog.Handler
exclude map[string]bool
}
func newExcludingHandler(inner slog.Handler, fields []string) slog.Handler {
if len(fields) == 0 {
return inner
}
m := make(map[string]bool, len(fields))
for _, f := range fields {
m[f] = true
}
return &excludingHandler{inner: inner, exclude: m}
}
func (h *excludingHandler) Enabled(ctx context.Context, level slog.Level) bool {
return h.inner.Enabled(ctx, level)
}
func (h *excludingHandler) Handle(ctx context.Context, record slog.Record) error {
// Rebuild the record without excluded attributes.
filtered := slog.NewRecord(record.Time, record.Level, record.Message, record.PC)
record.Attrs(func(a slog.Attr) bool {
if !h.exclude[a.Key] {
filtered.AddAttrs(a)
}
return true
})
return h.inner.Handle(ctx, filtered)
}
func (h *excludingHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
var kept []slog.Attr
for _, a := range attrs {
if !h.exclude[a.Key] {
kept = append(kept, a)
}
}
return &excludingHandler{inner: h.inner.WithAttrs(kept), exclude: h.exclude}
}
func (h *excludingHandler) WithGroup(name string) slog.Handler {
return &excludingHandler{inner: h.inner.WithGroup(name), exclude: h.exclude}
}

Some files were not shown because too many files have changed in this diff Show More