Crates.io | akas |
lib.rs | akas |
version | 2.4.13 |
created_at | 2024-08-23 21:10:05.049673+00 |
updated_at | 2025-08-25 13:22:03.251776+00 |
description | AKAS: API Key Authorization Server |
homepage | |
repository | https://gitlab.com/op_so/projects/akas |
max_upload_size | |
id | 1349629 |
size | 442,735 |
A simple and higth performance server to authorized HTTP requests by API key checks.
Authorization: Bearer <key>
The file of the list of the keys to be used for authorization should contain one key per line in plain or SHA-256 format:
8b89600015b273c28f966f368456e45e01df239a36bf939ff72a16881f775679
fb22be500af1ef0479745bbbce847854da33f5e910361ad278e0282995b95f4d
...
mykey-3532dceb-f38a-491b-814d-9607bc9a947a
mykey-c2d79a40-388e-4709-9e4b-903035b0e71e
...
$ ./akas --help
A HTTP API key-Based Authorization Server
Usage: akas <COMMAND>
Commands:
serve Start the server
load Load keys from file (Not yet implemented)
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
$./akas serve --help
Start the server
Usage: akas serve [OPTIONS]
Options:
--admin-key <ADMIN_KEY>
Admin key for /load and /status URI [env: AKAS_ADMIN_KEY=] [default: ]
--no-admin-key
No admin key flag
--local
Bind local adress only [env: AKAS_LOCAL=]
--enable-metrics
Enable Prometheus metrics endpoint [env: AKAS_ENABLE_METRICS=]
-p, --port <PORT>
Port of the server [env: AKAS_PORT=] [default: 5001]
--log-level <LOG_LEVEL>
Log level <error|warn|info|debug|trace> [env: AKAS_LOG_LEVEL=] [default: info]
--original-length <ORIGINAL_LENGTH>
Length of the x-forwarded-for, x-original header fields [env: AKAS_ORIGINAL_LENGTH=] [default: 100]
--metadata-length <METADATA_LENGTH>
Length of the metadata header field [env: AKAS_METADATA_LENGTH=] [default: 0]
--key-length <KEY_LENGTH>
Length of the key [optional] [env: AKAS_KEY_LENGTH=] [default: 0]
--key-prefix <KEY_PREFIX>
Prefix of the key [optional] [env: AKAS_KEY_PREFIX=] [default: ]
-h, --help
Print help
5001
./akas serve --admin-key my-admin-key
server {
listen 80;
server_name _;
location / {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /auth {
internal;
proxy_pass http://localhost:5001/auth;
proxy_pass_request_body off;
proxy_set_header content-length "";
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header x-original-host $host;
proxy_set_header x-original-uri $request_uri;
proxy_set_header x-akas-metadata "my-metadata";
}
}
More details of Nginx configuration can be found in the configuring subrequest authentication documentation
curl -H "Authorization: Bearer <key>" http://<host>/
/auth
: Authorization endpointIf the API key is present in the hashset
return 200 OK
,
otherwise return 401 Unauthorized
.
/load
Load new plain/hash keys file and replace the current keys in HashSet. The access is protected by an optional admin key.
Example of a curl
request:
curl -v \
-H "Authorization: Bearer my-admin-key" \
--url http://localhost:5001/load \
-F 'json={"format": "sha256", "hash_input_file": "43fcba0b3a ..."};type=application/json' \
-F file=@./tests/files/sha256_key.txt
Field | Description | Required | Default |
---|---|---|---|
file |
File path of the keys file to upload | Yes | - |
format |
Format of the keys <sha256|plain> | No | sha256 |
hash_input_file |
sha-256 of the uploaded file | No | - |
If the server is started without an admin key (--no-admin-key
), the header Authorization: Bearer
is still required with a fake key.
/status
Return the application state in JSON format. The access is protected by an optional admin key. Example:
{
"log_level": "INFO",
"original_length": 100,
"metadata_length": 0,
"file_hash": "43fcba0b3a5ab1b302f9d13617ae4eec6ae623a7fd52437dd992d5dca115e68d",
"file_date": "2024-11-09T14:07:23.416999558+00:00",
"file_key_count": 150,
"key_length": 42,
"key_prefix": "mykey-"
}
Example of request:
curl -v \
-H "Authorization: Bearer my-admin-key" \
http://localhost:5001/status
If the server is started without an admin key (--no-admin-key
), the header Authorization: Bearer
is still required with a fake key.
/metrics
Enabling the --enable-metrics
flag exposes Prometheus metrics via the /metrics
endpoint:
# HELP akas_http_requests_duration_seconds HTTP request duration in seconds for all requests
# TYPE akas_http_requests_duration_seconds histogram
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.005"} 1
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.01"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.025"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.05"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.1"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.25"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="0.5"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="1"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="2.5"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="5"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="10"} 2
akas_http_requests_duration_seconds_bucket{endpoint="/auth",method="GET",status="401",le="+Inf"} 2
akas_http_requests_duration_seconds_sum{endpoint="/auth",method="GET",status="401"} 0.005529125
akas_http_requests_duration_seconds_count{endpoint="/auth",method="GET",status="401"} 2
# HELP akas_http_requests_total Total number of HTTP requests
# TYPE akas_http_requests_total counter
akas_http_requests_total{endpoint="/auth",method="GET",status="401"} 2
# HELP auth_akas_requests_total Total number of requests for auth with custom labels
# TYPE auth_akas_requests_total counter
auth_akas_requests_total{endpoint="/auth",metadata="-",method="GET",status="401",x_original_host="-"} 2
/health
Returns 200 OK
to indicate the service is healthy and operational.
/auth-unauthorized
Always return 401 Unauthorized
without checking the key (for testing purposes or disable access).
serve
: Start serverload
: Load filestatus
: Get Hash of input file, datetime of load, number of valid keys./auth
: default endpoint./load
: Load new plain/hash keys file./status
: Get Hash of input file, datetime of load, number of valid keys./health
: indicate the service is healthy and operational./auth-unauthorized
: always return 401 Unauthorized
without checking the key./load
and /status
.https://crates.io/crates/tracing-actix-web
/load-diff
Load diff fileBinary file installation on Linux via the GitLab package registry of the project:
With a Rust environment, running this command will globally install the akas binary:
cargo install akas
The level of log is set with the RUST_LOG
environment variable:
{
"timestamp": "2025-05-29T22:25:56.133350Z",
"level": "INFO",
"fields": {
"message": "access authorized",
"key_hash": "92c55f4d88b1",
"forwarded_for": "203.0.113.195",
"original_host": "my-host.com",
"original_uri": "/some/path",
"metadata": "my-metadata",
"access": "authorized"
},
"target": "akas"
}
{
"timestamp": "2025-05-29T22:25:56.135564Z",
"level": "WARN",
"fields": {
"message": "access unauthorized",
"key_hash": "24328022c7341148e4d84fab687dff6bd1f7c836a73a307ceb3357a3b9bb2d9d",
"forwarded_for": "203.0.113.195",
"original_host": "my-host.com",
"original_uri": "/some/path",
"metadata": "my-metadata",
"access": "unauthorized"
},
"target": "akas"
}
Value | Description | Max field length |
---|---|---|
timestamp |
Date and time in ISO 8601 format | |
level |
Log level | |
fields.message |
Message | |
fields.key_hash |
sha256 key of the user, limited to 12 characters when authorized | |
fields.forwarded_for |
Extract of x-forwarded-for header field set by nginx, if not set: - |
--original-length option or AKAS_ORIGINAL_LENGTH env. variable [default: 100] |
fields.original_host |
Extract of x-original-host header field set by nginx, if not set: - |
--original-length option or AKAS_ORIGINAL_LENGTH env. variable [default: 100] |
fields.original_uri |
Extract of x-original-uri header field set by nginx, if not set: - |
--original-length option or AKAS_ORIGINAL_LENGTH env. variable [default: 100] |
fields.metadata |
Extract of x-akas-metadata header field set by nginx, if not set: - |
--metadata-length option or AKAS_METADATA_LENGTH env. variable [default: 0] |
fields.access |
authorized , unauthorized |
|
target |
Component |
More details:
AKAS employs two types of tests to ensure its quality:
Clone the source repository: git clone https://gitlab.com/op_so/projects/akas.git
To format and lint:
cargo fmt # cargo fmt -- --check
cargo clippy # Rust linter
cargo test # Unit and integration tests
cargo tarpaulin --ignore-tests # Code coverage
cargo audit # Security audit
To run: cargo run
To build:
cargo build # Debug binary target/debug/akas
cargo build --release # Release binary target/release/akas
This program is free software: you can redistribute it and/or modify it under the terms of the MIT License (MIT). See the LICENSE for details.