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

relay-proxy: Support API Keys validation to limit the applications being able to use GO Feature Flag #649

Merged
merged 10 commits into from
Apr 4, 2023

Conversation

dhanusaputra
Copy link
Contributor

@dhanusaputra dhanusaputra commented Mar 30, 2023

Description

The feature should meet the following requirements:

  • The relay proxy should be modified to support a list of authorized API keys in the configuration.

will use APIKeys to initiate list of keys

  • The authorized API keys list should be configurable.

configurable in goff.yaml

  • The relay proxy should check the API keys in the Authorization header when receiving any requests and only allow requests with valid API keys.

use middleware.KeyAuthWithConfig to check the header with format: Bearer <key>

  • Unauthorized requests should be rejected with an appropriate error message.

middleware.KeyAuthWithConfig.Validator will reject unauthorized requests

  • The feature should not significantly impact the performance of the relay proxy.

basically will add one more process in middleware to check the header

Changes include

  • Bugfix (non-breaking change that solves an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking changes (change that is not backward-compatible and/or changes current functionality)

Closes issue(s)

Resolve #613

Checklist

  • I have tested this code
  • I have added unit test to cover this code
  • I have updated the documentation (README.md and /website/docs)
  • I have followed the contributing guide

@netlify
Copy link

netlify bot commented Mar 30, 2023

Deploy Preview for go-feature-flag-doc-preview canceled.

Name Link
🔨 Latest commit 99a39b4
🔍 Latest deploy log https://app.netlify.com/sites/go-feature-flag-doc-preview/deploys/642c1c165e5cb30008330f97

@codecov
Copy link

codecov bot commented Mar 30, 2023

Codecov Report

Merging #649 (99a39b4) into main (34d24f6) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##             main     #649   +/-   ##
=======================================
  Coverage   88.40%   88.40%           
=======================================
  Files          58       58           
  Lines        2605     2605           
=======================================
  Hits         2303     2303           
  Misses        252      252           
  Partials       50       50           
Impacted Files Coverage Δ
cmd/relayproxy/config/config.go 95.31% <ø> (ø)
cmd/relayproxy/controller/all_flags.go 85.71% <ø> (ø)
cmd/relayproxy/controller/collect_eval_data.go 100.00% <ø> (ø)
cmd/relayproxy/controller/flag_eval.go 88.00% <ø> (ø)
cmd/relayproxy/main.go 0.00% <ø> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@dhanusaputra
Copy link
Contributor Author

hi @thomaspoignant just drafted this PR for initial feedback
please help take a look when have time thank you

please also check the controller part cmd/relayproxy/controller/api_key.go
it's still WIP, have put some comments regarding the API contract flow

one more thing, currently we can put user in request body of some endpoints to know who is the requester
maybe we can use the user data when we create API key?

@dhanusaputra dhanusaputra marked this pull request as draft March 30, 2023 12:09
Copy link
Owner

@thomaspoignant thomaspoignant left a comment

Choose a reason for hiding this comment

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

Hey thanks for this PR.

I am not sure to understand how you proposal will work.
How can I add an API key? By calling the API and it will be stored in memory?
How will it work when the relay-proxy will restart, will we lose the API keys configured?

How I was thinking of doing this, was to have a list of API keys in the relay proxy configuration file and I would have challenged the authorization headers with everything that is part of this list.

@dhanusaputra
Copy link
Contributor Author

How can I add an API key?

using the apiKeyCreate endpoint

By calling the API and it will be stored in memory?

yes

How will it work when the relay-proxy will restart, will we lose the API keys configured?

yes everything will be lost

How I was thinking of doing this, was to have a list of API keys in the relay proxy configuration file and I would have challenged the authorization headers with everything that is part of this list.

got it, let me rework the PR, I'm more aligned this way too, thank you for your feedback!

@@ -47,7 +47,7 @@ Before starting your **relay proxy** you will need to create a minimal configura
# this is a minimal config containing only where your flag file is located
retriever:
kind: http
url: https://raw.githubusercontent.com/thomaspoignant/go-feature-flag/main/examples/file/flags.yaml
Copy link
Contributor Author

Choose a reason for hiding this comment

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

invalid url

Copy link
Owner

Choose a reason for hiding this comment

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

Good catch 👍

@dhanusaputra dhanusaputra marked this pull request as ready for review April 2, 2023 10:00
…ing able to use GO Feature Flag, gen swagger
Copy link
Owner

@thomaspoignant thomaspoignant left a comment

Choose a reason for hiding this comment

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

This approach is way closer to what I had in mind thank you 🙏
I've added a few review point because I am not sure to get all the points here.

@@ -137,6 +138,9 @@ type Config struct {

// Version is the version of the relay-proxy
Version string

// APIKeys list of API keys that authorized to use endpoints
APIKeys map[string]bool `mapstructure:"apiKeys"`
Copy link
Owner

@thomaspoignant thomaspoignant Apr 3, 2023

Choose a reason for hiding this comment

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

I am not sure to understand why you have a map[string]bool, is it to have a set here?
If so we may need to consider having a map[string]interface{} instead since it is a bit better in term of memory and size.

See https://itnext.io/set-in-go-map-bool-and-map-struct-performance-comparison-5315b4b107b

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for the article, TIL
let me change it into slice since it's more easy to understand in config

Comment on lines 10 to 12
apiKeys:
apikey1: true
apikey2: true
Copy link
Owner

Choose a reason for hiding this comment

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

I am not sure to understand the boolean here.
Would it be better to have only a list, something like

apiKeys:
  - apikey1 # with a comment explaining who is the owner of the key
  - apikey2

I think it will make the configuration representation way easier to understand.
You can still put it in a set in the config struct, but in terms of configuration, it will be way more understandable for the users of the relay proxy.

@@ -31,6 +31,7 @@ If you want to replace a nested fields, please use `_` to separate each field _(
| `startWithRetrieverError` | boolean | `false` | By default the **relay proxy** will crash if he is not able to retrieve the flags from the configuration.<br/>If you don't want your relay proxy to crash, you can set `startWithRetrieverError` to true. Until the flag is retrievable the relay proxy will only answer with default values. |
| `exporter` | [exporter](#exporter) | **none** | Exporter is the configuration on how to export data. |
| `notifier` | [notifier](#notifier) | **none** | Notifiers is the configuration on where to notify a flag change. |
| `apiKeys` | map[string]bool | **none** | List of authorized API keys. Each request will need to provide one of authorized key inside `Authorization` header with format `Bearer <api-key>`. There will be no authorization when this config is not configured.<br /><br />_Note: there will be no authorization when this config is not set._ |
Copy link
Owner

Choose a reason for hiding this comment

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

You mention twice this, maybe we should remove one.

There will be no authorization when this config is not configured.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Owner

Choose a reason for hiding this comment

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

You are right.
I guess we could delete the one in cmd/relayproxy/docs since it is not really used and keep only the one that finish on the website.

Copy link
Owner

@thomaspoignant thomaspoignant left a comment

Choose a reason for hiding this comment

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

This looks exactly to what I had in mind.
I will review it soon.

@sonarcloud
Copy link

sonarcloud bot commented Apr 4, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link
Owner

@thomaspoignant thomaspoignant left a comment

Choose a reason for hiding this comment

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

@dhanusaputra thanks a lot for this pull request this is a super great new addition to GO Feature Flag 🙏

@thomaspoignant thomaspoignant merged commit a50b08f into thomaspoignant:main Apr 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

relay-proxy: Support API Keys validation to limit the applications being able to use GO Feature Flag
2 participants