auth: new api auth implementation#36968
Conversation
Signed-off-by: wangbaiping/wbpcode <wangbaiping@bytedance.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
| message Credential { | ||
| // The value of the unique API key. | ||
| string api_key = 1 [(validate.rules).string = {min_len: 1}]; | ||
|
|
||
| // The unique id or identity that used to identify the client or consumer. | ||
| string client_id = 2 [(validate.rules).string = {min_len: 1}]; | ||
| } | ||
|
|
||
| message Credentials { | ||
| repeated Credential entries = 1; | ||
| } | ||
|
|
||
| // Api credentials used to authenticate the clients. | ||
| Credentials credentials = 1 [(udpa.annotations.sensitive) = true]; |
There was a problem hiding this comment.
The api key credenticals has clear structure. It would be better to use a typed message rather than DataSource.
It's OK to change the API because the #36709 was just merged.
There was a problem hiding this comment.
FWIW, this implies that only an xDS-update will change the credentials.
If that is the intended behavior, that's fine by me, although I can see some (not huge) benefits of using DataSource (e.g., fine-granularity of credentials updates, and using env-vars).
There was a problem hiding this comment.
@adisuissa Yeah. I know. I prefer the explicitly defined structures rather than plain string or bytes and I think the xDS should be the first way to update the configuration.
And specific to the DataSource advantages, there are two possible compromised ways:
- Use the DataSource as config field type but require it's content to keep the structure of the
Crendentials. We can load it by theloadFromJsonStringdirectly to aCrendentialsproto type. - Add a new DataSource config field in the
Credentialsfuture if some users require env/file support. By this way, we can use both xDS or local file/env to configure this filter.
Both are ok to me (and a inclided to the second way), which one would you prefer?
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
|
cc @envoyproxy/api-shepherds |
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
| - source/extensions/compression/zstd/common/dictionary_manager.h | ||
| - source/extensions/filters/http/adaptive_concurrency/controller | ||
| - source/extensions/filters/http/admission_control | ||
| - source/extensions/filters/http/api_key_auth |
There was a problem hiding this comment.
This is necessary because the ExceptionFreeFactoryBase cannot handle the case where the route specific configuration loading will throw the exception.
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
adisuissa
left a comment
There was a problem hiding this comment.
Thanks!
Left a few high-level comments about the API.
I'll review the rest of the code once the API is more stable.
| message Credential { | ||
| // The value of the unique API key. | ||
| string api_key = 1 [(validate.rules).string = {min_len: 1}]; | ||
|
|
||
| // The unique id or identity that used to identify the client or consumer. | ||
| string client_id = 2 [(validate.rules).string = {min_len: 1}]; | ||
| } | ||
|
|
||
| message Credentials { | ||
| repeated Credential entries = 1; | ||
| } | ||
|
|
||
| // Api credentials used to authenticate the clients. | ||
| Credentials credentials = 1 [(udpa.annotations.sensitive) = true]; |
There was a problem hiding this comment.
FWIW, this implies that only an xDS-update will change the credentials.
If that is the intended behavior, that's fine by me, although I can see some (not huge) benefits of using DataSource (e.g., fine-granularity of credentials updates, and using env-vars).
| envoy.filters.http.api_key_auth: | ||
| categories: | ||
| - envoy.filters.http | ||
| security_posture: robust_to_untrusted_downstream |
There was a problem hiding this comment.
This will probably need a signoff from the security group.
There was a problem hiding this comment.
cc @envoyproxy/security-team
There was a problem hiding this comment.
Normally for filters which contain parsers and this one does have a small parser, a fuzzer is required to claim the robustness to unstrusted downstream.
There was a problem hiding this comment.
I am not familiar to the fuzz test. But I add one by refering to jwt fuzz. Hope it make sense.
Co-authored-by: Adi (Suissa) Peleg <adip@google.com> Signed-off-by: code <wbphub@gmail.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
|
wait any basically used to wait author's response. change it to wait review. |
adisuissa
left a comment
There was a problem hiding this comment.
One API question, but otherwise LGTM
| // then all authenticated clients are allowed. This provides very limited but simple authorization. | ||
| // If more complex authorization is required, then use the :ref:`HTTP RBAC filter | ||
| // <config_http_filters_rbac>` instead. | ||
| repeated string allowed_clients = 2; |
There was a problem hiding this comment.
The filter will try to authenticate the client by the
override_config(if exists) and filter level configuration first. After the client is authenticated, we will try to check if it's limited by theallowed_clients(if exists and non-empty).
IMHO this is somewhat fragile, and may lead to inconsistencies when new fields are added.
Specifically, IIUC, if both fields are set, the client needs both in the credentials list inside the override_config and in the allowed_clients list.
I understand the motivation behind adding one of the fields, but I'm not sure I fully grok when would adding both fields be useful.
To be more concrete, looking at the example below, it is unclear to me why the {one_key, one_client} pair is useful in the override config (other than maybe receiving a different HTTP response code).
….proto Co-authored-by: Adi (Suissa) Peleg <adip@google.com> Signed-off-by: code <wbphub@gmail.com>
….proto Co-authored-by: Adi (Suissa) Peleg <adip@google.com> Signed-off-by: code <wbphub@gmail.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
|
/retest |
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
|
cc @adisuissa , Hi, adi, the comments are updated and could you take a look at this again? Thanks. 🙏 |
|
Waiting for @adisuissa review |
| // Route specific APIKeyAuth configuration. This is optional and could be used to **override** the | ||
| // filter level ApiKeyAuth configuration **partly**. | ||
| // | ||
| // For example, if non-empty ``credentials`` is set in the ``override_config``, then the | ||
| // ``credentials`` in the filter level configuration will be ignored and the ``credentials`` in | ||
| // this configuration will be used. |
There was a problem hiding this comment.
I don't think partial override is the right way to go. If a message of type ApiKeyAuth is provided, then it should replace the one define above entirely. The reason I'm against this is that if a new field is added in the future to ApiKeyAuth where it won't make sense to do a partial override, this will complicate the use of this field and the override.
If an override to a specific field is desired, then an additional field can be added to ApiKeyAuthPerRoute. For example repeated Credential credentials that will override only the credentials defined above.
There was a problem hiding this comment.
If an override to a specific field is desired, then an additional field can be added to ApiKeyAuthPerRoute. For example repeated Credential credentials that will override only the credentials defined above.
Yeah, it's required.
Then I think I can remove the override_config and use the repeated Credential credentials and repeated KeySource key_sources directly.
| // .. note:: | ||
| // Setting this field and ``override_config.credentials`` at the same configuration entry is not | ||
| // an error but also makes no sense because they provide similar functionality. Please only use | ||
| // one of them at same configuration entry. |
There was a problem hiding this comment.
Why wouldn't this be an error?
IIUC all the options here are essentially a oneof. As this is a newly introduced feature I think it can either reject or declare the order (prioritization) of these fields.
There was a problem hiding this comment.
The authentication and authorization are two different phases. Even both credentials and allowed_clients are configured, the filter could handle them correctly as expected.
So, I don't think this is an error and don't deserve a configuration rejection. The prioritization also only make the implementation more complex and make no much sense.
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
Signed-off-by: wangbaiping(wbpcode) <wangbaiping@bytedance.com>
adisuissa
left a comment
There was a problem hiding this comment.
Thanks!
Left a minor API rephrase suggestion, but otherwise LGTM.
|
/wait |
Co-authored-by: Adi (Suissa) Peleg <adip@google.com> Signed-off-by: code <wbphub@gmail.com>
Co-authored-by: Adi (Suissa) Peleg <adip@google.com> Signed-off-by: code <wbphub@gmail.com>
|
@yanavlasov I think now this is ready for a final review or approval, thanks :) |
| return ApiKeyAuthStats{ALL_API_KEY_AUTH_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; | ||
| } | ||
|
|
||
| ApiKeyAuthConfig default_config_; |
There was a problem hiding this comment.
I suggest being strict about const correctness of the configuration types as they are shared across multiple threads.
There was a problem hiding this comment.
Let's land this PR first and create a new PR immediately.
Commit Message: auth: new api auth implementation
Additional Description:
To close #34877
Risk Level: low. New extension.
Testing: unit, integration.
Docs Changes: added.
Release Notes: added.
Platform Specific Features: n/a.