Skip to content

Commit

Permalink
Merge pull request #2920 from cyberark/oidc-ca-cert-config
Browse files Browse the repository at this point in the history
Add optional ca-cert variable to authn-oidc and retrieval functions
  • Loading branch information
gl-johnson authored Aug 31, 2023
2 parents afe87cb + 31143d5 commit 4c9b632
Show file tree
Hide file tree
Showing 23 changed files with 195 additions and 41 deletions.
3 changes: 2 additions & 1 deletion app/domain/authentication/authn_azure/authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def decoded_token
claims_to_verify: {
verify_iss: true,
iss: provider_uri
}
},
ca_cert: nil
),
logger: @logger
)
Expand Down
3 changes: 2 additions & 1 deletion app/domain/authentication/authn_azure/validate_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def required_variable_names

def validate_provider_is_responsive
@discover_identity_provider.(
provider_uri: provider_uri
provider_uri: provider_uri,
ca_cert: nil
)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def decoded_token
iss: PROVIDER_URI,
verify_iat: true,
verify_expiration: true
}
},
ca_cert: nil
),
logger: @logger
)
Expand Down
3 changes: 2 additions & 1 deletion app/domain/authentication/authn_gcp/validate_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def call

def validate_provider_is_responsive
@discover_identity_provider.(
provider_uri: PROVIDER_URI
provider_uri: PROVIDER_URI,
ca_cert: nil
)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def discover_provider

def discovered_provider
@discovered_provider ||= @discover_identity_provider.call(
provider_uri: @provider_uri
provider_uri: @provider_uri,
ca_cert: nil
)
end

