AIStore Authentication Server (AuthN) provides token-based secure access to AIStore. It employs the JSON Web Tokens framework to grant access to resources: buckets and objects. Please read a short introduction to JWT for details. Currently, we only support hash-based message authentication (HMAC) using SHA256 hash.
AuthN is a standalone server that manages users and tokens. If AuthN is enabled on a cluster, a client must request a token from AuthN and put it into HTTP headers of every request to the cluster. Requests without tokens are rejected.
A typical workflow looks as follows:
AuthN generates self-sufficient tokens: a proxy does not need access to AuthN to check permissions. Though, for security reasons, clusters should be registered at AuthN server. AuthN broadcasts revoked tokens to all registered clusters, so they updated their blacklists.
A workflow for the case when a token is revoked and only one cluster is registered. "AIS Cluster 2" is unregistered and allows requests with revoked token:
AuthN supports both HTTP and HTTPS protocols. By default, AuthN starts as an HTTP server listening on port 52001.
If you enable HTTPS access, make sure that the configuration file options server_crt and server_key point to the correct SSL certificate and key.
Environment variables used by the deployment script to setup AuthN server:
| Variable | Default value | Description |
|---|---|---|
| AIS_SECRET_KEY | aBitLongSecretKey |
A secret key to sign tokens |
| AUTH_ENABLED | false |
Set it to true to enable AuthN server and token-based access in AIStore proxy |
| AUTHN_PORT | 52001 |
Port on which AuthN listens to requests |
| AUTHN_TTL | 24h |
A token expiration time. Can be set to 0 which means "no expiration time" |
All variables can be set at AIStore cluster deployment. Example of starting a cluster with AuthN enabled:
$ AUTH_ENABLED=true make deployNote: don't forget to change the default secret key used to sign tokens before starting the deployment process.
To change AuthN settings after deployment, modify the server's configuration file and restart the server. If you change the server's secret key, make sure to modify AIStore proxy configuration as well.
At start, AuthN checks the user list. If it is empty, AuthN creates a default user that can access everything:
user ID is admin and password is admin. Do not forget to change the user's password for security reasons.
In this README:
AUTHSRV- denotes a (hostname:port) address of a deployed AuthN server
PROXY- (hostname:port) of a gateway(any gateway in a given AIS cluster)
| File | Location |
|---|---|
| Server configuration | $AUTHN_CONF_DIR/authn.json |
| User database | $AUTHN_CONF_DIR/authn.db |
| Log directory | $AIS_LOG_DIR/authn/log/ |
By default, AIStore deployment currently does not launch the AuthN server. To start AuthN manually, perform the following steps:
- Start authn server: <path_to_ais_binaries>/authn -config=<path_to_config_dir>/authn.json. Path to config directory is set at the time of cluster deployment and it is the same as the directory for AIStore proxies and targets
- Update AIS CLI configuration file: change AuthN URL. Alternatively, prepend AuthN URL to every CLI command that uses
authsubcommand:AUTHN_URL=http://10.10.1.190:52001 ais auth COMMAND - Change AIStore cluster configuration to enable token-based access and use the same secret as AuthN uses:
$ # Change the secret
$ ais cluster configure auth.secret SECRET
$ # Enable cluster-wide authorization
$ ais cluster configure auth.enabled true
$ # Register the cluster at AuthN to receive AuthN messages (e.g, revoked token list)
$ # ais auth add cluster CLUSTER_ALIAS CLUSTER-URL-LIST
$ ais auth add cluster mainCluster http://10.10.1.70:50001 http://10.10.1.71:50001
$ # Calling AuthN without modifying CLI configuration
$ # Assuming AuthN listens at http://10.10.1.190:52001
$ AUTHN_URL=http://10.10.1.190:52001 ais auth add cluster mainCluster http://10.10.1.70:50001 http://10.10.1.71:50001To increase security, a secret key for token generation can be put to Kubernetes secrets instead of keeping them in an AuthN configuration file. When secrets are used, AuthN overrides configuration values with environment variables set by Kubernetes.
Add secrets to AuthN pod description:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: container-name
image: image-name
env:
- name: SECRETKEY
valueFrom:
secretKeyRef:
name: mysecret
key: secret-key
In the example above the values in all-capitals are the names of the environment variables that AuthN looks for. All other values are arbitrary.
When AuthN pod starts, it loads its configuration from the local file, and then overrides secret values with ones from the pod's description.
After deploying the cluster, a superuser role Admin and admin account are created automatically.
Only users with Admin role can manage AuthN. Every request to AuthN(except login one) must
contain authentication token in the header:
Authorization: Bearer <token-issued-by-AuthN-after-login>
For curl, it is an argument -H 'Authorization: Bearer token'.
AIStore proxies and targets require a valid token in a request header - but only if AuthN is enabled. Every token includes all the information needed by a node:
- User name
- User ACL
- Time when the token expires
A proxy validates the token. The token must not be expired and it must not be on the blacklist (the list of revoked tokens). AuthN broadcasts the revoked token when it is added to AuthN. When AuthN registers a new cluster, it sends to the cluster the entire list of revoked tokens. Periodically the list is cleaned up: expired and invalid tokens are removed.
Generating a token for data access requires correct user name and password.
Token expiration time is 24 hours by default.
Modify expiration_time in the configuration file to change default expiration time.
To issue single token with custom expiration time, pass optional expiration duration in the request. Example: generate a token that expires in 5 hours. API:
POST {"password": "password", "expires_in": 18000000000000} /v1/users/usename
CLI:
$ ais auth login -p password usename -e 5hPass a zero value "expires_in": 0 to generate a never-expired token.
AuthN return the generated token in as a JSON formatted message. Example: {"token": "issued_token"}.
Call revoke token API to forcefully invalidate a token before it expires.
| Operation | HTTP Action | Example |
|---|---|---|
| Generate a token for a user (Log in) | POST {"password": "pass"} /v1/users/username | curl -X POST AUTHSRV/v1/users/username -d '{"password":"pass"}' -H 'Content-Type: application/json' |
| Revoke a token | DEL { "token": "issued_token" } /v1/tokens | curl -X DEL AUTHSRV/v1/tokens -d '{"token":"issued_token"}' -H 'Content-Type: application/json' |
When a cluster is registered, an arbitrary alias can be assigned for the cluster. CLI supports both cluster's ID and cluster's alias in commands. The alias is used to create default roles for a just registered cluster. If a cluster does not have an alias, the role names contain cluster ID.
| Operation | HTTP Action | Example |
|---|---|---|
| Get a list of registered clusters | GET /v1/clusters | curl -X GET AUTHSRV/v1/clusters |
| Get a registered cluster info | GET /v1/clusters/cluster-id | curl -X GET AUTHSRV/v1/clusters/cluster-id |
| Register a cluster | POST /v1/clusters {"id": "cluster-id", "alias": "cluster-alias", "urls": ["http://CLUSTERIP:PORT"]} | curl -X POST AUTHSRV/v1/clusters -d '{"id": "cluster-id", "alias": "cluster-alias", "urls": ["http://CLUSTERIP:PORT"]}' -H 'Content-Type: application/json' |
| Update a registered cluster | PUT /v1/clusters/id {"alias": "cluster-alias", "urls": ["http://CLUSTERIP:PORT"]} | curl -X PUT AUTHSRV/v1/clusters/id -d '{"alias": "cluster-alias", "urls": ["http://CLUSTERIP:PORT"]}' -H 'Content-Type: application/json' |
| Delete a registered cluster | DELETE /v1/clusters/cluster-id | curl -X DELETE AUTHSRV/v1/clusters/cluster-id |
| Operation | HTTP Action | Example |
|---|---|---|
| Get a list of roles | GET /v1/roles | curl -X GET AUTHSRV/v1/roles |
| Get a role | GET /v1/roles/ROLE_ID | curl -X GET AUTHSRV/v1/roles/ROLE_ID |
| Create a new role | POST /v1/roles {"name": "rolename", "desc": "description", "clusters": ["clusterid": permissions]} | curl -X AUTHSRV/v1/roles '{"name": "rolename", "desc": "description", "clusters": ["clusterid": permissions]}' |
| Update an existing role | PUT /v1/roles/role-name {"desc": "description", "clusters": ["clusterid": permissions]} | curl -X PUT AUTHSRV/v1/roles '{"desc": "description", "clusters": ["clusterid": permissions]}' |
| Delete a role | DELETE /v1/roles/role-name | curl -X DELETE AUTHSRV/v1/roles/role-name |
| Operation | HTTP Action | Example |
|---|---|---|
| Get a list of users | GET /v1/users | curl -X GET AUTHSRV/v1/users |
| Get a users | GET /v1/users/USER_ID | curl -X GET AUTHSRV/v1/users/USER_ID |
| Add a user | POST {"id": "username", "password": "pass", "roles": ["CluOne-owner", "CluTwo-readonly"]} /v1/users | curl -X POST AUTHSRV/v1/users -d '{"id": "username", "password":"pass", "roles": ["CluOne-owner", "CluTwo-readonly"]}' -H 'Content-Type: application/json' |
| Update an existing user | PUT {"password": "pass", "roles": ["CluOne-owner", "CluTwo-readonly"]} /v1/users/user-id | curl -X PUT AUTHSRV/v1/users/user-id -d '{"password":"pass", "roles": ["CluOne-owner", "CluTwo-readonly"]}' -H 'Content-Type: application/json' |
| Delete a user | DELETE /v1/users/username | curl -X DELETE AUTHSRV/v1/users/username |
| Operation | HTTP Action | Example |
|---|---|---|
| Get AuthN configuration | GET /v1/daemon | curl -X GET AUTHSRV/v1/daemon |
| Update AuthN configuration | PUT /v1/daemon { "auth": { "secret": "new_secret", "expiration_time": "24h"}} | curl -X PUT AUTHSRV/v1/daemon -d '{"auth": {"secret": "new_secret"}}' -H 'Content-Type: application/json' |
If the AuthN server is enabled, all requests to buckets and objects must contain a valid token issued by AuthN. Requests without a token are rejected.
Steps to generate and use a token:
- Superuser creates a user account
$ curl -X POST http://AUTHSRV/v1/users \
-d '{"name": "username", "password": "pass"}' \
-H 'Content-Type: application/json' -uadmin:admin- The user requests a token
$ curl -X POST http://AUTHSRV/v1/users/username \
-d '{"password": "pass"}' -H 'Content-Type: application/json'
{"token": "eyJhbGciOiJI.eyJjcmVkcyI.T6r6790"}- The user adds the token to every AIStore request (list buckets names example)
$ curl -L http://PROXY/v1/buckets/* -X GET \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer eyJhbGciOiJI.eyJjcmVkcyI.T6r6790"
{
"ais": [ "train-set-001", "train-set-002" ]
"gcp": [ "image-net-set-1" ],
}- Per-bucket authentication. It is currently impossible to limit user access to only a certain bucket, or buckets. Once users with read-write access log in, they have full access to all cluster's buckets.

