Skip to content

Commit

Permalink
[DDO-3785] OIDC (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-r-warren authored Jul 25, 2024
1 parent ac76150 commit 123f9a8
Show file tree
Hide file tree
Showing 38 changed files with 2,500 additions and 47 deletions.
2 changes: 1 addition & 1 deletion go-shared/go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/broadinstitute/sherlock/go-shared

go 1.21
go 1.22

require github.com/google/go-cmp v0.6.0
2 changes: 1 addition & 1 deletion sherlock-go-client/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/broadinstitute/sherlock/sherlock-go-client

go 1.21
go 1.22

require (
github.com/go-openapi/errors v0.22.0
Expand Down
2 changes: 1 addition & 1 deletion sherlock-webhook-proxy/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/broadinstitute/sherlock/sherlock-webhook-proxy

go 1.21
go 1.22

require (
github.com/GoogleCloudPlatform/functions-framework-go v1.8.1
Expand Down
18 changes: 11 additions & 7 deletions sherlock/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
ARG GO_VERSION='1.21'
ARG ALPINE_VERSION='3.19'
ARG GO_VERSION='1.22'

FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS build
# https://github.com/microsoft/go-images/tree/microsoft/main
FROM mcr.microsoft.com/oss/go/microsoft/golang:${GO_VERSION}-fips-cbl-mariner2.0 AS build
ARG BUILD_VERSION='development'
WORKDIR /build/sherlock
ENV CGO_ENABLED=0
ENV GOBIN=/bin
ENV CGO_ENABLED=1

COPY sherlock/go.mod sherlock/go.sum ./
COPY go-shared ../go-shared/
Expand All @@ -14,8 +13,13 @@ RUN go mod download && go mod verify
COPY sherlock ./
RUN go build -buildvcs=false -ldflags="-X 'github.com/broadinstitute/sherlock/go-shared/pkg/version.BuildVersion=${BUILD_VERSION}'" -o /bin/sherlock ./cmd/...

# FROM alpine:${ALPINE_VERSION} as runtime <-- use this if you hit issues
FROM gcr.io/distroless/static:nonroot AS runtime
# Check that the binary is FIPS-capable, fail if not
RUN go get github.com/acardace/fips-detect && \
go run github.com/acardace/fips-detect /bin/sherlock \
| grep -E 'FIPS-capable Go binary.*Yes'

# https://mcr.microsoft.com/en-us/product/cbl-mariner/distroless/minimal/about
FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0-nonroot AS runtime

COPY --from=build /bin/sherlock /bin/sherlock
ENTRYPOINT [ "/bin/sherlock" ]
62 changes: 62 additions & 0 deletions sherlock/config/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,56 @@ db:
ignoreNotFoundWarning: true
level: warn

# Configures Sherlock's own OIDC provider, not to be confused with its capability to interpret tokens
# from IAP or GitHub Actions.
oidc:
enable: true
# The issuer URL of Sherlock itself. This should be scheme + host + "/oidc", because Sherlock
# serves its own OIDC provider at that sub-path. This should also generally be an in-cluster
# address, because the IAP in front of the public endpoints isn't in-spec. This is fine as long
# as we just use Sherlock as an in-cluster authorization service.
#
# An example is https://sherlock-api-service.sherlock.svc.cluster.local/oidc
issuerUrl: http://localhost:8080/oidc
# The *public* side of Sherlock's OIDC issuer. This should be a normally-accessible URL that should
# go to the same destination as issuerUrl above. This is automatically used in the OIDC discovery
# config to tell clients how to have *users* authenticate against Sherlock. The downstream system
# will talk to issuerUrl in-cluster, but end-users will need to talk to publicIssuerUrl.
#
# An example is https://sherlock.dsp-devops-prod.broadinstitute.org/oidc
publicIssuerUrl: http://localhost:8080/oidc

# The key that Sherlock should use to AES-256 encrypt internal data it sends to clients. This is
# used in two places by the underlying OIDC library:
# 1. Encrypting "{Token.ID}:{User.ID}" to create access tokens returned to clients
# 2. Encrypting "{AuthRequest.ID}" to create authorization codes returned to clients
# This does need to be rotated but doing so is potentially disruptive; Sherlock will cease
# respecting access tokens or authorization codes it has issued.
#
# Sherlock will error on boot if this doesn't parse from a hex string to 32 bytes. You'll probably
# want to pass this in the environment with SHERLOCK_oidc_encryptionKeyHex. It should be passed
# in hex format.
encryptionKeyHex: 7265706c6163652d6d652d776974682d33322d627974652d6b65792d2d2d2d2d # "replace-me-with-32-byte-key----"
# The duration that ID and access tokens vended to clients should be valid for.
tokenDuration: 15m
# The duration that refresh tokens vended to clients should be valid for.
refreshTokenDuration: 30m
# The duration that a particular signing key should be used before being rotated.
signingKeyPrimaryDuration: 4h
# The time after which a signing key should be deleted (and its signatures no longer accepted)
# after it has been rotated. This should be longer than all token durations so that we
# continue to respect our own signatures until they'd expire on their own.
signingKeyPostRotationDuration: 2h
# When enabled, Sherlock will use Google Cloud KMS to symmetrically encrypt the private keys
# it stores in its own database. This is a defense-in-depth measure to prevent key leakage in
# the event of SQL injection or other database compromise.
#
# This must be true when mode is not "debug".
signingKeyEncryptionKMSEnable: false
# The fully-qualified name of the KMS key to use when signingKeyEncryptionKMSEnable is true.
signingKeyEncryptionKMSKeyName: projects/some-project/locations/some-location/keyRings/some-key-ring/cryptoKeys/some-key


auth:
githubActionsOIDC:
issuer: https://token.actions.githubusercontent.com
Expand Down Expand Up @@ -217,6 +267,18 @@ argoCd:
environmentUrlFormatString: https://argocd.dsp-devops-prod.broadinstitute.org/applications?showFavorites=false&proj=&sync=&health=&namespace=&cluster=&labels=env%%253D%s

model:
roles:
# When set, Sherlock won't ever report an Environment/Cluster RequiredRole field as being null.
# Instead, it will substitute this value in its place (even though it won't be stored in the database).
# This can be useful in that it means downstream consumers don't need null handling like
# `requiredRole ?? "all-users"`. While that's simple, it's actually easier at a security/compliance
# level to say that Sherlock defines it and anything else uses it verbatim. (This was a specific
# request from appsec for this reason`.)
#
# Even if this is set, Sherlock will allow setting the field to empty to clear it out -- but will then
# respond in the API as if it's been set to this value. Note that the role set here needs to already
# exist or downstream consumers could have issues.
substituteEmptyRequiredRoleWithValue:
environments:
templates:
# Uses appVersionResolver = "none", chartVersionResolver = "latest", and helmfileRef = "HEAD"
Expand Down
2 changes: 2 additions & 0 deletions sherlock/config/test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pactbroker:
enable: false

model:
roles:
substituteEmptyRequiredRoleWithValue: all-users
environments:
templates:
autoPopulateCharts:
Expand Down
11 changes: 11 additions & 0 deletions sherlock/db/migrations/000095_oidc.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
drop table signing_keys;

drop table tokens;

drop table refresh_tokens;

drop table auth_request_codes;

drop table auth_requests;

drop table clients;
98 changes: 98 additions & 0 deletions sherlock/db/migrations/000095_oidc.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
create table clients
(
id text not null
primary key,
client_secret_hash bytea,
client_secret_salt bytea,
client_secret_iterations bigint,
client_redirect_uris text,
client_post_logout_redirect_uris text,
client_application_type text,
client_auth_method text,
client_id_token_lifetime bigint,
client_dev_mode boolean,
client_clock_skew bigint
);

create table auth_requests
(
id text not null
primary key,
created_at timestamp with time zone,
done_at timestamp with time zone,
client_id text
constraint fk_auth_requests_client
references clients
on update cascade on delete cascade,
nonce text,
redirect_uri text,
response_type text,
response_mode text,
scopes text,
state text,
code_challenge text,
code_challenge_method text,
user_id bigint
constraint fk_auth_requests_user
references users
on update cascade on delete cascade
);

create table auth_request_codes
(
code text not null
primary key,
created_at timestamp with time zone,
auth_request_id text
constraint fk_auth_request_codes_auth_request
references auth_requests
on update cascade on delete cascade
);

create table refresh_tokens
(
id text not null
primary key,
created_at timestamp with time zone,
token_hash bytea unique,
client_id text
constraint fk_refresh_tokens_client
references clients
on update cascade on delete cascade,
scopes text,
original_auth_at timestamp with time zone,
user_id bigint
constraint fk_refresh_tokens_user
references users
on update cascade on delete cascade
);

create table tokens
(
id text not null
primary key,
created_at timestamp with time zone,
refresh_token_id text
constraint fk_tokens_refresh_token
references refresh_tokens
on update cascade on delete cascade,
client_id text
constraint fk_tokens_client
references clients
on update cascade on delete cascade,
scopes text,
expiry timestamp with time zone,
user_id bigint
constraint fk_tokens_user
references users
on update cascade on delete cascade
);

create table signing_keys
(
id text not null
primary key,
created_at timestamp with time zone,
public_key bytea,
private_key bytea
);
35 changes: 27 additions & 8 deletions sherlock/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
module github.com/broadinstitute/sherlock/sherlock

go 1.21
go 1.22

toolchain go1.22.5

require (
cloud.google.com/go/cloudsqlconn v1.11.1
cloud.google.com/go/kms v1.18.3
contrib.go.opencensus.io/exporter/prometheus v0.4.2
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
github.com/PagerDuty/go-pagerduty v1.8.0
Expand All @@ -13,6 +16,7 @@ require (
github.com/dustinkirkland/golang-petname v0.0.0-20230626224747-e794b9370d49
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0
github.com/go-jose/go-jose/v4 v4.0.2
github.com/golang-migrate/migrate/v4 v4.17.1
github.com/google/go-cmp v0.6.0
github.com/google/go-github/v58 v58.0.0
Expand All @@ -29,10 +33,13 @@ require (
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.3
github.com/zitadel/oidc/v3 v3.26.0
go.opencensus.io v0.24.0
golang.org/x/crypto v0.25.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/net v0.27.0
golang.org/x/oauth2 v0.21.0
golang.org/x/text v0.16.0
google.golang.org/api v0.188.0
gorm.io/datatypes v1.2.1
gorm.io/driver/postgres v1.5.9
Expand All @@ -42,15 +49,19 @@ require (
replace github.com/broadinstitute/sherlock/go-shared => ../go-shared

require (
cloud.google.com/go v0.115.0 // indirect
cloud.google.com/go/auth v0.7.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
cloud.google.com/go/compute/metadata v0.4.0 // indirect
cloud.google.com/go/iam v1.1.10 // indirect
cloud.google.com/go/longrunning v0.5.9 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
Expand All @@ -62,9 +73,10 @@ require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-chi/chi/v5 v5.1.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
Expand All @@ -82,6 +94,7 @@ require (
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand Down Expand Up @@ -116,6 +129,8 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/muhlemmer/gu v0.3.1 // indirect
github.com/muhlemmer/httpforwarded v0.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand All @@ -125,26 +140,30 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/prometheus/statsd_exporter v0.22.8 // indirect
github.com/rs/cors v1.11.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/std-uritemplate/std-uritemplate/go v0.0.57 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/zitadel/logging v0.6.0 // indirect
github.com/zitadel/schema v1.3.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect
google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect
google.golang.org/grpc v1.64.1 // indirect
google.golang.org/protobuf v1.34.2 // indirect
Expand Down
Loading

0 comments on commit 123f9a8

Please sign in to comment.