> For the complete documentation index, see [llms.txt](https://access-hub.gitbook.io/access-hub-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://access-hub.gitbook.io/access-hub-docs/authentication.md).

# Authentication

Account registration and authentication

## Register an Employee account

> Validates the public account details, hashes the password, and creates\
> a user with the seeded Employee role.<br>

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"paths":{"/api/v1/auth/register":{"post":{"tags":["Authentication"],"summary":"Register an Employee account","description":"Validates the public account details, hashes the password, and creates\na user with the seeded Employee role.\n","operationId":"registerUser","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationRequest"}}}},"responses":{"201":{"description":"Account created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicUser"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"409":{"$ref":"#/components/responses/ConflictError"},"503":{"description":"Registration is unavailable because required RBAC seed data is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"RegistrationRequest":{"type":"object","required":["username","email","password"],"properties":{"username":{"type":"string","minLength":3},"email":{"type":"string","format":"email"},"password":{"type":"string","format":"password","minLength":8,"writeOnly":true},"full_name":{"type":"string","nullable":true,"maxLength":150}}},"PublicUser":{"type":"object","required":["id","username","email","is_active","is_suspended"],"properties":{"id":{"type":"integer"},"username":{"type":"string"},"email":{"type":"string","format":"email"},"full_name":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"is_suspended":{"type":"boolean"}}},"ValidationErrors":{"type":"object","required":["errors"],"properties":{"errors":{"type":"object","additionalProperties":{"type":"string"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}},"responses":{"ValidationError":{"description":"Request validation or a business rule failed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrors"},{"$ref":"#/components/schemas/Error"}]}}}},"ConflictError":{"description":"The username or email is already registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Log in with a username or email

> Verifies the credentials and returns one access/refresh token pair.

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"paths":{"/api/v1/auth/login":{"post":{"tags":["Authentication"],"summary":"Log in with a username or email","description":"Verifies the credentials and returns one access/refresh token pair.","operationId":"loginUser","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Authentication succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"description":"The credentials are invalid or the account is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"LoginRequest":{"type":"object","required":["identifier","password"],"properties":{"identifier":{"type":"string","description":"Registered username or email address."},"password":{"type":"string","format":"password","writeOnly":true}}},"TokenPair":{"type":"object","required":["access_token","refresh_token","token_type"],"properties":{"access_token":{"type":"string","description":"Short-lived JWT used to authorize API requests."},"refresh_token":{"type":"string","description":"Long-lived JWT used only at the refresh endpoint."},"token_type":{"type":"string"}}},"ValidationErrors":{"type":"object","required":["errors"],"properties":{"errors":{"type":"object","additionalProperties":{"type":"string"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}},"responses":{"ValidationError":{"description":"Request validation or a business rule failed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrors"},{"$ref":"#/components/schemas/Error"}]}}}}}}}
```

## Get the current account

> Returns public account and role information for the access-token owner.

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Enter the access token returned by the login endpoint."}},"schemas":{"CurrentUser":{"allOf":[{"$ref":"#/components/schemas/PublicUser"},{"type":"object","required":["role"],"properties":{"role":{"type":"string","nullable":true}}}]},"PublicUser":{"type":"object","required":["id","username","email","is_active","is_suspended"],"properties":{"id":{"type":"integer"},"username":{"type":"string"},"email":{"type":"string","format":"email"},"full_name":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"is_suspended":{"type":"boolean"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"JwtError":{"type":"object","required":["msg"],"properties":{"msg":{"type":"string"}}}},"responses":{"UnauthorizedError":{"description":"The token is missing, invalid, expired, revoked, or has the wrong type.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/JwtError"}]}}}}}},"paths":{"/api/v1/auth/me":{"get":{"tags":["Authentication"],"summary":"Get the current account","description":"Returns public account and role information for the access-token owner.","operationId":"getCurrentUser","responses":{"200":{"description":"Current account information.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUser"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}}}}
```

## Test access-token authentication

> Demonstrates a route that requires a valid access token and active account.

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Enter the access token returned by the login endpoint."}},"schemas":{"ProtectedResponse":{"type":"object","required":["message","user_id"],"properties":{"message":{"type":"string"},"user_id":{"type":"integer"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"JwtError":{"type":"object","required":["msg"],"properties":{"msg":{"type":"string"}}}},"responses":{"UnauthorizedError":{"description":"The token is missing, invalid, expired, revoked, or has the wrong type.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/JwtError"}]}}}}}},"paths":{"/api/v1/auth/protected":{"get":{"tags":["Authentication"],"summary":"Test access-token authentication","description":"Demonstrates a route that requires a valid access token and active account.","operationId":"accessProtectedResource","responses":{"200":{"description":"The access token and account are valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}}}}
```

## Issue a new access token

> Requires the refresh token in the Bearer header. The new access token\
> retains the original session ID and cannot outlive the shared session.<br>

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Enter the access token returned by the login endpoint."}},"schemas":{"AccessTokenResponse":{"type":"object","required":["access_token","token_type"],"properties":{"access_token":{"type":"string","description":"Newly issued short-lived JWT."},"token_type":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"JwtError":{"type":"object","required":["msg"],"properties":{"msg":{"type":"string"}}}},"responses":{"UnauthorizedError":{"description":"The token is missing, invalid, expired, revoked, or has the wrong type.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/JwtError"}]}}}}}},"paths":{"/api/v1/auth/refresh":{"post":{"tags":["Authentication"],"summary":"Issue a new access token","description":"Requires the refresh token in the Bearer header. The new access token\nretains the original session ID and cannot outlive the shared session.\n","operationId":"refreshAccessToken","responses":{"200":{"description":"A new access token was issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessTokenResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}}}}
```

## Revoke the current login session

> Accepts either token from the pair and revokes their shared session.\
> After logout, both the access token and refresh token become unusable.<br>

```json
{"openapi":"3.0.3","info":{"title":"Access Hub API","version":"0.2.0"},"tags":[{"name":"Authentication","description":"Account registration and authentication"}],"servers":[{"url":"/","description":"Same server hosting this documentation"},{"url":"http://localhost:5000","description":"Local native Flask server"},{"url":"http://localhost:5001","description":"Local Docker Compose"},{"url":"https://authmicroservice.up.railway.app","description":"Railway deployment"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Enter the access token returned by the login endpoint."}},"schemas":{"MessageResponse":{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"JwtError":{"type":"object","required":["msg"],"properties":{"msg":{"type":"string"}}}},"responses":{"UnauthorizedError":{"description":"The token is missing, invalid, expired, revoked, or has the wrong type.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/JwtError"}]}}}}}},"paths":{"/api/v1/auth/logout":{"post":{"tags":["Authentication"],"summary":"Revoke the current login session","description":"Accepts either token from the pair and revokes their shared session.\nAfter logout, both the access token and refresh token become unusable.\n","operationId":"logoutUser","responses":{"200":{"description":"The shared session was revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://access-hub.gitbook.io/access-hub-docs/authentication.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
