Skip to content
This repository was archived by the owner on Apr 22, 2024. It is now read-only.

Decouple CA load from request lifecycle #50

Merged
merged 4 commits into from
Feb 25, 2024
Merged

Decouple CA load from request lifecycle #50

merged 4 commits into from
Feb 25, 2024

Conversation

sergicastro
Copy link
Contributor

Currently, the CA was loaded from the file (if configured) every time it was needed, meaning every request that matches this configuration.
This PR mainly creates a TLS pool that holds all requested TLS configs and serves them when necessary, so the file load only happens once, the first time a TLS config is requested.

It also allows configuring an asynchronous refresh of the CA, so the next time the same TLS config is requested it will contain new values from the file if that changed without restarting the authservice-go.

This code should be ready to add k8s secret support in the future. By implementing internal.Reader interface and adding a secret reference in the trustedCAconfig.

Note: I didn't want to add a dependency on github.com/fsnotify/fsnotify as I don't expect the CAs to rotate frequently, but it shouldn't be a big deal to add it in the future.

@sergicastro sergicastro requested a review from nacx February 23, 2024 18:51
Copy link

codecov bot commented Feb 23, 2024

Codecov Report

Attention: Patch coverage is 92.53731% with 10 lines in your changes are missing coverage. Please review.

Project coverage is 93.16%. Comparing base (c758258) to head (a4a512b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #50      +/-   ##
==========================================
+ Coverage   93.05%   93.16%   +0.10%     
==========================================
  Files          20       21       +1     
  Lines        1311     1433     +122     
==========================================
+ Hits         1220     1335     +115     
- Misses         55       60       +5     
- Partials       36       38       +2     
Files Coverage Δ
internal/file.go 100.00% <100.00%> (ø)
internal/authz/oidc.go 93.55% <80.00%> (+0.01%) ⬆️
internal/oidc/jwks.go 96.15% <75.00%> (+0.07%) ⬆️
internal/server/authz.go 94.79% <66.66%> (+0.05%) ⬆️
internal/tls.go 89.41% <89.23%> (-1.90%) ⬇️

Copy link
Member

@nacx nacx left a comment

Choose a reason for hiding this comment

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

Overall looks good! I added some minor comments

// The duration between refreshes of the trusted certificate authority if `trusted_certificate_authority_file` is set.
// Unset or 0 means disables the refresh, useful is no rotation is expected.
// Default is unset, means disabled.
// Is a String that ends in `s` to indicate seconds and is preceded by the number of seconds,
Copy link
Member

Choose a reason for hiding this comment

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

I think it supports also minutes or hours?
Also, let's not mention nanos; no one will use such precision when configuring this interval

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's what I thought, but this is not golang time.Duration, it's the protobuf one it says only seconds and nanos are supported: https://protobuf.dev/reference/protobuf/google.protobuf/#duration

Copy link
Member

Choose a reason for hiding this comment

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

I think this is what happens when you marshal the duration into a JSON, that it always marshals it as seconds, but when unmarshaling you can use normal Golang Duration string values. Can you try it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I already tried it:

proto: (line 32:63): invalid google.protobuf.Duration value "60m"

But as the documentation says, it only accepts seconds with decimals for nanos.

Something that could make sense is to turn this field into a string representing the golang time.Duration format and validate that manually when we're loading the config.

@nacx
Copy link
Member

nacx commented Feb 24, 2024

Now that we have merged the PR to load the client-secret from a K8s secret, WDYT about adding an option to load the CA from a secret as well, and update the Secret loader accordingly? This can be done in another PR though.

@sergicastro
Copy link
Contributor Author

Now that we have merged the PR to load the client-secret from a K8s secret, WDYT about adding an option to load the CA from a secret as well, and update the Secret loader accordingly? This can be done in another PR though.

yes, this was the intention, I thought I wrote it in the description 🤔

Copy link
Member

@nacx nacx left a comment

Choose a reason for hiding this comment

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

LGTM. Just one thing about the comment for the duration field, and for the examples used in the tests.

@sergicastro
Copy link
Contributor Author

I'm merging this as I could raise a new PR if we need to change something about the Duration comments.

@sergicastro sergicastro merged commit cbb3330 into main Feb 25, 2024
10 of 11 checks passed
@sergicastro sergicastro deleted the ca-reloader branch February 25, 2024 07:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants