> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gofast.live/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> Authentication and Authorization

## Authentication

The main logic is located in the `auth/auth.go` file.

### JWT-Based Authentication

* JWT Authentication: The system uses JSON Web Tokens (JWT) with refresh token rotation for managing user sessions.
* Encryption: JWTs are encrypted using `EdDSA` for enhanced security.
* Server-Side Security: As much logic as possible is handled on the server side to maintain security.
* Token can be invalidated: Refresh tokens allow generating new JWTs and can be manually invalidated by clearing the `user_id` in the `tokens` table.
* Transport:
  * For `HTTP`, the tokens are sent in the `authorization` header as `Bearer` tokens.
  * For `gRPC`, the tokens are sent in the `metadata` as `authorization` tokens.
* Key Management:
  * Private/Public Key Pair: The system uses a private/public key pair for token validation.
  * Key Generation: To generate new keys, run the script:

```bash theme={null}
sh scripts/keys.sh
```

## Authorization

The main logic is located in the `auth/auth.go` file.

### Role-Based Access Control (RBAC)

* The main authorization mechanism is based on [Discord permissions](https://discord.com/developers/docs/topics/permissions).
* Each user has a set of permissions that are checked against the required permissions for a given action.
* Permissions are stored in a variable-length integer serialized into a string, and are calculated using bitwise operations.
* This allows for a high level of granularity in permissions, a very low storage overhead, and fast permission checks.

#### Permissions Constants

```go theme={null}
const (
	READ_NOTES  int64 = 0x0000000000000001
	INSERT_NOTE int64 = 0x0000000000000002
	UPDATE_NOTE int64 = 0x0000000000000004
	DELETE_NOTE int64 = 0x0000000000000008

	READ_PAYMENTS  int64 = 0x0000000000000010
	CREATE_PAYMENT int64 = 0x0000000000000020

	READ_EMAILS int64 = 0x0000000000000040
	SEND_EMAIL  int64 = 0x0000000000000080

	READ_FILES    int64 = 0x0000000000000100
	UPLOAD_FILE   int64 = 0x0000000000000200
	DOWNLOAD_FILE int64 = 0x0000000000000400
	DELETE_FILE   int64 = 0x0000000000000800
)
```

#### Checking Permissions

```go theme={null}
access := auth.NewAccess(user.Access)
if !access.HasAccess(auth.READ_NOTES) {
    return system.ErrForbidden{Message: "Access denied"}
}
```

### Attribute-Based Access Control (ABAC)

* The system also supports Attribute-Based Access Control (ABAC) for more complex access control scenarios.
* Define policies in the `CheckUserAttr` function:

```go theme={null}
func CheckUserAttr(access int64, userAttr *UserAttr) bool {
	if access == UPDATE_NOTE {
		return userAttr.Department == "IT" && userAttr.Position == "Developer"
	}
	if access == DELETE_NOTE {
		return userAttr.Department == "IT" && userAttr.Position == "Admin"
	}
	return true
}
```

And then check the access:

```go theme={null}
if !auth.NewAccessWithAttr(user.Access, userAttr).HasAccess(auth.UPDATE_NOTE) {
    return system.ErrForbidden{Message: "Access denied"}
}
```

## How to Use

Combine the two mechanisms to create a secure and flexible access control system.
The flow start with extracting the token from the request, either from the `authorization` header or the `metadata`.
Then, in the service layer, validate the token and check the access:

```go theme={null}
user, err := sauthystem.ValidateToken(token)
if err != nil {
    return system.ErrUnauthorized{Err: err}
}
access := auth.NewAccess(user.Access)
if !access.HasAccess(auth.READ_NOTES) {
    return system.ErrForbidden{Message: "Access denied"}
}
```

## Need help?

Visit our discord server to ask any questions, make suggestions and give feedback :).

[https://discord.gg/EdSZbQbRyJ](https://discord.gg/EdSZbQbRyJ)
