@mastra/core
Version:
357 lines (221 loc) • 12.6 kB
Markdown
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
# MastraAuthGoogle and MastraRBACGoogle class
## MastraAuthGoogle class
The `MastraAuthGoogle` class provides authentication for Mastra using Google Workspace. It implements an OAuth 2.0 / OIDC login flow with encrypted session cookies, verifies Google ID tokens, and integrates with the Mastra server using the `auth` option.
### Usage example
```typescript
import { Mastra } from '@mastra/core'
import { MastraAuthGoogle } from '@mastra/auth-google'
export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: process.env.GOOGLE_REDIRECT_URI,
allowedDomains: ['example.com'],
}),
},
})
```
> **Note:** You can omit the constructor parameters if you have the appropriately named environment variables set. In that case, use `new MastraAuthGoogle()` without any arguments.
### Constructor parameters
**clientId** (`string`): Google OAuth client ID. (Default: `process.env.GOOGLE_CLIENT_ID`)
**clientSecret** (`string`): Google OAuth client secret. Required for Studio SSO. (Default: `process.env.GOOGLE_CLIENT_SECRET`)
**redirectUri** (`string`): OAuth redirect URI for the SSO callback. Must match the redirect URI configured in your Google Cloud OAuth client. (Default: `process.env.GOOGLE_REDIRECT_URI`)
**scopes** (`string[]`): OAuth scopes requested during the login flow. (Default: `['openid', 'profile', 'email']`)
**allowedDomains** (`string | string[]`): Allowed Google Workspace hosted domains. Mastra validates these against the verified hd claim. (Default: `process.env.GOOGLE_ALLOWED_DOMAINS`)
**hostedDomain** (`string`): Hosted-domain login hint passed to Google as hd. This is a hint only and is not used for authorization. (Default: `process.env.GOOGLE_HOSTED_DOMAIN or the single allowed domain`)
**session** (`GoogleSessionOptions`): Session cookie configuration.
**session.cookieName** (`string`): Name of the session cookie.
**session.cookieMaxAge** (`number`): Cookie max age in seconds.
**session.cookiePassword** (`string`): Password for encrypting session cookies. Must be at least 32 characters. If not set, an auto-generated value is used in development that does not survive restarts.
**session.secureCookies** (`boolean`): Set the Secure flag on session cookies.
**name** (`string`): Custom name for the auth provider instance. (Default: `'google'`)
### Environment variables
The following environment variables are automatically used when constructor options aren't provided:
**GOOGLE\_CLIENT\_ID** (`string`): Google OAuth client ID from your Google Cloud OAuth client.
**GOOGLE\_CLIENT\_SECRET** (`string`): Google OAuth client secret. Required for the SSO authorization code flow.
**GOOGLE\_REDIRECT\_URI** (`string`): OAuth redirect URI for the SSO callback.
**GOOGLE\_COOKIE\_PASSWORD** (`string`): Password for encrypting session cookies. Must be at least 32 characters.
**GOOGLE\_ALLOWED\_DOMAINS** (`string`): Comma-separated Google Workspace hosted domains to allow.
**GOOGLE\_HOSTED\_DOMAIN** (`string`): Hosted-domain login hint passed to Google during SSO login.
### Authentication flow
`MastraAuthGoogle` authenticates requests in the following order:
1. **Session cookie**: When SSO is enabled, reads the encrypted session cookie and decrypts it. If the session is valid and not expired, the user is authenticated.
2. **Google ID token fallback**: If no valid session cookie is present, verifies the `Authorization` header token against Google's JWKS endpoint.
After authentication, `authorizeUser` checks that the user has a valid Google user ID, the token-derived expiration has not passed, and the user's verified `hd` claim matches `allowedDomains` when domains are configured.
### Authentication methods
#### `authenticateToken(token, request?)`
Authenticates a Google ID token. When SSO is enabled, this method checks the encrypted session cookie before it verifies the Bearer token.
```typescript
const user = await auth.authenticateToken(idToken, request)
```
Returns: `Promise<GoogleUser | null>`
#### `getCurrentUser(request)`
Returns the authenticated user from a session cookie or Bearer Google ID token.
```typescript
const user = await auth.getCurrentUser(request)
```
Returns: `Promise<GoogleUser | null>`
#### `authorizeUser(user)`
Returns `true` when the user has an ID, has not expired, and matches `allowedDomains` when domains are configured.
```typescript
const allowed = auth.authorizeUser(user)
```
Returns: `boolean`
#### `getUser(userId)`
Returns `null`. Google ID tokens are verified directly, so this provider does not perform user lookup by ID.
```typescript
const user = await auth.getUser(userId)
```
Returns: `Promise<GoogleUser | null>`
### `GoogleUser` type
The `GoogleUser` type extends the base `EEUser` interface with Google-specific fields:
**id** (`string`): Mastra user ID. Uses the Google sub claim.
**googleId** (`string`): Google Account subject identifier.
**email** (`string`): User email address.
**name** (`string`): User display name from Google profile claims.
**avatarUrl** (`string`): URL to the user's Google profile picture.
**hostedDomain** (`string`): Google Workspace hosted domain from the verified hd claim.
**expiresAt** (`Date`): Verified ID token expiration time, when available.
**emailVerified** (`boolean`): Whether Google reports the email address as verified.
**groups** (`string[]`): Optional pre-resolved Google Workspace group role IDs.
## MastraRBACGoogle class
The `MastraRBACGoogle` class maps Google Workspace groups to Mastra permissions. It fetches user groups from the Google Admin SDK Directory API and resolves them against a configurable role mapping. Use it with `MastraAuthGoogle` or any other auth provider.
> **Note:** RBAC requires a valid Enterprise Edition license. It works without a license in development so you can try it locally, but you'll need a license for production. [Contact sales](https://mastra.ai/contact) for more information.
### Usage example
Use `MastraRBACGoogle` alongside an auth provider by passing it to the `rbac` option:
```typescript
import { Mastra } from '@mastra/core'
import { MastraAuthGoogle, MastraRBACGoogle } from '@mastra/auth-google'
export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle(),
rbac: new MastraRBACGoogle({
serviceAccount: {
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
},
roleMapping: {
'admins@example.com': ['*'],
'engineering@example.com': ['agents:*', 'workflows:*', 'tools:*'],
'viewers@example.com': ['agents:read', 'workflows:read'],
_default: [],
},
}),
},
})
```
To use Google Workspace RBAC with a different auth provider, pass a `getUserKey` function to resolve the Google Directory API user key from the other provider's user object:
```typescript
import { Mastra } from '@mastra/core'
import { MastraAuthAuth0 } from '@mastra/auth-auth0'
import { MastraRBACGoogle } from '@mastra/auth-google'
export const mastra = new Mastra({
server: {
auth: new MastraAuthAuth0(),
rbac: new MastraRBACGoogle({
getUserKey: user => user.email,
serviceAccount: {
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
},
roleMapping: {
'engineering@example.com': ['agents:*', 'workflows:*'],
'admins@example.com': ['*'],
_default: [],
},
}),
},
})
```
### Constructor parameters
**roleMapping** (`RoleMapping`): Maps Google Workspace group role IDs to arrays of Mastra permission strings. Use '\_default' to assign permissions to users who do not match any group. Supports wildcards like '\*' (full access) and 'agents:\*' (all agent actions).
**accessToken** (`string`): Pre-obtained Workspace Directory API access token.
**getAccessToken** (`() => Promise<string> | string`): Callback that returns a Workspace Directory API access token.
**serviceAccount** (`GoogleWorkspaceServiceAccount`): Service account credentials for domain-wide delegated Directory API access.
**serviceAccount.clientEmail** (`string`): Google service account email.
**serviceAccount.privateKey** (`string`): PEM-encoded private key. Escaped \n values from .env files are supported.
**serviceAccount.privateKeyId** (`string`): Optional private key ID.
**serviceAccount.subject** (`string`): Workspace administrator user to impersonate with domain-wide delegation.
**serviceAccount.scopes** (`string[]`): OAuth scopes for the service account token.
**getUserKey** (`(user: unknown) => string | undefined`): Extract the Directory API userKey from an authenticated user. Defaults to user.email.
**mapGroupToRoles** (`(group: GoogleWorkspaceGroup) => string[]`): Map a Google Workspace group to role IDs. Defaults to \[group.email].
**cache** (`PermissionCacheOptions`): Configure the LRU cache for group lookups.
**cache.maxSize** (`number`): Maximum number of users to cache.
**cache.ttlMs** (`number`): Time-to-live in milliseconds.
### RBAC methods
#### `getRoles(user)`
Returns Google Workspace group role IDs for a user.
```typescript
const roles = await rbac.getRoles(user)
```
Returns: `Promise<string[]>`
#### `getPermissions(user)`
Returns Mastra permissions resolved from Google Workspace groups and `roleMapping`.
```typescript
const permissions = await rbac.getPermissions(user)
```
Returns: `Promise<string[]>`
#### `hasPermission(user, permission)`
Checks whether a user has a permission.
```typescript
const canReadAgents = await rbac.hasPermission(user, 'agents:read')
```
Returns: `Promise<boolean>`
#### `hasRole(user, role)`
Checks whether a user resolved to a specific Google Workspace group role.
```typescript
const isAdmin = await rbac.hasRole(user, 'admins@example.com')
```
Returns: `Promise<boolean>`
#### `hasAllPermissions(user, permissions)`
Checks whether a user has every requested permission.
```typescript
const canManageAgents = await rbac.hasAllPermissions(user, ['agents:read', 'agents:update'])
```
Returns: `Promise<boolean>`
#### `hasAnyPermission(user, permissions)`
Checks whether a user has at least one requested permission.
```typescript
const canReadSomething = await rbac.hasAnyPermission(user, ['agents:read', 'workflows:read'])
```
Returns: `Promise<boolean>`
#### `getAvailableRoles()`
Returns the role IDs configured in `roleMapping`, excluding `_default`.
```typescript
const roles = await rbac.getAvailableRoles()
```
Returns: `Promise<{ id: string; name: string }[]>`
#### `getPermissionsForRole(roleId)`
Returns the permissions configured for a role ID.
```typescript
const permissions = await rbac.getPermissionsForRole('engineering@example.com')
```
Returns: `Promise<string[]>`
#### `clearCache()`
Clears all cached Google Workspace group lookups.
```typescript
rbac.clearCache()
```
Returns: `void`
#### `clearUserCache(userKey)`
Clears the cached group lookup for one Directory API user key, such as an email address.
```typescript
rbac.clearUserCache('user@example.com')
```
Returns: `void`
#### `getCacheStats()`
Returns the current group lookup cache size and maximum size.
```typescript
const stats = rbac.getCacheStats()
```
Returns: `{ size: number; maxSize: number }`
### Additional configuration
`MastraRBACGoogle` uses `GET https://admin.googleapis.com/admin/directory/v1/groups?userKey=...` and handles pagination. Provide a service account with domain-wide delegation for production Google Workspace deployments, or pass `accessToken` / `getAccessToken` if your application already manages Google API tokens.
If `user.groups` is already an array, `MastraRBACGoogle` uses that value and does not call the Directory API. An empty `groups` array means the user has no Google group roles and resolves to `_default` permissions when `_default` is configured.
`MastraRBACGoogle` does not automatically read service-account environment variables. Pass service-account credentials through the `serviceAccount` option, or pass `accessToken` / `getAccessToken`.
## Related
[Google auth docs](https://mastra.ai/docs/server/auth/google)