-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Add support for API keys to access Elasticsearch #38291
Conversation
In order to support api keys for access to elasticsearch, we need the ability to generate these api keys. A transport action has been added along with the request and response objects that allow for the generation of api keys. The api keys require a name and optionally allow a role to be specified which defines the amount of access the key has. Additionally an expiration may also be provided. This change does not include the restriction that the role needs to be a subset of the user's permissions, which will be added seperately. As it exists in this change, the api key is currently not usable which is another aspect that will come later. Relates #34383
This change implements the verification of api keys in the ApiKeyService. There is no integration into the AuthenticationService as part of this change; this will be done in a future change. Verification of an API key involves validating the provided key with the hash stored in the document and then ensuring that the token is not expired. A conscious decision has been made to always validate the hash and then check expiration. This is done to prevent leaking that a given key has expired.
This commit integrates usage of the api key service into the authentication service for verification of api keys. A bug was fixed in the validation of api keys where the structure of the document was not being used properly. Additionally, unit tests have been added for authentication with api keys.
This change implements a lookup of permissions for API keys when a request moves to authorization. In order to support this, the authentication of an API key will attach values as metadata on the authentication result. The values attached will include the source of the role descriptors. The authentication service will then copy this metadata to the authentication object and set the authentication type to API_KEY. The authorization service will use the authentication type to make a decision on how the roles should be obtained.
This commit enables api keys to share the same cache for roles that is already in use for roles from other sources. In order to avoid the possibility of a key collision with roles that do not belong to api keys, the key for the roles cache now includes a source field that prevents these collisions.
This change builds upon the work done in #35970 and adds appropriate types for anonymous and internal authentication to the `AuthenticationType` enum.
Pinging @elastic/es-security |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't reviewed enough of the API Key PRs to be able to say whether this is ready or not, but I have no objections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't go through the whole changeset here but I've reviewed enough of the individual PRs so LGTM
…-lease-expiration * elastic/master: (24 commits) Add support for API keys to access Elasticsearch (elastic#38291) Add typless client side GetIndexRequest calls and response class (elastic#37778) Limit token expiry to 1 hour maximum (elastic#38244) add docs saying mixed-cluster ILM is not supported (elastic#37954) Skip unsupported languages for tests (elastic#38328) Deprecate `_type` in simulate pipeline requests (elastic#37949) Mute testCannotShrinkLeaderIndex (elastic#38374) Tighten mapping syncing in ccr remote restore (elastic#38071) Add test for `PutFollowAction` on a closed index (elastic#38236) Fix SSLContext pinning to TLSV1.2 in reload tests (elastic#38341) Mute RareClusterStateIT.testDelayedMappingPropagationOnReplica (elastic#38357) Deprecate types in rollover index API (elastic#38039) Types removal - fix FullClusterRestartIT warning expectations (elastic#38310) Fix ILM explain response to allow unknown fields (elastic#38054) Mute testFollowIndexAndCloseNode (elastic#38360) Docs: Drop inline callout from scroll example (elastic#38340) Deprecate HLRC security methods (elastic#37883) Remove types from Monitoring plugin "backend" code (elastic#37745) Add Composite to AggregationBuilders (elastic#38207) Clarify slow cluster-state log messages (elastic#38302) ...
X-Pack security supports built-in authentication service `token-service` that allows access tokens to be used to access Elasticsearch without using Basic authentication. The tokens are generated by `token-service` based on OAuth2 spec. The access token is a short-lived token (defaults to 20m) and refresh token with a lifetime of 24 hours, making them unsuitable for long-lived or recurring tasks where the system might go offline thereby failing refresh of tokens. This commit introduces a built-in authentication service `api-key-service` that adds support for long-lived tokens aka API keys to access Elasticsearch. The `api-key-service` is consulted after `token-service` in the authentication chain. By default, if TLS is enabled then `api-key-service` is also enabled. The service can be disabled using the configuration setting. The API keys:- - by default do not have an expiration but expiration can be configured where the API keys need to be expired after a certain amount of time. - when generated will keep authentication information of the user that generated them. - can be defined with a role describing the privileges for accessing Elasticsearch and will be limited by the role of the user that generated them - can be invalidated via invalidation API - information can be retrieved via a get API - that have been expired or invalidated will be retained for 1 week before being deleted. The expired API keys remover task handles this. Following are the API key management APIs:- 1. Create API Key - `PUT/POST /_security/api_key` 2. Get API key(s) - `GET /_security/api_key` 3. Invalidate API Key(s) `DELETE /_security/api_key` The API keys can be used to access Elasticsearch using `Authorization` header, where the auth scheme is `ApiKey` and the credentials, is the base64 encoding of API key Id and API key separated by a colon. Example:- ``` curl -H "Authorization: ApiKey YXBpLWtleS1pZDphcGkta2V5" http://localhost:9200/_cluster/health ``` Closes elastic#34383
X-Pack security supports built-in authentication service `token-service` that allows access tokens to be used to access Elasticsearch without using Basic authentication. The tokens are generated by `token-service` based on OAuth2 spec. The access token is a short-lived token (defaults to 20m) and refresh token with a lifetime of 24 hours, making them unsuitable for long-lived or recurring tasks where the system might go offline thereby failing refresh of tokens. This commit introduces a built-in authentication service `api-key-service` that adds support for long-lived tokens aka API keys to access Elasticsearch. The `api-key-service` is consulted after `token-service` in the authentication chain. By default, if TLS is enabled then `api-key-service` is also enabled. The service can be disabled using the configuration setting. The API keys:- - by default do not have an expiration but expiration can be configured where the API keys need to be expired after a certain amount of time. - when generated will keep authentication information of the user that generated them. - can be defined with a role describing the privileges for accessing Elasticsearch and will be limited by the role of the user that generated them - can be invalidated via invalidation API - information can be retrieved via a get API - that have been expired or invalidated will be retained for 1 week before being deleted. The expired API keys remover task handles this. Following are the API key management APIs:- 1. Create API Key - `PUT/POST /_security/api_key` 2. Get API key(s) - `GET /_security/api_key` 3. Invalidate API Key(s) `DELETE /_security/api_key` The API keys can be used to access Elasticsearch using `Authorization` header, where the auth scheme is `ApiKey` and the credentials, is the base64 encoding of API key Id and API key separated by a colon. Example:- ``` curl -H "Authorization: ApiKey YXBpLWtleS1pZDphcGkta2V5" http://localhost:9200/_cluster/health ``` Closes #34383
* 6.x: (25 commits) Backport of types removal for Put/Get index templates (elastic#38465) Add support for API keys to access Elasticsearch (elastic#38291) (elastic#38399) Deprecate support for internal versioning for concurrency control (elastic#38451) Deprecate types in rollover index API (elastic#38389) (elastic#38458) Add typless client side GetIndexRequest calls and response class (elastic#38422) [ML] Report index unavailable instead of waiting for lazy node (elastic#38444) await fix CurtIT#testIndex until elastic#38451 is merged (elastic#38466) Update ilm-api.asciidoc, point to REMOVE policy (elastic#38235) (elastic#38464) SQL: Fix esType for DATETIME/DATE and INTERVALS (elastic#38179) Clean up duplicate follow config parameter code (elastic#37688) (elastic#38443) Deprecation check for No Master Block setting (elastic#38383) Bubble-up exceptions from scheduler (elastic#38441) Lift retention lease expiration to index shard (elastic#38391) Deprecate maxRetryTimeout in RestClient and increase default value (elastic#38425) Update Rollup Caps to allow unknown fields (elastic#38446) Backport of elastic#38411: `if_seq_no` and `if_primary_term` parameters aren't wired correctly in REST Client's CRUD API Support unknown fields in ingest pipeline map configuration (elastic#38429) SQL: Implement CURRENT_DATE (elastic#38175) Backport changes to the release notes script. (elastic#38346) Fix ILM explain response to allow unknown fields (elastic#38363) ...
I was recently adding support for the API Key authentication to the Go client (elastic/go-elasticsearch@3b68c0f), and I think there's a small, but nice usability optimization: it would help if the API would return also the base64-encoded value for the key, so the users (or the client) doesn't have to perform the encoding themselves. |
@karmi I see in the ES code that the key ( |
@albertzaharovits , what I mean is the output (ie. result) of the "Create API Key" API: docker run \
--env "discovery.type=single-node" \
--env "xpack.security.enabled=true" \
--env "xpack.security.authc.api_key.enabled=true" \
--env "xpack.license.self_generated.type=trial" \
--env "ELASTIC_PASSWORD=elastic" \
--publish 9200:9200 \
--rm -it \
docker.elastic.co/elasticsearch/elasticsearch:8.0.0-SNAPSHOT
curl -s -X POST \
-H 'Content-Type: application/json' \
http://elastic:elastic@localhost:9200/_security/api_key -d \
'{"name":"test-key", "role_descriptors":{}}' \
| jq '.' Output: {
"id": "ZquG-WsBx1ePiPP47oig",
"name": "test-key",
"api_key": "ipRxILiWT7udFhKgb69O4Q"
}
Ie. the API returns the |
Thank you @karmi . I was under the impression that @bizybot Do you think it would be feasible to achieve what @karmi is asking for? Either by adding another field in the response or make ES not require the |
Yes, exactly — with the goal of increasing the usability. If the response contains the fully-encoded value, the user can just copy&paste that value into the client in a single step.
Yes, that's what I had in mind — adding a property like |
Hi @karmi and @albertzaharovits, |
Yes, please! Thanks for catching it, @bizybot ! |
This part is not feasible. The |
X-Pack security supports built-in authentication service
token-service
that allowsaccess tokens to be used to access Elasticsearch without using Basic authentication.
The tokens are generated by
token-service
based on OAuth2 spec. The access tokenis a short-lived token (defaults to 20m) and refresh token with a lifetime of 24 hours,
making them unsuitable for long-lived or recurring tasks where the system might go
offline thereby failing refresh of tokens.
This commit introduces a built-in authentication service
api-key-service
thatadds support for long-lived tokens aka API keys to access Elasticsearch. The
api-key-service
is consulted after
token-service
in the authentication chain. By default, if TLS is enabledthen
api-key-service
is also enabled. The service can be disabled using the configurationsetting.
The API keys:-
where the API keys need to be expired after a certain amount of time.
generated them.
Elasticsearch and will be limited by the role of the user that generated
them
being deleted. The expired API keys remover task handles this.
Following are the API key management APIs:-
PUT/POST /_security/api_key
GET /_security/api_key
DELETE /_security/api_key
The API keys can be used to access Elasticsearch using
Authorization
header, where the auth scheme is
ApiKey
and the credentials, is thebase64 encoding of API key Id and API key separated by a colon.
Example:-
Closes #34383