Skip to content
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

AuthnOIDC V2: write custom certs to non-default directory #2988

Merged
merged 4 commits into from
Oct 13, 2023

Conversation

john-odonnell
Copy link
Contributor

@john-odonnell john-odonnell commented Oct 11, 2023

Desired Outcome

Authn-OIDC with ca-cert variable fails on Conjur Enterprise.

Errno::EACCES: Permission denied @ rb_file_s_symlink - (/tmp/d20231006-289-9u7rno/conjur-oidc-client.0.pem, /usr/lib/ssl/certs/bb3ed97b.0)

When Authn-OIDC V2 is configured with a ca-cert variable, it writes the provided certificate content into a temporary file, and creates a symlink to the file in the Conjur container's default certificate directory, meaning it would be trusted for outbound requests to the configured OIDC provider. After a successful request, the symlinks are deleted, and the temp files destroyed.

In Conjur Enterprise, the Conjur server is running as a user conjur, which lacks write permissions on the container's default cert store.

Implemented Changes

Instead of creating symlinks in the default cert store, instead create them in the Conjur project directory tree - the Conjur process is able to write to the ${conjur_root}/etc/certs in both Conjur Open Source and Enterprise.

In the previous solution iteration, if a custom certificate was established in the ca-cert variable but connecting to the OIDC provider did not require that particular certificate, Authn-OIDC could fall back on any trusted certificate in the default cert store. No longer - if the ca-cert variable is set, it must contain the full certificate chain required for connecting to the OIDC provider. No certificates included in the system's default store will be considered.

Connected Issue/Story

CyberArk internal issue ID: CNJR-2844

Definition of Done

At least 1 todo must be completed in the sections below for the PR to be
merged.

Changelog

  • The CHANGELOG has been updated, or
  • This PR does not include user-facing changes and doesn't require a
    CHANGELOG update

Test coverage

  • This PR includes new unit and integration tests to go with the code
    changes, or
  • The changes in this PR do not require tests

Documentation

  • Docs (e.g. READMEs) were updated in this PR
  • A follow-up issue to update official docs has been filed here: [insert issue ID]
  • This PR does not require updating any documentation

Behavior

  • This PR changes product behavior and has been reviewed by a PO, or
  • These changes are part of a larger initiative that will be reviewed later, or
  • No behavior was changed with this PR

Security

  • Security architect has reviewed the changes in this PR,
  • These changes are part of a larger initiative with a separate security review, or
  • There are no security aspects to these changes

app/domain/authentication/authn_oidc/v2/client.rb Outdated Show resolved Hide resolved
app/domain/authentication/authn_oidc/v2/client.rb Outdated Show resolved Hide resolved
app/domain/authentication/authn_oidc/v2/client.rb Outdated Show resolved Hide resolved
app/domain/authentication/authn_oidc/v2/client.rb Outdated Show resolved Hide resolved
app/domain/authentication/authn_oidc/v2/client.rb Outdated Show resolved Hide resolved
@john-odonnell john-odonnell force-pushed the cert-writing-bug branch 3 times, most recently from b2d2105 to d52c8f0 Compare October 13, 2023 04:16
@@ -148,6 +161,27 @@ def callback_with_temporary_cert(
symlink_a << symlink
end

if OpenIDConnect.http_config.nil? || OpenIDConnect.http_client.ssl.ca_path != cert_dir
config_proc = proc do |config|
config.ssl.ca_path = cert_dir
Copy link

Choose a reason for hiding this comment

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

Authentication::AuthnOidc::V2::Client#callback_with_temporary_cert calls 'config.ssl' 2 times

@@ -226,6 +260,27 @@
symlink_a << symlink
end

if OpenIDConnect.http_config.nil? || OpenIDConnect.http_client.ssl.ca_path != cert_dir
config_proc = proc do |config|
config.ssl.ca_path = cert_dir
Copy link

Choose a reason for hiding this comment

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

Authentication::AuthnOidc::V2::Client#self.discover calls 'config.ssl' 2 times

@@ -148,6 +161,27 @@
symlink_a << symlink
end

if OpenIDConnect.http_config.nil? || OpenIDConnect.http_client.ssl.ca_path != cert_dir
Copy link

Choose a reason for hiding this comment

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

Authentication::AuthnOidc::V2::Client#callback_with_temporary_cert performs a nil-check

@@ -226,6 +260,27 @@
symlink_a << symlink
end

if OpenIDConnect.http_config.nil? || OpenIDConnect.http_client.ssl.ca_path != cert_dir
Copy link

Choose a reason for hiding this comment

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

Authentication::AuthnOidc::V2::Client#self.discover performs a nil-check

# nil configs. We can't be certain that each gem is configured
# with the same Faraday config and need them synchronized, so we
# inject them manually.
OpenIDConnect.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

@john-odonnell john-odonnell marked this pull request as ready for review October 13, 2023 13:43
@john-odonnell john-odonnell requested a review from a team as a code owner October 13, 2023 13:43
OpenIDConnect.class_variable_set(:@@http_config, config_proc)
WebFinger.instance_variable_set(:@http_config, config_proc)
SWD.class_variable_set(:@@http_config, config_proc)
Rack::OAuth2.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

# inject them manually.
OpenIDConnect.class_variable_set(:@@http_config, config_proc)
WebFinger.instance_variable_set(:@http_config, config_proc)
SWD.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

# inject them manually.
OpenIDConnect.class_variable_set(:@@http_config, config_proc)
WebFinger.instance_variable_set(:@http_config, config_proc)
SWD.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

# nil configs. We can't be certain that each gem is configured
# with the same Faraday config and need them synchronized, so we
# inject them manually.
OpenIDConnect.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

OpenIDConnect.class_variable_set(:@@http_config, config_proc)
WebFinger.instance_variable_set(:@http_config, config_proc)
SWD.class_variable_set(:@@http_config, config_proc)
Rack::OAuth2.class_variable_set(:@@http_config, config_proc)
Copy link

Choose a reason for hiding this comment

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

Replace class var :@@http_config with a class instance var.

@codeclimate
Copy link

codeclimate bot commented Oct 13, 2023

Code Climate has analyzed commit 1d079cd and detected 16 issues on this pull request.

Here's the issue category breakdown:

Category Count
Style 9
Complexity 7

The test coverage on the diff in this pull request is 100.0% (50% is the threshold).

This pull request will bring the total coverage in the repository to 88.5% (0.0% change).

View more on Code Climate.

fileutils.mkdir_p(@default_cert_dir) unless dir.exist?(@default_cert_dir.to_s)

@default_cert_dir
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Any particular reason we're using instance variables instead of variables scoped to the method?

Ah, I think I understand what you're trying to accomplish here. We only want to set the @default_cert_dir if it hasn't yet been set. This is in a singleton so you can pass it into the callback_with_temporary_cert method below.

@jvanderhoof jvanderhoof self-requested a review October 13, 2023 18:12
Copy link
Contributor

@jvanderhoof jvanderhoof left a comment

Choose a reason for hiding this comment

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

I believe this code is good enough for now. I'll work with @jtuttle, @andytinkham, and @adamouamani, and the rest of the C&I team on a refactor to cleanup the implementation and improve testability of the code.

@john-odonnell john-odonnell merged commit 40401f4 into master Oct 13, 2023
5 of 6 checks passed
@john-odonnell john-odonnell deleted the cert-writing-bug branch October 13, 2023 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants