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

[DOCS] Clarify API key format for create API key #75076

Merged

Conversation

lockewritesdocs
Copy link
Contributor

@lockewritesdocs lockewritesdocs commented Jul 7, 2021

Clarifies that the credentials passed in the authorization request for the create API key should be in UTF-8 format. Also includes some formatting and grammatical cleanup.

Preview: https://elasticsearch_75076.docs-preview.app.elstc.co/guide/en/elasticsearch/reference/master/security-api-create-api-key.html

Resolves #66975

@lockewritesdocs lockewritesdocs added >docs General docs changes :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC v8.0.0 v7.14.0 v7.13.3 v7.15.0 labels Jul 7, 2021
@lockewritesdocs lockewritesdocs self-assigned this Jul 7, 2021
@elasticmachine elasticmachine added Team:Docs Meta label for docs team Team:Security Meta label for security team labels Jul 7, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-docs (Team:Docs)

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

Comment on lines 151 to 152
are a Base64-encoded string in UTF-8 format that you create by combining the
`id` and `api_key` with a colon (`:`).
Copy link
Contributor

@tvernum tvernum Jul 8, 2021

Choose a reason for hiding this comment

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

I think this is still ambiguous.

What needs to be done is:

  1. let concat = key_id & ":" & api_key
  2. let bytes = getBytesInUtf8( concat )
  3. let credential = base64Encode( bytes )
  4. let header = HttpHeader( "Authorization", "ApiKey " & credential )

The ambiguity is that both concat and credential are strings, and it is the conversion of concat into bytes that needs to be performed using UTF8 encoding.

Explaining that clearly is tricky though.
Maybe pseudo-code is the clearest option, but I'm not sure.

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 explanation, Tim. If I'm following correctly, we need to:

  1. Concatenate the id and api_key
  2. Get the bytes of that combined String
  3. Encode the bytes of the concatenated String (in Base64) in UTF-8 format
  4. Use the credential in the authorization request

Can we use the iconv tool to accomplish this task? Here are the steps that I took:

I used the create API key API to generate this response (I redacted some information with ellipses):

{
  "id" : "Xf9-hno...",
  "name" : "my-api-key",
  "api_key" : "ZyG-2q..."
}

Then, I concatenated the id and api_key (encoded in base64), and also included iconv -t utf8 to specify the UTF-8 encoding (note: when I specified utf-16, this entire process fails, as we note in the docs):

echo -n "Xf9-hnoBcNSS-6PfVe4Q:ZyG-2qjSTrKENOj2SjBNww" | base64 | iconv -t utf8

The command generated these credentials:

WGY5L...Qk53dw==

Which I then used to successfully authenticate with my cloud cluster:

curl -H "Authorization: ApiKey WGY5L...Qk53dw==" \
https://<cluster-id>:9243/_cluster/health\?pretty

Copy link
Contributor

@tvernum tvernum Jul 9, 2021

Choose a reason for hiding this comment

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

It's actually step 2 (rather than step 3) that needs to be UTF8.

So, the command line would be:

echo -n "Xf9-hnoBcNSS-6PfVe4Q:ZyG-2qjSTrKENOj2SjBNww" | iconv -t utf8 | base64 

Except that use of iconv is redundant - because the input is pure ASCII, the conversion to UTF-8 doesn't do anything.

However, if you instead did

echo -n "Xf9-hnoBcNSS-6PfVe4Q:ZyG-2qjSTrKENOj2SjBNww" | iconv -t utf-16 | base64 

That would produce an incorrect result.

To get into some technical details let's assume that the id is "i" and the api_key is "k".
The concatenation would be i:k. In order to convert that string into bytes, you need an encoding so that you know how each character should be represented.

For Ascii and UTF8 i:k is encoded as 0x69 0x3a 0x6b (a 3 byte array)
For UTF-16 that same string is encoded as 0x00 0x69 0x00 0x3a 0x00 0x6b (a 6 byte array)

Performing a base64 encoding of those 2 different byte arrays will give very different sets of credentials.

For simple command line usage, there's no need to convert anything.
echo will default to outputting ASCII (which will be equivalent to UTF-8) and the commandline base64 utility will not perform any conversions on the input, so everything is fine.

The issue is that some other tools require an explicit encoding when you turn a String into bytes.
For example, in Java, this would be something like:

// Assuming "result" is the output from the call to create api key 
var bytes = (result.id + ":" + result.api_key).getBytes(StandardCharsets.UTF_8);
var header = "ApiKey " + Base64.getEncoder().encodeToString(bytes);

Replacing that StandardCharsets.UTF_8 with StandardCharsets.UTF_16 will give the wrong result.

It's tricky because we intentionally provide examples in simple command line tools, but when people want to translate that to their programming language there may be these traps that they need to avoid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As always, thanks for the thorough explanation @tvernum. I pushed some changes in d52a45d that hopefully clarify the finer points around the string byte conversion.

Copy link
Contributor

@tvernum tvernum left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for all the work on this one.

@lockewritesdocs
Copy link
Contributor Author

@elasticmachine update branch

@lockewritesdocs lockewritesdocs merged commit ba8d83a into elastic:master Jul 13, 2021
@lockewritesdocs lockewritesdocs deleted the docs__clarify-create-api-auth branch July 13, 2021 14:28
lockewritesdocs pushed a commit to lockewritesdocs/elasticsearch that referenced this pull request Jul 13, 2021
* [DOCS] Clarify API key format for create API key

* Removing unnecessary NOTCONSOLE

* Clarifying information about UTF-8 format

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	x-pack/docs/en/rest-api/security/create-api-keys.asciidoc
lockewritesdocs pushed a commit to lockewritesdocs/elasticsearch that referenced this pull request Jul 13, 2021
* [DOCS] Clarify API key format for create API key

* Removing unnecessary NOTCONSOLE

* Clarifying information about UTF-8 format

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	x-pack/docs/en/rest-api/security/create-api-keys.asciidoc
lockewritesdocs pushed a commit that referenced this pull request Jul 13, 2021
* [DOCS] Clarify API key format for create API key

* Removing unnecessary NOTCONSOLE

* Clarifying information about UTF-8 format

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	x-pack/docs/en/rest-api/security/create-api-keys.asciidoc
lockewritesdocs pushed a commit that referenced this pull request Jul 13, 2021
* [DOCS] Clarify API key format for create API key

* Removing unnecessary NOTCONSOLE

* Clarifying information about UTF-8 format

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	x-pack/docs/en/rest-api/security/create-api-keys.asciidoc
lockewritesdocs pushed a commit that referenced this pull request Jul 13, 2021
* [DOCS] Clarify API key format for create API key

* Removing unnecessary NOTCONSOLE

* Clarifying information about UTF-8 format

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	x-pack/docs/en/rest-api/security/create-api-keys.asciidoc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>docs General docs changes :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Docs Meta label for docs team Team:Security Meta label for security team v7.13.3 v7.14.0 v7.15.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Docs] Clarify that the API Key auth header is UTF8
4 participants