Skip to content

Add Identity support to dev environment #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ plugins:
gofmt:
enabled: true
golint:
enabled: true
enabled: false
exclude_patterns:
- "**/" # exclude all
- "!./cmd/" # unexclude just the ones we want to lint
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ dev/tmp
build_ca_certificate
.vscode/

ci/identity/users.yml

# CLI binaries
conjur
# Exclude binary entrypoint
Expand Down
31 changes: 31 additions & 0 deletions ci/identity/policy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
- !policy
id: conjur
body:
- !policy
id: authn-oidc
body:
- !policy
id: identity
body:
- !webservice

- !variable provider-uri
- !variable client-id
- !variable client-secret

# URI of Conjur instance
- !variable redirect_uri

# Defines the JWT claim to use as the Conjur identifier
- !variable claim-mapping

# Group with permission to authenticate
- !group
id: authenticatable
annotations:
description: Users who can authenticate using this authenticator

- !permit
role: !group authenticatable
privilege: [ read, authenticate ]
resource: !webservice
9 changes: 9 additions & 0 deletions ci/identity/secrets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ci:
IDENTITY_CLIENT_ID: !var ci/identity/app/client-id
IDENTITY_CLIENT_SECRET: !var ci/identity/app/client-secret
IDENTITY_PROVIDER_URI: !var ci/identity/app/provider-uri

development:
IDENTITY_CLIENT_ID: !var dev/identity/app/client-id
IDENTITY_CLIENT_SECRET: !var dev/identity/app/client-secret
IDENTITY_PROVIDER_URI: !var dev/identity/app/provider-uri
7 changes: 7 additions & 0 deletions ci/identity/users.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Users with permission to authenticate
- !user {{ IDENTITY_USERNAME }}

- !grant
members:
- !user {{ IDENTITY_USERNAME }}
role: !group conjur/authn-oidc/identity/authenticatable
1 change: 1 addition & 0 deletions dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ services:
environment:
- OKTA_USERNAME=${OKTA_USERNAME:-user}
- OKTA_PASSWORD=${OKTA_PASSWORD:-password}
- IDENTITY_USERNAME=${IDENTITY_USERNAME:-user}
command: bash -c "cd ${PWD}/..; make install; sleep infinity"
working_dir: ${PWD}/..
restart: on-failure
Expand Down
160 changes: 95 additions & 65 deletions dev/start
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ source "../ci/keycloak/keycloak_functions.sh"
# TODO: add a prompt and an -f flag to give the user control over destroying an already existing development environment.
# It can be such a pain to mistakenly destroy your environment.

ENABLE_AUTHN_OIDC=false
ENABLE_OIDC_KEYCLOAK=false
ENABLE_OIDC_OKTA=false
ENABLE_OIDC_IDENTITY=false
export IDENTITY_USERNAME=""

# Minimal set of services. We add to this list based on cmd line flags.
services=(pg conjur proxy cli-dev)
Expand Down Expand Up @@ -111,7 +113,7 @@ EOL
echo
echo "Setting up authenticators"

init_oidc
configure_oidc_providers

# Updates CONJUR_AUTHENTICATORS and restarts required services.
start_auth_services
Expand All @@ -127,11 +129,16 @@ EOL
docker-compose exec cli-dev bash -c 'conjur logout
conjur init --force-netrc --force -u http://conjur -i -a dev -t oidc --service-id okta-2
conjur login -i $OKTA_USERNAME -p $OKTA_PASSWORD'
elif [ "$ENABLE_AUTHN_OIDC" = true ]; then
elif [ "$ENABLE_OIDC_KEYCLOAK" = true ]; then
echo "Setting up Conjur for OIDC (Keycloak)"
docker-compose exec cli-dev bash -c 'conjur logout
conjur init --force-netrc --force -u http://conjur -i -a dev -t oidc --service-id keycloak
conjur login -i alice -p alice'
elif [ "$ENABLE_OIDC_IDENTITY" = true ]; then
echo "Setting up Conjur for OIDC (Identity)"
docker-compose exec cli-dev bash -c 'conjur logout
conjur init --force-netrc --force -u http://conjur -i -a dev -t oidc --service-id identity
conjur login -i $IDENTITY_USERNAME'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it assumed that a developer will be using their own account as IDENTITY_USERNAME and providing their own password?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's the idea. Feel free to to test it out, all C&I team should have Identity access now.

