API Endpoints: User and Token
Relevant source files
The following files were used as context for generating this wiki page:
The User and Token management system is a core component of huskyCI's API, responsible for securing access and authorizing actions. It provides functionalities for user authentication via Basic Auth, user data management, and the generation and invalidation of repository-specific access tokens. These tokens are essential for the huskyCI client to securely submit code for analysis.
Upon initialization, the API ensures a default user is present in the database, creating one if it doesn't exist. This ensures the system is immediately usable after setup. All user and token-related endpoints are grouped under the /api/1.0 route and are protected by a Basic Authentication middleware.
Sources: api/server.go:39-47, 72-75, api/util/api/api.go:65-71, 201-214
Authentication
Authentication for sensitive endpoints is handled via HTTP Basic Authentication. The API server uses a dedicated middleware to protect routes under the /api/1.0 group, which includes all user and token management endpoints.
Sources: api/server.go:72-75
Basic Authentication Flow
The auth.ValidateUser function serves as the middleware handler for Basic Auth. For each incoming request to a protected route, this function executes the following steps:
- Retrieves the
usernameandpasswordfrom theAuthorizationheader. - Queries the database for a user with the provided username.
- If the user is found, it reconstructs the password hash using the provided password and the user's stored salt, iterations, key length, and hash function.
- It compares the reconstructed hash with the one stored in the database.
- Access is granted only if the hashes match.
The diagram below illustrates the Basic Authentication validation sequence.
Diagram based on logic in api/auth/auth.go.
The password hashing uses the PBKDF2 algorithm, with parameters (salt, iterations, key length) stored per-user in the database.
Sources: api/auth/auth.go:21-48, api/types/types.go:72-79
API Endpoints
The following table summarizes the main user and token management endpoints. All are prefixed with /api/1.0 and require Basic Authentication.
| Method | Endpoint | Handler | Description |
|---|---|---|---|
PUT | /user | routes.UpdateUser | Updates the authenticated user's password. |
POST | /token | routes.HandleToken | Generates a new access token for a repository. |
POST | /token/deactivate | routes.HandleDeactivation | Invalidates an existing access token. |
Sources: api/server.go:78-81, 98-99
User Management
User management currently consists of updating a user's password and the automated creation of a default user on startup.
User Data Structure
The User object contains all necessary information for authentication and management.
| Field | Type | Description |
|---|---|---|
Username | string | The user's unique username. |
Password | string | The user's plain-text password (used for requests, not stored). |
Salt | string | The salt used for password hashing (stored in the database). |
Iterations | int | The number of iterations for the PBKDF2 algorithm (stored). |
KeyLen | int | The key length for the PBKDF2 algorithm (stored). |
HashFunction | string | The name of the hash function used (e.g., "sha256") (stored). |
NewPassword | string | The new password, provided during an update request. |
ConfirmNewPassword | string | Confirmation of the new password, provided during an update request. |
Sources: api/types/types.go:72-79
Default User Creation
On API startup, the checkDefaultUser function verifies if the default user (defined as user.DefaultAPIUser) exists in the database. If the user is not found, it calls user.InsertDefaultUser to create it using credentials from environment variables (HUSKYCI_API_DEFAULT_USERNAME, HUSKYCI_API_DEFAULT_PASSWORD).
Sources: api/util/api/api.go:65-71, 201-214
Update User (PUT /user)
This endpoint allows an authenticated user to change their password. The UpdateUser handler performs the following actions:
- Binds the JSON request body to a
Userstruct. - Validates that
NewPasswordandConfirmNewPasswordmatch. - Hashes the new password using a newly generated salt.
- Updates the user's record in the database with the new password hash and salt.
The following flowchart shows the logic for updating a user's password.
Diagram based on logic in api/routes/user.go.
Sources: api/routes/user.go:21-55
Token Management
Access tokens are repository-specific credentials used by the huskyCI client to authenticate when submitting a new analysis. This prevents a token for one repository from being used for another.
Token Data Structures
Several structs are used to handle token requests and storage.
TokenRequest: The JSON body sent to the /token endpoint.
RepositoryURL(string): The URL of the repository for which a token is being requested.
AccessToken: The JSON response after a successful token generation.
HuskyToken(string): The generated access token.
DBToken: The structure used to store token information in the database.
| Field | Type | Description |
|---|---|---|
HuskyToken | string | The PBKDF2 hash of the random part of the token. |
URL | string | The repository URL this token is valid for. |
IsValid | bool | A flag indicating if the token is active. Set to false on deactivation. |
CreatedAt | time.Time | Timestamp of token creation. |
Salt | string | The salt used to hash the HuskyToken. |
UUID | string | A unique identifier for this token record. |
Sources: api/types/types.go:154-177
Generate Token (POST /token)
This endpoint generates a new access token for a given repository URL. The token consists of a UUID and a random string, encoded together.
The flow is as follows:
- The
HandleTokenroute handler receives aTokenRequest. - It calls
token.GenerateAccessTokenwith the repository URL. GenerateAccessTokenvalidates the URL.- It generates a secure random token and a salt.
- It hashes the random token using PBKDF2 with the new salt.
- A new
DBTokenrecord is created with the hashed token, a new UUID, the salt, and the repository URL. This record is stored in the database. - The function returns a Base64-encoded string combining the
UUIDand the original (un-hashed) random token, in the formatUUID:random_token. This is theHuskyTokensent to the client.
The sequence diagram below details this process.
Diagram based on logic in api/routes/token.go:21-39 and api/token/token.go:22-58.
Deactivate Token (POST /token/deactivate)
This endpoint invalidates an existing access token.
- The
HandleDeactivationhandler receives thehuskytokenfrom the request body. - It calls
token.InvalidateToken. InvalidateTokendecodes the token to extract theUUID.- It finds the corresponding
DBTokenrecord in the database using theUUID. - It sets the
IsValidflag on that record tofalseand updates the database.
Diagram based on logic in api/routes/token.go:41-57 and api/token/token.go:143-154.
Token Validation
Although not exposed as a direct endpoint, the token.ValidateToken function is critical for other parts of the application (like handling analysis requests). It validates a token by:
- Splitting the received token into its
UUIDandrandomDataparts. - Finding the
DBTokenin the database via theUUID. - Checking if the token
IsValidand if itsURLmatches the repository URL of the incoming request. - Re-hashing the
randomDatawith the storedsaltand comparing it to the storedHuskyTokenhash.
Sources: api/token/token.go:127-141
Conclusion
The user and token management system provides the necessary security layer for the huskyCI API. It uses standard Basic Authentication for user access to management endpoints and a robust, repository-specific token system for programmatic access from CI/CD pipelines. The separation of concerns, with clear handlers for routing, core logic for token operations, and well-defined data structures, creates a secure and maintainable authentication and authorization module.