Skip to content

Commit f0bbd93

Browse files
committed
authn: mark as beta + enforce stricter access for user GET
Signed-off-by: Ryan Koo <rbk65@cornell.edu>
1 parent b752ff1 commit f0bbd93

File tree

6 files changed

+26
-6
lines changed

6 files changed

+26
-6
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ AIS consistently shows [balanced I/O distribution and linear scalability](https:
2222
***Data Consistency:** Guaranteed [consistency](/docs/overview.md#read-after-write-consistency) across all gateways, with [write-through](/docs/overview.md#write-through) semantics in presence of [remote backends](/docs/overview.md#backend-provider).
2323
***Small File Optimization:** AIS supports TAR, ZIP, TAR.GZ, and TAR.LZ4 serialization for batching and processing small files. Features include [initial sharding](https://aistore.nvidia.com/blog/2024/08/16/ishard), distributed shuffle (re-sharding), appending to existing shards, listing contained files, and [more](/docs/overview.md#shard).
2424
***Kubernetes:** For production deployments, we developed the [AIS/K8s Operator](https://github.com/NVIDIA/ais-k8s/tree/main/operator). A dedicated GitHub [repository](https://github.com/NVIDIA/ais-k8s) contains Ansible scripts, Helm charts, and deployment guidance.
25-
***Authentication and Access Control:** OAuth 2.0-compatible [authentication server (AuthN)](/docs/authn.md).
25+
***Authentication and Access Control:** OAuth 2.0-compatible [authentication server (AuthN)](/docs/authn.md)[^authn-beta].
2626
***Batch Jobs:** Start, monitor, and control cluster-wide [batch operations](/docs/batch.md).
2727

2828
The feature set is actively growing and also includes: [adding/removing nodes at runtime](/docs/lifecycle_node.md), managing [TLS certificates](/docs/cli/x509.md) at runtime, listing, copying, prefetching, and transforming [virtual directories](/docs/howto_virt_dirs.md), executing [presigned S3 requests](/docs/s3compat.md#presigned-s3-requests), adaptive [rate limiting](/docs/rate_limit.md), and more.
@@ -133,9 +133,11 @@ Let others know your project is powered by high-performance AI storage:
133133
* [Batch Jobs](/docs/batch.md)
134134
* [Performance](/docs/performance.md) and [CLI: performance](/docs/cli/performance.md)
135135
* [CLI Reference](/docs/cli.md)
136-
* [Authentication](/docs/authn.md)
136+
* [Authentication](/docs/authn.md)[^authn-beta]
137137
* [Production Deployment: Kubernetes Operator, Ansible Playbooks, Helm Charts, Monitoring](https://github.com/NVIDIA/ais-k8s)
138138

139+
[^authn-beta]: AuthN is under development and has *NOT* gone through a complete security audit.
140+
139141
### How to find information
140142

141143
* See [Extended Index](/docs/docs.md)

cmd/authn/hserv.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ func (h *hserv) httpUserGet(w http.ResponseWriter, r *http.Request) {
266266
code int
267267
)
268268
if len(items) == 0 {
269+
if err := validateAdminPerms(w, r); err != nil {
270+
return
271+
}
269272
if users, code, err = h.mgr.userList(); err != nil {
270273
cmn.WriteErr(w, r, err, code)
271274
return
@@ -276,6 +279,17 @@ func (h *hserv) httpUserGet(w http.ResponseWriter, r *http.Request) {
276279
writeJSON(w, users, "list users")
277280
return
278281
}
282+
tk, err := getToken(r)
283+
if err != nil {
284+
cmn.WriteErr(w, r, err, http.StatusUnauthorized)
285+
return
286+
}
287+
reqUser := items[0]
288+
if !tk.IsAdmin && tk.UserID != reqUser {
289+
err := errors.New("not authorized: requires admin or self")
290+
cmn.WriteErr(w, r, err, http.StatusUnauthorized)
291+
return
292+
}
279293
uInfo, code, err := h.mgr.lookupUser(items[0])
280294
if err != nil {
281295
cmn.WriteErr(w, r, err, code)

docs/authn.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,14 @@ When a cluster is registered, an arbitrary alias can be assigned to the cluster.
422422

423423
| Operation | HTTP Action | Example |
424424
|-------------------------|-------------|-----------------------------------------------------------------------------------------------------------------------|
425-
| Get a list of users | GET /v1/users | `curl -X GET $AUTHSRV/v1/users` |
426-
| Get a user | GET /v1/users/\<user-id\> | `curl -X GET $AUTHSRV/v1/users/<user-id>` |
425+
| Get a list of users | GET /v1/users | `curl -X GET $AUTHSRV/v1/users -H 'Authorization: Bearer <token>'` |
426+
| Get a user | GET /v1/users/\<user-id\> | `curl -X GET $AUTHSRV/v1/users/<user-id> -H 'Authorization: Bearer <token>'` |
427427
| Add a user | POST /v1/users | `curl -X POST $AUTHSRV/v1/users -d '{"id": "<user-id>", "password": "<password>", "roles": "[{<role-json>}]"' -H 'Authorization: Bearer <token>'` |
428428
| Update an existing user | PUT /v1/users/\<user-id\> | `curl -X PUT $AUTHSRV/v1/users/<user-id> -d '{"id": "<user-id>", "password": "<password>", "roles": "[{<role-json>}]"' -H 'Authorization: Bearer <token>'` |
429429
| Delete a user | DELETE /v1/users/\<user-id\> | `curl -X DELETE $AUTHSRV/v1/users/<user-id> -H 'Authorization: Bearer <token>'` |
430430

431+
> Note: A user can update their own password without admin privileges by issuing `PUT /v1/users/<user-id>` with only the `password` field set, authorized with their own token. A user can also retrieve their own user info via `GET /v1/users/<user-id>` using their own token.
432+
431433
### Configuration
432434

433435
| Operation | HTTP Action | Example |

docs/cli/auth.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ For quick getting-started (local-playground) session _and_ in-depth overview, pl
22

33
* [AIS AuthN documentation](/docs/authn.md).
44

5+
> Note: AuthN is currently in beta.
6+
57
## Table of contents
68

79
- [User Account and Access management](#user-account-and-access-management)

python/aistore/sdk/authn/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
The AIStore Authentication Server (AuthN) is a standalone service that provides secure, user- and role-based access to AIStore by leveraging [OAuth 2.0](https://oauth.net/2/) compliant [JSON Web Tokens (JWTs)](https://datatracker.ietf.org/doc/html/rfc7519). The `aistore.sdk.authn` sub-package in the Python SDK allows developers to interact with the AuthN server to manage authentication, users, roles, clusters, and tokens seamlessly.
44

5+
> Note: AuthN is currently in beta.
6+
57
> For more details, please refer to the [AuthN documentation](https://github.com/NVIDIA/aistore/blob/main/docs/authn.md).
68
79
### Quick Start

python/tests/integration/sdk/authn/test_authn_user_manager.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ def test_update_user_no_roles(self):
159159
# Test invalid login with old password
160160
with self.assertRaises(ErrUserInvalidCredentials):
161161
self.authn_client.login(self.user.id, "12345")
162-
self.authn_client.login(self.user.id, "123456")
163162

164163
# Check if the user has the same roles
165164
updated_user = self.user_manager.get(username=self.user.id)
@@ -187,7 +186,6 @@ def test_update_user(self):
187186
# Test invalid login with old password
188187
with self.assertRaises(ErrUserInvalidCredentials):
189188
self.authn_client.login(self.user.id, "12345")
190-
self.authn_client.login(self.user.id, "1234567")
191189

192190
# Check if the user has the new role and not the old role
193191
updated_user = self.user_manager.get(username=self.user.id)

0 commit comments

Comments
 (0)