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

Add --api-key CLI option #596

Merged
merged 3 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions docs/source/explanations/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ client, a cookie will be set in your client and you won’t need to use the toke
again. It is valid indefinitely.

For horizontally-scaled deployments where you need multiple instances of the
server to share the same secret, you can set it via an environment variable like
so.
server to share the same secret, you can set it with a CLI option

```
tiled serve ... --api-key=YOUR_SECRET
```

or via an environment variable

```
TILED_SINGLE_USER_API_KEY=YOUR_SECRET tiled serve ...
Expand Down
58 changes: 55 additions & 3 deletions tiled/commandline/_serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ def serve_directory(
"this option selected."
),
),
api_key: str = typer.Option(
None,
"--api-key",
help=(
"Set the single-user API key. "
"By default, a random key is generated at startup and printed."
),
),
keep_ext: bool = typer.Option(
False,
"--keep-ext",
Expand Down Expand Up @@ -182,7 +190,10 @@ def serve_directory(
register_logger.setLevel("INFO")
web_app = build_app(
catalog_adapter,
{"allow_anonymous_access": public},
{
"allow_anonymous_access": public,
"single_user_api_key": api_key,
},
server_settings,
)
if watch:
Expand Down Expand Up @@ -270,6 +281,14 @@ def serve_catalog(
"this option selected."
),
),
api_key: str = typer.Option(
None,
"--api-key",
help=(
"Set the single-user API key. "
"By default, a random key is generated at startup and printed."
),
),
host: str = typer.Option(
"127.0.0.1",
help=(
Expand Down Expand Up @@ -388,7 +407,13 @@ def serve_catalog(
init_if_not_exists=init,
)
web_app = build_app(
tree, {"allow_anonymous_access": public}, server_settings, scalable=scalable
tree,
{
"allow_anonymous_access": public,
"single_user_api_key": api_key,
},
server_settings,
scalable=scalable,
)
print_admin_api_key_if_generated(web_app, host=host, port=port)

Expand All @@ -414,6 +439,14 @@ def serve_pyobject(
"option selected."
),
),
api_key: str = typer.Option(
None,
"--api-key",
help=(
"Set the single-user API key. "
"By default, a random key is generated at startup and printed."
),
),
host: str = typer.Option(
"127.0.0.1",
help=(
Expand Down Expand Up @@ -453,7 +486,13 @@ def serve_pyobject(
"available_bytes"
] = object_cache_available_bytes
web_app = build_app(
tree, {"allow_anonymous_access": public}, server_settings, scalable=scalable
tree,
{
"allow_anonymous_access": public,
"single_user_api_key": api_key,
},
server_settings,
scalable=scalable,
)
print_admin_api_key_if_generated(web_app, host=host, port=port)

Expand Down Expand Up @@ -507,6 +546,14 @@ def serve_config(
"option selected."
),
),
api_key: str = typer.Option(
None,
"--api-key",
help=(
"Set the single-user API key. "
"By default, a random key is generated at startup and printed."
),
),
host: str = typer.Option(
None,
help=(
Expand Down Expand Up @@ -543,6 +590,11 @@ def serve_config(
if "authentication" not in parsed_config:
parsed_config["authentication"] = {}
parsed_config["authentication"]["allow_anonymous_access"] = True
# Let --api-key flag override config.
if api_key:
if "authentication" not in parsed_config:
parsed_config["authentication"] = {}
parsed_config["authentication"]["single_user_api_key"] = api_key

# Delay this import so that we can fail faster if config-parsing fails above.

Expand Down
2 changes: 2 additions & 0 deletions tiled/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ def override_get_settings():
]:
if authentication.get(item) is not None:
setattr(settings, item, authentication[item])
if authentication.get("single_user_api_key") is not None:
settings.single_user_api_key_generated = False
for item in [
"allow_origins",
"response_bytesize_limit",
Expand Down