mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-26 01:58:21 +03:00
update auth api endpoint descriptions and docs
This commit is contained in:
parent
1f60c64a5e
commit
743acd87fd
@ -270,3 +270,42 @@ To use role-based access control, you must connect to Frigate via the **authenti
|
||||
1. Log in as an **admin** user via port `8971`.
|
||||
2. Navigate to **Settings > Users**.
|
||||
3. Edit a user’s role by selecting **admin** or **viewer**.
|
||||
|
||||
## API Authentication Guide
|
||||
|
||||
## Getting a Bearer Token
|
||||
|
||||
To use the Frigate API, you need to authenticate first. Follow these steps to obtain a Bearer token:
|
||||
|
||||
### 1. Login
|
||||
|
||||
Make a POST request to `/login` with your credentials:
|
||||
|
||||
```bash
|
||||
curl -i -X POST https://frigate_ip:8971/api/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"user": "admin", "password": "your_password"}'
|
||||
```
|
||||
|
||||
::: note
|
||||
|
||||
You may need to include `-k` in the argument list in these steps (eg: `curl -k -i -X POST ...`) if your Frigate instance is using a self-signed certificate.
|
||||
|
||||
:::
|
||||
|
||||
The response will contain a cookie with the JWT token.
|
||||
|
||||
### 2. Using the Bearer Token
|
||||
|
||||
Once you have the token, include it in the Authorization header for subsequent requests:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <your_token>" https://frigate_ip:8971/api/profile
|
||||
```
|
||||
|
||||
### 3. Token Lifecycle
|
||||
|
||||
- Tokens are valid for the configured session length
|
||||
- Tokens are automatically refreshed when you visit the `/auth` endpoint
|
||||
- Tokens are invalidated when the user's password is changed
|
||||
- Use `/logout` to clear your session cookie
|
||||
|
||||
105
docs/static/frigate-api.yaml
vendored
105
docs/static/frigate-api.yaml
vendored
@ -14,7 +14,11 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Auth
|
||||
summary: Authenticate request
|
||||
description: |-
|
||||
Authenticates the current request based on proxy headers or JWT token.
|
||||
Returns user role and permissions for camera access.
|
||||
This endpoint verifies authentication credentials and manages JWT token refresh.
|
||||
operationId: auth_auth_get
|
||||
responses:
|
||||
"200":
|
||||
@ -22,11 +26,21 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"202":
|
||||
description: Authentication Accepted
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"401":
|
||||
description: Authentication Failed
|
||||
/profile:
|
||||
get:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Profile
|
||||
summary: Get user profile
|
||||
description: |-
|
||||
Returns the current authenticated user's profile including username, role, and allowed cameras.
|
||||
This endpoint requires authentication and returns information about the user's permissions.
|
||||
operationId: profile_profile_get
|
||||
responses:
|
||||
"200":
|
||||
@ -34,11 +48,16 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"401":
|
||||
description: Unauthorized
|
||||
/logout:
|
||||
get:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Logout
|
||||
summary: Logout user
|
||||
description: |-
|
||||
Logs out the current user by clearing the session cookie.
|
||||
After logout, subsequent requests will require re-authentication.
|
||||
operationId: logout_logout_get
|
||||
responses:
|
||||
"200":
|
||||
@ -46,11 +65,22 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"303":
|
||||
description: See Other (redirects to login page)
|
||||
/login:
|
||||
post:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Login
|
||||
summary: Login with credentials
|
||||
description: |-
|
||||
Authenticates a user with username and password.
|
||||
Returns a JWT token as a secure HTTP-only cookie that can be used for subsequent API requests.
|
||||
The JWT token can also be retrieved from the response and used as a Bearer token in the Authorization header.
|
||||
|
||||
Example using Bearer token:
|
||||
```
|
||||
curl -H "Authorization: Bearer <token_value>" https://frigate_ip:8971/api/profile
|
||||
```
|
||||
operationId: login_login_post
|
||||
requestBody:
|
||||
required: true
|
||||
@ -64,6 +94,11 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"401":
|
||||
description: Login Failed - Invalid credentials
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"422":
|
||||
description: Validation Error
|
||||
content:
|
||||
@ -74,7 +109,10 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Get Users
|
||||
summary: Get all users
|
||||
description: |-
|
||||
Returns a list of all users with their usernames and roles.
|
||||
Requires admin role. Each user object contains the username and assigned role.
|
||||
operationId: get_users_users_get
|
||||
responses:
|
||||
"200":
|
||||
@ -82,10 +120,19 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"403":
|
||||
description: Forbidden - Admin role required
|
||||
post:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Create User
|
||||
summary: Create new user
|
||||
description: |-
|
||||
Creates a new user with the specified username, password, and role.
|
||||
Requires admin role. Password must meet strength requirements:
|
||||
- Minimum 8 characters
|
||||
- At least one uppercase letter
|
||||
- At least one digit
|
||||
- At least one special character (!@#$%^&*(),.?":{}\|<>)
|
||||
operationId: create_user_users_post
|
||||
requestBody:
|
||||
required: true
|
||||
@ -99,6 +146,13 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request - Invalid username or role
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"403":
|
||||
description: Forbidden - Admin role required
|
||||
"422":
|
||||
description: Validation Error
|
||||
content:
|
||||
@ -109,7 +163,10 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Delete User
|
||||
summary: Delete user
|
||||
description: |-
|
||||
Deletes a user by username. The built-in admin user cannot be deleted.
|
||||
Requires admin role. Returns success message or error if user not found.
|
||||
operationId: delete_user_users__username__delete
|
||||
parameters:
|
||||
- name: username
|
||||
@ -118,12 +175,15 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
title: Username
|
||||
description: The username of the user to delete
|
||||
responses:
|
||||
"200":
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"403":
|
||||
description: Forbidden - Cannot delete admin user or admin role required
|
||||
"422":
|
||||
description: Validation Error
|
||||
content:
|
||||
@ -134,7 +194,17 @@ paths:
|
||||
put:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Update Password
|
||||
summary: Update user password
|
||||
description: |-
|
||||
Updates a user's password. Users can only change their own password unless they have admin role.
|
||||
Requires the current password to verify identity for non-admin users.
|
||||
Password must meet strength requirements:
|
||||
- Minimum 8 characters
|
||||
- At least one uppercase letter
|
||||
- At least one digit
|
||||
- At least one special character (!@#$%^&*(),.?":{}\|<>)
|
||||
|
||||
If user changes their own password, a new JWT cookie is automatically issued.
|
||||
operationId: update_password_users__username__password_put
|
||||
parameters:
|
||||
- name: username
|
||||
@ -143,6 +213,7 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
title: Username
|
||||
description: The username of the user whose password to update
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@ -155,6 +226,14 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request - Current password required or password doesn't meet requirements
|
||||
"401":
|
||||
description: Unauthorized - Current password is incorrect
|
||||
"403":
|
||||
description: Forbidden - Viewers can only update their own password
|
||||
"404":
|
||||
description: Not Found - User not found
|
||||
"422":
|
||||
description: Validation Error
|
||||
content:
|
||||
@ -165,7 +244,10 @@ paths:
|
||||
put:
|
||||
tags:
|
||||
- Auth
|
||||
summary: Update Role
|
||||
summary: Update user role
|
||||
description: |-
|
||||
Updates a user's role. The built-in admin user's role cannot be modified.
|
||||
Requires admin role. Valid roles are defined in the configuration.
|
||||
operationId: update_role_users__username__role_put
|
||||
parameters:
|
||||
- name: username
|
||||
@ -174,6 +256,7 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
title: Username
|
||||
description: The username of the user whose role to update
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@ -186,6 +269,10 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request - Invalid role
|
||||
"403":
|
||||
description: Forbidden - Cannot modify admin user's role or admin role required
|
||||
"422":
|
||||
description: Validation Error
|
||||
content:
|
||||
|
||||
@ -549,7 +549,12 @@ def resolve_role(
|
||||
|
||||
|
||||
# Endpoints
|
||||
@router.get("/auth", dependencies=[Depends(allow_public())])
|
||||
@router.get(
|
||||
"/auth",
|
||||
dependencies=[Depends(allow_public())],
|
||||
summary="Authenticate request",
|
||||
description="Authenticates the current request based on proxy headers or JWT token. Returns user role and permissions for camera access.",
|
||||
)
|
||||
def auth(request: Request):
|
||||
auth_config: AuthConfig = request.app.frigate_config.auth
|
||||
proxy_config: ProxyConfig = request.app.frigate_config.proxy
|
||||
@ -689,7 +694,12 @@ def auth(request: Request):
|
||||
return fail_response
|
||||
|
||||
|
||||
@router.get("/profile", dependencies=[Depends(allow_any_authenticated())])
|
||||
@router.get(
|
||||
"/profile",
|
||||
dependencies=[Depends(allow_any_authenticated())],
|
||||
summary="Get user profile",
|
||||
description="Returns the current authenticated user's profile including username, role, and allowed cameras.",
|
||||
)
|
||||
def profile(request: Request):
|
||||
username = request.headers.get("remote-user", "anonymous")
|
||||
role = request.headers.get("remote-role", "viewer")
|
||||
@ -703,7 +713,12 @@ def profile(request: Request):
|
||||
)
|
||||
|
||||
|
||||
@router.get("/logout", dependencies=[Depends(allow_public())])
|
||||
@router.get(
|
||||
"/logout",
|
||||
dependencies=[Depends(allow_public())],
|
||||
summary="Logout user",
|
||||
description="Logs out the current user by clearing the session cookie.",
|
||||
)
|
||||
def logout(request: Request):
|
||||
auth_config: AuthConfig = request.app.frigate_config.auth
|
||||
response = RedirectResponse("/login", status_code=303)
|
||||
@ -714,7 +729,12 @@ def logout(request: Request):
|
||||
limiter = Limiter(key_func=get_remote_addr)
|
||||
|
||||
|
||||
@router.post("/login", dependencies=[Depends(allow_public())])
|
||||
@router.post(
|
||||
"/login",
|
||||
dependencies=[Depends(allow_public())],
|
||||
summary="Login with credentials",
|
||||
description="Authenticates a user with username and password. Returns a JWT token as a secure HTTP-only cookie that can be used for subsequent API requests. The token can also be retrieved and used as a Bearer token in the Authorization header.",
|
||||
)
|
||||
@limiter.limit(limit_value=rateLimiter.get_limit)
|
||||
def login(request: Request, body: AppPostLoginBody):
|
||||
JWT_COOKIE_NAME = request.app.frigate_config.auth.cookie_name
|
||||
@ -752,7 +772,12 @@ def login(request: Request, body: AppPostLoginBody):
|
||||
return JSONResponse(content={"message": "Login failed"}, status_code=401)
|
||||
|
||||
|
||||
@router.get("/users", dependencies=[Depends(require_role(["admin"]))])
|
||||
@router.get(
|
||||
"/users",
|
||||
dependencies=[Depends(require_role(["admin"]))],
|
||||
summary="Get all users",
|
||||
description="Returns a list of all users with their usernames and roles. Requires admin role.",
|
||||
)
|
||||
def get_users():
|
||||
exports = (
|
||||
User.select(User.username, User.role).order_by(User.username).dicts().iterator()
|
||||
@ -760,7 +785,12 @@ def get_users():
|
||||
return JSONResponse([e for e in exports])
|
||||
|
||||
|
||||
@router.post("/users", dependencies=[Depends(require_role(["admin"]))])
|
||||
@router.post(
|
||||
"/users",
|
||||
dependencies=[Depends(require_role(["admin"]))],
|
||||
summary="Create new user",
|
||||
description="Creates a new user with the specified username, password, and role. Requires admin role. Password must meet strength requirements.",
|
||||
)
|
||||
def create_user(
|
||||
request: Request,
|
||||
body: AppPostUsersBody,
|
||||
@ -789,7 +819,12 @@ def create_user(
|
||||
return JSONResponse(content={"username": body.username})
|
||||
|
||||
|
||||
@router.delete("/users/{username}", dependencies=[Depends(require_role(["admin"]))])
|
||||
@router.delete(
|
||||
"/users/{username}",
|
||||
dependencies=[Depends(require_role(["admin"]))],
|
||||
summary="Delete user",
|
||||
description="Deletes a user by username. The built-in admin user cannot be deleted. Requires admin role.",
|
||||
)
|
||||
def delete_user(request: Request, username: str):
|
||||
# Prevent deletion of the built-in admin user
|
||||
if username == "admin":
|
||||
@ -802,7 +837,10 @@ def delete_user(request: Request, username: str):
|
||||
|
||||
|
||||
@router.put(
|
||||
"/users/{username}/password", dependencies=[Depends(allow_any_authenticated())]
|
||||
"/users/{username}/password",
|
||||
dependencies=[Depends(allow_any_authenticated())],
|
||||
summary="Update user password",
|
||||
description="Updates a user's password. Users can only change their own password unless they have admin role. Requires the current password to verify identity. Password must meet strength requirements (minimum 8 characters, uppercase letter, digit, and special character).",
|
||||
)
|
||||
async def update_password(
|
||||
request: Request,
|
||||
@ -887,6 +925,8 @@ async def update_password(
|
||||
@router.put(
|
||||
"/users/{username}/role",
|
||||
dependencies=[Depends(require_role(["admin"]))],
|
||||
summary="Update user role",
|
||||
description="Updates a user's role. The built-in admin user's role cannot be modified. Requires admin role.",
|
||||
)
|
||||
async def update_role(
|
||||
request: Request,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user