Create and Use API Keys
This guide applies to multi-user Tiled deployments, i.e. deployments configured with an authentication provider.
Note
Single-user deployments run with a single API key. By default, it is randomly generated and printed to the console at server startup, like so:
$ tiled serve pyobject tiled.examples.generated:tree
Generating large example data...
Done generating example data.
Use the following URL to connect to Tiled:
"http://127.0.0.1:8000?api_key=8df0146c93e9add287d0e7f84a165ba4bd3517bbb3c7c6b4d963c3e1549d0311"
This guide does not apply to single-user deployments like this.
Why use API keys?
Users can log in to Tiled with a simple username/password or through a third party like ORICD or Google, as demonstrated in the tutorial Log into an Authenticated Tiled Server. For interactive workflows in Python, this the most convenient way to authenticate.
But in other situations, it can more convenient to generate and use an API key. An API key uses a comparatively simpler interaction, without an interactive prompt or the need to periodically “refresh” a session to keep it active. This is useful when:
The code using tiled is running in an unsupervised, automated fashion or scaled across many workers, such as in an HPC job, where is it not possible to provide credentials interactively.
You are connecting from a generic web client like a web browser or
curl
, which has no built-in integration with Tiled or with OpenAPI+OAuth2.
Create an API Key
To follow along, you may start a Tiled server with a simple authentication provider,
as shown. Alternatively, you may use an existing authenticated Tiled server, such as
https://tiled-demo.blueskyproject.io
; if you do, replace http://localhost:8000
in the example below with that address.
# You can find example_configs/ in the root of the tiled source code repository.
ALICE_PASSWORD=secret1 tiled serve config example_configs/toy_authentication.yml
Using the Tiled commandline interface, log in as alice
using the password secret1
.
$ tiled profile create http://localhost:8000
$ tiled login
Username: alice
Password:
Create a new API key.
$ tiled api_key create
48e8f8598940fa0f3e80b406def606e17e815a2c76fe21350a99d6d9935371d11533b318
This text is the API key. It should be handled as a secret.
Use the API Key in Python
We can use it in the Python client:
>>> from tiled.client import from_url
>>> API_KEY = "YOUR_KEY_HERE"
>>> c = from_uri("http://localhost:8000", api_key=API_KEY)
API keys should never be placed directly in scripts or notebooks.
Instead, set the environment variable TILED_API_KEY
.
export TILED_API_KEY=YOUR_KEY_HERE
and then start Python (or IPython, or Jupyter, or…). The Python client will use that, unless it is explicitly passed different credentials.
>>> from tiled.client import from_url
>>> c = from_uri("http://localhost:8000") # uses TILED_API_KEY, if set
Use the API Key in other web clients
We can use in other web clients as well. For example, using HTTPie we can see that unauthenticated requests are refused
$ http http://localhost:8000/api/v1/metadata/
HTTP/1.1 401 Unauthorized
content-length: 30
content-type: application/json
date: Mon, 31 Jan 2022 17:30:06 GMT
server: uvicorn
server-timing: app;dur=2.6
set-cookie: tiled_csrf=bZLhKsXVE2VirgXQncHsHn4Y0Wwwr66U0T0hqarJyfw; HttpOnly; Path=/; SameSite=lax
x-tiled-root: http://localhost:8000/api/v1
{
"detail": "Not authenticated"
}
but passing the API key in the Authorization
header as Apikey YOUR_KEY_HERE
is accepted.
(Note the use of '
quotes.)
$ http http://localhost:8000/api/v1/metadata/ 'Authorization:Apikey 48e8f8598940fa0f3e80b406def606e17e815a2c76fe21350a99d6d9935371d11533b318'
HTTP/1.1 200 OK
content-length: 320
content-type: application/json
date: Mon, 31 Jan 2022 17:34:48 GMT
etag: c7d94c99b0a3cd6e102a78520db84bef
server: uvicorn
server-timing: tok;dur=0.0, pack;dur=0.0, app;dur=15.2
set-cookie: tiled_csrf=InE4mplUO0goPxf4V07tVuLSLUvDqhgtALTHYoC3T3s; HttpOnly; Path=/; SameSite=lax
<etc.>
The API key can also be passed in the URL like
http://localhost:8000/api/v1/metadata/?api_key=YOUR_KEY_HERE
. Using the
Authorization
header is preferred (more secure) but in some situations, as in
pasting a link into a web browser, the URL is the only option.
Manage API Keys
We can use the tiled commandline interface to examine and revoke API keys as well.
$ tiled api_key
Usage: tiled api_key [OPTIONS] COMMAND [ARGS]...
Create, list, and revoke API keys.
Options:
--help Show this message and exit.
Commands:
create
list
revoke
We can see the key that we made above in the list.
$ tiled api_key list
First 8 Expires at (UTC) Latest activity Note Scopes
48e8f859 - 2022-01-31T18:32:33 inherit
By default, an API key inherits all the same access as the user who is for. If an API key will be used for a specific task, it is good security hygiene to give it only the privileges it needs for that task. It is also recommended to set a limited lifetimes so that if the key is unknowingly leaked it will not continue to work forever. For example, this command creates an API key that will expire in 10 minutes (600 seconds) and can search/list metadata but cannot download array data.
$ tiled api_key create --expires-in 600 --scopes read:metadata
ba9af604023a829ab22edb786168d6e1b97cef68c54c6d95d7fad5e3e6347fa131263581
See Scopes for the full list of scopes and their capabilities.
$ tiled api_key list
First 8 Expires at (UTC) Latest activity Note Scopes
48e8f859 - 2022-01-31T18:32:33 inherit
ba9af604 2022-01-31T23:03:57 - read:metadata
Finally, the --note
option can be used to label an API key as a reminder of
where or how it is being used.
$ tiled api_key create --note="Data validation pipeline" --scopes read:metadata --scopes read:data
573928c62e53096321fb874847bcc6a90ea636eebd8acbd7c5e9d18d2859847b3bfb4f19
$ tiled api_key list
First 8 Expires at (UTC) Latest activity Note Scopes
48e8f859 - 2022-01-31T18:32:33 inherit
ba9af604 2022-01-31T23:03:57 - read:metadata
573928c6 - - Data validation pipeline read:metadata read:data
If an API key is no longer need or accidentally leaked, it should be revoked. It
can be identified by its first eight characters, as shown in the the output of
tiled api_key list
.
$ tiled api_key revoke 573928c6
$ tiled api_key list
First 8 Expires at (UTC) Latest activity Note Scopes
48e8f859 - 2022-01-31T18:32:33 inherit
ba9af604 2022-01-31T23:03:57 - read:metadata
Passing the full key also works, if you have it handy. There is no need to trim just the first eight.