# What Authentication Methods Does Multica Support? JWT, PAT, OAuth, and Daemon Tokens Explained

> Explore Multica's authentication: JWT for sessions, PAT for APIs, OAuth for sign-in, and Daemon Tokens for M2M. Secure your applications with Multica's flexible auth options.

- Repository: [multica-ai/multica](https://github.com/multica-ai/multica)
- Tags: api-reference
- Published: 2026-04-11

---

**Multica supports four distinct authentication mechanisms: JWT tokens for user sessions, Personal Access Tokens (PAT) for API access, Google OAuth for third-party sign-in, and Daemon Tokens for machine-to-machine authentication.**

The multica-ai/multica repository implements a comprehensive authentication layer in its Go backend that covers interactive users, programmatic clients, and background daemon processes. Understanding what authentication methods Multica supports is essential for securely integrating with its REST API, whether you are building a web frontend, automating CI/CD pipelines, or deploying persistent agent daemons.

## JSON Web Tokens (JWT)

Multica uses **JWT (JSON Web Token)** as its default session mechanism for authenticated users. These tokens are signed with HMAC-SHA256 and contain claims for the user ID, email, name, expiration (`exp`), and issued-at timestamp (`iat`).

### JWT Generation

After successful email-code verification or Google OAuth login, the backend issues a JWT through the `issueJWT` function in [`server/internal/handler/auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/handler/auth.go):

```go
func (h *Handler) issueJWT(user db.User) (string, error) {
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "sub":   uuidToString(user.ID),   // user ID
        "email": user.Email,
        "name":  user.Name,
        "exp":   time.Now().Add(30 * 24 * time.Hour).Unix(),
        "iat":   time.Now().Unix(),
    })
    return token.SignedString(auth.JWTSecret())
}

```

The signing secret originates from the `JWT_SECRET` environment variable (with a development fallback).

### JWT Validation

Incoming requests are validated by the **Auth** middleware in [`server/internal/middleware/auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/middleware/auth.go). The middleware extracts the `Authorization: Bearer <token>` header, parses the JWT using the shared secret, and injects `X-User-ID` and `X-User-Email` headers into the request context:

```go
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
        return nil, jwt.ErrSignatureInvalid
    }
    return auth.JWTSecret(), nil
})

```

## Personal Access Tokens (PAT)

For programmatic API access, Multica implements **Personal Access Tokens (PAT)**. These are long-lived credentials that allow scripts and integrations to authenticate without user sessions.

### PAT Structure and Generation