fi

echo
Expand All @@ -141,8 +148,10 @@ conjur login -i alice -p alice'
parse_options() {
while true ; do
case "$1" in
--authn-oidc ) ENABLE_AUTHN_OIDC=true ; shift ;;
--oidc-keycloak ) ENABLE_OIDC_KEYCLOAK=true ; shift ;;
--oidc-okta ) ENABLE_OIDC_OKTA=true ; shift ;;
--oidc-identity ) ENABLE_OIDC_IDENTITY=true ; shift ;;
--identity-user ) IDENTITY_USERNAME="$2" ; shift ; shift ;;
# -h | --help ) print_help ; shift ;;
* )
if [ -z "$1" ]; then
Expand All @@ -153,6 +162,11 @@ parse_options() {
fi ;;
esac
done

if [[ $ENABLE_OIDC_IDENTITY = true && -z "$IDENTITY_USERNAME" ]]; then
echo "Flag --oidc-identity must be paired with flag --identity-user. See --help."
exit
fi
}

start_conjur_server() {
Expand Down Expand Up @@ -183,93 +197,109 @@ client_add_secret() {
configure_oidc_providers() {
# Start conjur again, since it is recreating by docker-compose because of
# dependency with keycloak
if [[ $ENABLE_OIDC_KEYCLOAK = true ]]; then
echo "Configuring Keycloak provider"
setup_keycloak
fi

if [[ $ENABLE_OIDC_OKTA = true ]]; then
echo "Configuring Okta provider"
setup_okta
fi

if [[ $ENABLE_OIDC_IDENTITY = true ]]; then
echo "Configuring Identity provider"
setup_identity
fi

enable_oidc_authenticators
}

setup_keycloak() {
services+=(keycloak)
docker-compose up -d --no-deps "${services[@]}"
start_conjur_server
wait_for_keycloak_server
fetch_keycloak_certificate
configure_oidc_authenticators
enable_oidc_authenticators
setup_oidc_client "keycloak" "https://keycloak:8443/auth/realms/master" "conjurClient" "1234" "email"
create_keycloak_users
echo "keycloak admin console url: http://0.0.0.0:7777/auth/admin"
}

configure_oidc_authenticators() {
echo "Setting Keycloak policy and variables values in Conjur"
client_load_policy "../ci/keycloak/policy.yml"

client_add_secret 'conjur/authn-oidc/keycloak/provider-uri' 'https://keycloak:8443/auth/realms/master'
client_add_secret 'conjur/authn-oidc/keycloak/client-id' 'conjurClient'
client_add_secret 'conjur/authn-oidc/keycloak/client-secret' '1234'
client_add_secret 'conjur/authn-oidc/keycloak/claim-mapping' 'email'
client_add_secret 'conjur/authn-oidc/keycloak/redirect_uri' 'http://127.0.0.1:8888/callback'
setup_okta() {
check_environment_variables "OKTA_PROVIDER_URI" "OKTA_CLIENT_ID" "OKTA_CLIENT_SECRET"
setup_oidc_client "okta-2" "${OKTA_PROVIDER_URI}oauth2/default" \
"${OKTA_CLIENT_ID}" "${OKTA_CLIENT_SECRET}" "preferred_username"
}

client_load_policy "../ci/keycloak/users.yml"
setup_identity() {
check_environment_variables "IDENTITY_PROVIDER_URI" "IDENTITY_CLIENT_ID" "IDENTITY_CLIENT_SECRET"
generate_identity_policy
setup_oidc_client "identity" "${IDENTITY_PROVIDER_URI}" \
"${IDENTITY_CLIENT_ID}" "${IDENTITY_CLIENT_SECRET}" "email"
}

if [[ $ENABLE_OIDC_OKTA = true ]]; then
echo "Confuring Okta policy and variables values in Conjur"
client_load_policy "../ci/okta/policy.yml"
setup_oidc_client() {
service_id="$1"
provider_uri="$2"
client_id="$3"
client_secret="$4"
claim_mapping="$5"

local okta_valid=true
if [[ -z "$OKTA_PROVIDER_URI" ]]; then
echo "OKTA_PROVIDER_URI is not set"
okta_valid=false
fi
trim_service_id="${service_id%-*}"
echo "Setting $service_id policy and variable values in Conjur"

if [[ -z "$OKTA_CLIENT_ID" ]]; then
echo "OKTA_CLIENT_ID is not set"
okta_valid=false
fi
client_load_policy "../ci/$trim_service_id/policy.yml"

if [[ -z "$OKTA_CLIENT_SECRET" ]]; then
echo "OKTA_CLIENT_SECRET is not set"
okta_valid=false
fi
client_add_secret "conjur/authn-oidc/$service_id/provider-uri" "$provider_uri"
client_add_secret "conjur/authn-oidc/$service_id/client-id" "$client_id"
client_add_secret "conjur/authn-oidc/$service_id/client-secret" "$client_secret"
client_add_secret "conjur/authn-oidc/$service_id/claim-mapping" "$claim_mapping"
client_add_secret "conjur/authn-oidc/$service_id/redirect_uri" "http://127.0.0.1:8888/callback"

if [[ $okta_valid = true ]]; then
# Replace these okta values with your own if not using Summon
client_add_secret 'conjur/authn-oidc/okta-2/provider-uri' "${OKTA_PROVIDER_URI}oauth2/default"
client_add_secret 'conjur/authn-oidc/okta-2/client-id' "$OKTA_CLIENT_ID"
client_add_secret 'conjur/authn-oidc/okta-2/client-secret' "$OKTA_CLIENT_SECRET"
else
echo "Skipped Okta configuration due to missing environment variables"
fi
client_load_policy "../ci/$trim_service_id/users.yml"
}

function generate_identity_policy() {
echo "Generating policy for AuthnOIDC V2 service 'identity' and user '$IDENTITY_USERNAME'"
policy_dir="../ci/identity"
rm -f "$policy_dir/users.yml"
sed -e "s#{{ IDENTITY_USERNAME }}#$IDENTITY_USERNAME#g" "$policy_dir/users.template.yml" > "$policy_dir/users.yml"
}

client_add_secret 'conjur/authn-oidc/okta-2/claim-mapping' 'preferred_username'
client_add_secret 'conjur/authn-oidc/okta-2/redirect_uri' 'http://127.0.0.1:8888/callback'
check_environment_variables() {
vars=("$@")
local valid=true
for i in "${vars[@]}"
do
if [[ -z "${!i}" ]]; then
echo "${i} is not set"
valid=false
fi
done

client_load_policy "../ci/okta/users.yml"
if [[ $valid = false ]]; then
exit 1
fi
}

enable_oidc_authenticators() {
echo "Configuring Keycloak as OpenID provider for automatic testing"
# We enable an OIDC authenticator without a service-id to test that it's
# invalid.
enabled_authenticators="$enabled_authenticators,authn-oidc/keycloak"
if [[ $ENABLE_OIDC_KEYCLOAK = true ]]; then
echo "Configuring Keycloak as OpenID provider for automatic testing"
# We enable an OIDC authenticator without a service-id to test that it's
# invalid.
enabled_authenticators="$enabled_authenticators,authn-oidc/keycloak"
fi

if [[ $ENABLE_OIDC_OKTA = true ]]; then
echo "Configuring OKTA as OpenID provider for manual testing"
echo "Configuring Okta as OpenID provider for manual testing"
enabled_authenticators="$enabled_authenticators,authn-oidc/okta-2"
fi
}

init_oidc() {
# # ADFS and OKTA make no sense without OIDC.
# if [[ $ENABLE_AUTHN_OIDC = false &&
# ($ENABLE_OIDC_ADFS = true || $ENABLE_OIDC_OKTA = true) ]]
# then
# echo "Error: --oidc-adfs and --oidc-okta both require --authn-oidc"
# exit 1
# fi

if [[ $ENABLE_AUTHN_OIDC != true ]]; then
return
if [[ $ENABLE_OIDC_IDENTITY = true ]]; then
echo "Configuring Identity as OpenID provider for manual testing"
enabled_authenticators="$enabled_authenticators,authn-oidc/identity"
fi

services+=(keycloak)
docker-compose up -d --no-deps "${services[@]}"

configure_oidc_providers
}

start_auth_services() {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/zalando/go-keyring v0.2.2 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.4.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ github.com/zalando/go-keyring v0.2.2 h1:f0xmpYiSrHtSNAVgwip93Cg8tuF45HJM6rHq/A5R
github.com/zalando/go-keyring v0.2.2/go.mod h1:sI3evg9Wvpw3+n4SqplGSJUMwtDeROfD4nsFz4z9PG0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand Down
Loading