Expand Down
3 changes: 2 additions & 1 deletion app/domain/authentication/authn_oidc/authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def status(authenticator_status_input:)
# If successful, validate the new set of required variables
if authenticator.present?
Authentication::AuthnOidc::ValidateStatus.new(
required_variable_names: %w[provider-uri client-id client-secret claim-mapping]
required_variable_names: %w[provider-uri client-id client-secret claim-mapping],
optional_variable_names: %w[ca-cert]
).(
account: authenticator_status_input.account,
service_id: authenticator_status_input.service_id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module AuthnOidc

UpdateInputWithUsernameFromIdToken ||= CommandClass.new(
dependencies: {
fetch_authenticator_secrets: Authentication::Util::FetchAuthenticatorSecrets.new,
validate_account_exists: ::Authentication::Security::ValidateAccountExists.new,
verify_and_decode_token: ::Authentication::OAuth::VerifyAndDecodeToken.new,
logger: Rails.logger
Expand Down Expand Up @@ -40,7 +39,8 @@ def verify_and_decode_token
@decoded_token = @verify_and_decode_token.(
provider_uri: oidc_authenticator_secrets["provider-uri"],
token_jwt: decoded_credentials["id_token"],
claims_to_verify: {} # We don't verify any claims
claims_to_verify: {}, # We don't verify any claims
ca_cert: oidc_authenticator_secrets["ca-cert"]
)
end

Expand Down Expand Up @@ -86,7 +86,9 @@ def token_from_body
end

def oidc_authenticator_secrets
@oidc_authenticator_secrets ||= @fetch_authenticator_secrets.(
@oidc_authenticator_secrets ||= Authentication::Util::FetchAuthenticatorSecrets.new(
optional_variable_names: optional_variable_names
).(
service_id: service_id,
conjur_account: account,
authenticator_name: authenticator_name,
Expand All @@ -98,6 +100,10 @@ def required_variable_names
@required_variable_names ||= %w[provider-uri id-token-user-property]
end

def optional_variable_names
@optional_variable_names ||= %w[ca-cert]
end

def validate_conjur_username
if conjur_username.to_s.empty?
raise Errors::Authentication::AuthnOidc::IdTokenClaimNotFoundOrEmpty.new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module DataObjects
class Authenticator

REQUIRED_VARIABLES = %i[provider_uri client_id client_secret claim_mapping].freeze
OPTIONAL_VARIABLES = %i[redirect_uri response_type provider_scope name token_ttl].freeze
OPTIONAL_VARIABLES = %i[redirect_uri response_type provider_scope name token_ttl ca_cert].freeze

attr_reader(
:provider_uri,
Expand All @@ -15,7 +15,8 @@ class Authenticator
:account,
:service_id,
:redirect_uri,
:response_type
:response_type,
:ca_cert
)

def initialize(
Expand All @@ -29,7 +30,8 @@ def initialize(
name: nil,
response_type: 'code',
provider_scope: nil,
token_ttl: 'PT60M'
token_ttl: 'PT60M',
ca_cert: nil
)
@account = account
@provider_uri = provider_uri
Expand All @@ -42,6 +44,7 @@ def initialize(
@provider_scope = provider_scope
@redirect_uri = redirect_uri
@token_ttl = token_ttl
@ca_cert = ca_cert
end

def scope
Expand Down
15 changes: 11 additions & 4 deletions app/domain/authentication/authn_oidc/validate_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module AuthnOidc

ValidateStatus = CommandClass.new(
dependencies: {
fetch_authenticator_secrets: Authentication::Util::FetchAuthenticatorSecrets.new,
discover_identity_provider: Authentication::OAuth::DiscoverIdentityProvider.new,
required_variable_names: %w[provider-uri id-token-user-property]
required_variable_names: %w[provider-uri id-token-user-property],
optional_variable_names: %w[ca-cert]
},
inputs: %i[account service_id]
) do
Expand All @@ -26,7 +26,9 @@ def validate_secrets
end

def oidc_authenticator_secrets
@oidc_authenticator_secrets ||= @fetch_authenticator_secrets.(
@oidc_authenticator_secrets ||= Authentication::Util::FetchAuthenticatorSecrets.new(
optional_variable_names: @optional_variable_names
).(
service_id: @service_id,
conjur_account: @account,
authenticator_name: "authn-oidc",
Expand All @@ -36,13 +38,18 @@ def oidc_authenticator_secrets

def validate_provider_is_responsive
@discover_identity_provider.(
provider_uri: provider_uri
provider_uri: provider_uri,
ca_cert: ca_cert
)
end

def provider_uri
@oidc_authenticator_secrets["provider-uri"]
end

def ca_cert
@oidc_authenticator_secrets["ca-cert"]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module OAuth
logger: Rails.logger,
open_id_discovery_service: OpenIDConnect::Discovery::Provider::Config
},
inputs: %i[provider_uri]
inputs: %i[provider_uri ca_cert]
) do
def call
log_provider_uri
Expand Down
5 changes: 3 additions & 2 deletions app/domain/authentication/o_auth/fetch_provider_keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module OAuth
logger: Rails.logger,
discover_identity_provider: DiscoverIdentityProvider.new
},
inputs: %i[provider_uri]
inputs: %i[provider_uri ca_cert]
) do
def call
discover_provider
Expand All @@ -23,7 +23,8 @@ def discover_provider

def discovered_provider
@discovered_provider ||= @discover_identity_provider.(
provider_uri: @provider_uri
provider_uri: @provider_uri,
ca_cert: @ca_cert
)
end

Expand Down
5 changes: 3 additions & 2 deletions app/domain/authentication/o_auth/verify_and_decode_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module OAuth
verify_and_decode_token: ::Authentication::Jwt::VerifyAndDecodeToken.new,
logger: Rails.logger
},
inputs: %i[provider_uri token_jwt claims_to_verify]
inputs: %i[provider_uri token_jwt claims_to_verify ca_cert]
) do
def call
fetch_provider_keys
Expand All @@ -35,7 +35,8 @@ def call
def fetch_provider_keys(force_read: false)
provider_keys = @fetch_provider_keys.call(
provider_uri: @provider_uri,
refresh: force_read
refresh: force_read,
ca_cert: @ca_cert
)

@jwks = provider_keys.jwks
Expand Down
26 changes: 18 additions & 8 deletions app/domain/authentication/util/fetch_authenticator_secrets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,35 @@ module Util

FetchAuthenticatorSecrets = CommandClass.new(
dependencies: {
fetch_secrets: ::Conjur::FetchRequiredSecrets.new
fetch_required_secrets: ::Conjur::FetchRequiredSecrets.new,
fetch_optional_secrets: ::Conjur::FetchOptionalSecrets.new,
optional_variable_names: []
},
inputs: %i[conjur_account authenticator_name service_id required_variable_names]
) do
def call
@required_variable_names.each_with_object({}) do |variable_name, secrets|
full_variable_name = full_variable_name(variable_name)
secrets[variable_name] = required_secrets[full_variable_name]
end
secret_map_for(required_secrets).merge(secret_map_for(optional_secrets))
end

private

def required_secrets
@required_secrets ||= @fetch_secrets.(resource_ids: required_resource_ids)
@required_secrets ||= @fetch_required_secrets.(resource_ids: resource_ids_for(@required_variable_names))
end

def optional_secrets
@optional_secrets ||= @fetch_optional_secrets.(resource_ids: resource_ids_for(@optional_variable_names))
end

def secret_map_for(secret_values)
secret_values.each_with_object({}) do |(full_name, value), secrets|
short_name = full_name.to_s.split('/')[-1]
secrets[short_name] = value
end
end

def required_resource_ids
@required_variable_names.map { |var_name| full_variable_name(var_name) }
def resource_ids_for(variable_names)
variable_names.map { |var_name| full_variable_name(var_name) }
end

def full_variable_name(var_name)
Expand Down
31 changes: 31 additions & 0 deletions app/domain/conjur/fetch_optional_secrets.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'command_class'

module Conjur

FetchOptionalSecrets ||= CommandClass.new(
dependencies: { resource_class: ::Resource },
inputs: [:resource_ids]
) do
def call
secret_values
end

private

def secret_values
secrets.transform_values do |secret|
secret ? secret.value : nil
end
end

def resources
@resources ||= @resource_ids.map { |id| [id, @resource_class[id]] }.to_h
end

def secrets
@secrets ||= resources.transform_values do |resource|
resource ? resource.secret : nil
end
end
end
end
1 change: 0 additions & 1 deletion ci/oauth/keycloak/fetch_certificate
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ openssl s_client \
>/etc/ssl/certs/keycloak.pem

hash=$(openssl x509 -hash -in /etc/ssl/certs/keycloak.pem -out /dev/null)

ln -s /etc/ssl/certs/keycloak.pem "/etc/ssl/certs/${hash}.0" || true
3 changes: 3 additions & 0 deletions ci/test_suites/authenticators_oidc/policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
- !variable
id: id-token-user-property

- !variable
id: ca-cert

- !group
id: users
annotations:
Expand Down
8 changes: 8 additions & 0 deletions dev/policies/authenticators/authn-oidc/keycloak2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
- !policy
id: keycloak2
body:
- !webservice
id: status
annotations:
description: Status service to check that the authenticator is configured correctly

- !webservice

- !variable provider-uri
Expand All @@ -16,6 +21,9 @@
# URI of Conjur instance
- !variable redirect_uri

# Defines the cert chain to be used for TLS verification
- !variable ca-cert

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

Expand Down
7 changes: 7 additions & 0 deletions dev/start
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ENABLE_OIDC_KEYCLOAK=false
ENABLE_OIDC_OKTA=false
ENABLE_ROTATORS=false
IDENTITY_USER=""
COMPOSE="docker compose"

declare -a required_envvars
required_envvars[identity]="IDENTITY_CLIENT_ID IDENTITY_CLIENT_SECRET IDENTITY_PROVIDER_URI"
Expand Down Expand Up @@ -300,6 +301,9 @@ configure_oidc_v1() {
client_load_policy "/src/conjur-server/$policy_path"
client_add_secret "conjur/authn-oidc/$service_id/provider-uri" "$provider_uri"
client_add_secret "conjur/authn-oidc/$service_id/id-token-user-property" "$token_property"
if [ "$service_id" = "keycloak" ]; then
client_add_secret "conjur/authn-oidc/$service_id/ca-cert" "$($COMPOSE exec conjur cat /etc/ssl/certs/keycloak.pem)"
fi
}

configure_oidc_v2() {
Expand All @@ -315,6 +319,9 @@ configure_oidc_v2() {
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://localhost:3000/authn-oidc/$service_id/cucumber/authenticate"
if [ "$service_id" = "keycloak2" ]; then
client_add_secret "conjur/authn-oidc/$service_id/ca-cert" "$($COMPOSE exec conjur cat /etc/ssl/certs/keycloak.pem)"
fi

client_load_policy "/src/conjur-server/dev/policies/authenticators/authn-oidc/$service_id-users.yml"
}
Expand Down
Loading

0 comments on commit 4c9b632

Please sign in to comment.