PATs are random 40-character hexadecimal strings prefixed with `mul_`. The `GeneratePATToken` function in [`server/internal/auth/jwt.go`](https://github.com/multica-ai/multica/blob/main/server/internal/auth/jwt.go) creates these tokens using cryptographic randomness:

```go
func GeneratePATToken() (string, error) {
    b := make([]byte, 20) // 20 bytes → 40 hex chars
    if _, err := rand.Read(b); err != nil {
        return "", fmt.Errorf("generate PAT token: %w", err)
    }
    return "mul_" + hex.EncodeToString(b), nil
}

```

### Secure Storage with SHA-256 Hashing

Security is enforced by never storing the raw token. Instead, the `HashToken` function computes a SHA-256 hash for database storage in the `personal_access_tokens` table:

```go
func HashToken(token string) string {
    h := sha256.Sum256([]byte(token))
    return hex.EncodeToString(h[:])
}

```

### PAT Validation in Middleware

When a request includes a `mul_` prefixed token, the middleware in [`server/internal/middleware/auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/middleware/auth.go) hashes the presented token and queries the database for a matching hash:

```go
if strings.HasPrefix(tokenString, "mul_") {
    hash := auth.HashToken(tokenString)
    pat, err := queries.GetPersonalAccessTokenByHash(r.Context(), hash)
    // …
}

```

## Google OAuth Integration

Multica supports **Google OAuth** as a third-party authentication provider, enabling users to sign in with their Google accounts.

### OAuth Flow Implementation

The `GoogleLogin` handler in [`server/internal/handler/auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/handler/auth.go) manages the server-side exchange:

```go
// Exchange the one‑time code for an access token.
tokenResp, err := http.PostForm("https://oauth2.googleapis.com/token", url.Values{
    "code":          {req.Code},
    "client_id":     {clientID},
    "client_secret": {clientSecret},
    "redirect_uri":  {redirectURI},
    "grant_type":    {"authorization_code"},
})

```

After exchanging the authorization code for an access token, the handler fetches the user's Google profile, creates or updates the local user record, and issues a standard JWT for session management.

## Daemon Tokens

For **machine-to-machine authentication** between background agents and the API, Multica uses Daemon Tokens prefixed with `mdt_`.

### Daemon Token Generation

Generated similarly to PATs via `GenerateDaemonToken` in [`server/internal/auth/jwt.go`](https://github.com/multica-ai/multica/blob/main/server/internal/auth/jwt.go), these tokens use a distinct prefix to trigger separate validation logic:

```go
func GenerateDaemonToken() (string, error) {
    b := make([]byte, 20)
    if _, err := rand.Read(b); err != nil {
        return "", fmt.Errorf("generate daemon token: %w", err)
    }
    return "mdt_" + hex.EncodeToString(b), nil
}

```

### Workspace-Scoped Validation

The **DaemonAuth** middleware in [`server/internal/middleware/daemon_auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/middleware/daemon_auth.go) validates these tokens. It checks not only the token's validity against the `daemon_tokens` table but also enforces that the daemon can only access its assigned workspace:

```go
if strings.HasPrefix(tokenString, "mdt_") {
    // look up token, verify workspace, then set X-Workspace-ID, X-User-ID …
}

```

## Practical Code Examples

### Authenticating with a JWT

```bash
curl -H "Authorization: Bearer <jwt-token>" \
     https://api.multica.ai/v1/issues

```

### Using a Personal Access Token

```bash
curl -H "Authorization: Bearer mul_abcdef1234..." \
     https://api.multica.ai/v1/projects

```

### Daemon Token Usage

```bash
curl -H "Authorization: Bearer mdt_1234abcd..." \
     -H "X-Workspace-ID: workspace-abc123" \
     https://api.multica.ai/v1/daemon/poll

```

## Summary

- **JWT tokens** provide temporary user sessions after email or OAuth login, validated by HMAC-SHA256 signatures in [`server/internal/middleware/auth.go`](https://github.com/multica-ai/multica/blob/main/server/internal/middleware/auth.go).
- **Personal Access Tokens** offer long-lived API credentials using `mul_` prefixed hashes stored in the `personal_access_tokens` table.
- **Google OAuth** enables third-party sign-in via the `GoogleLogin` handler, which exchanges codes for profiles and issues standard JWTs.
- **Daemon Tokens** facilitate secure machine-to-machine authentication with workspace scoping via the `DaemonAuth` middleware.

## Frequently Asked Questions

### Can I use Multica without Google OAuth?

Yes. Multica supports email-based authentication with verification codes, which issues standard JWT tokens upon successful validation. OAuth is optional and implemented alongside the native email-code flow.

### How are tokens revoked in Multica?

PATs and Daemon Tokens are revoked by deleting their SHA-256 hash entries from the respective database tables (`personal_access_tokens` or `daemon_tokens`). JWTs expire automatically based on their `exp` claim and cannot be individually revoked before expiration.

### What is the difference between a PAT and a Daemon Token?

While both use similar cryptographic generation in [`server/internal/auth/jwt.go`](https://github.com/multica-ai/multica/blob/main/server/internal/auth/jwt.go), **PATs** (`mul_` prefix) are validated by the standard `Auth` middleware for user-level API access, whereas **Daemon Tokens** (`mdt_` prefix) are processed by the `DaemonAuth` middleware which additionally enforces workspace isolation for background processes.

### Is the JWT secret configurable?

Yes. The `JWT_SECRET` environment variable configures the HMAC-SHA256 signing key. If not provided, the system uses a development default, which should not be used in production environments.