mastra-ai/mastra · error
Google Workspace Directory authentication is not configured.
Error message
Google Workspace Directory authentication is not configured.
What it means
Thrown by MastraRBACGoogle.getToken when no authentication source is available: no getAccessToken callback, no serviceAccount, and no (remaining) accessToken. The provider needs a bearer token for the Google Workspace Directory API to fetch the user's groups, and none is configured.
Source
Thrown at auth/google/src/rbac-provider.ts:196
if (this.accessToken && Date.now() < this.tokenExpiresAt - 60_000) {
return this.accessToken;
}
if (this.options.serviceAccount) {
if (!this.tokenRefreshPromise) {
this.tokenRefreshPromise = this.getServiceAccountToken().finally(() => {
this.tokenRefreshPromise = undefined;
});
}
return this.tokenRefreshPromise;
}
if (this.accessToken) {
return this.accessToken;
}
throw new Error('Google Workspace Directory authentication is not configured.');
}
private async getServiceAccountToken(): Promise<string> {
const account = this.options.serviceAccount!;
const now = Math.floor(Date.now() / 1000);
const header = { alg: 'RS256', typ: 'JWT', ...(account.privateKeyId ? { kid: account.privateKeyId } : {}) };
const claim = {
iss: account.clientEmail,
scope: (account.scopes ?? DEFAULT_DIRECTORY_SCOPES).join(' '),
aud: OAUTH_TOKEN_URL,
exp: now + 3600,
iat: now,
...(account.subject ? { sub: account.subject } : {}),
};
const unsigned = `${this.base64Url(JSON.stringify(header))}.${this.base64Url(JSON.stringify(claim))}`;
const privateKey = this.normalizePrivateKey(account.privateKey);
let signature: string;View on GitHub (pinned to 75dd419e61)
Solutions
- Configure authentication: pass a serviceAccount ({ clientEmail, privateKey, subject }) for server-side deployments — the recommended long-lived option.
- Alternatively supply a getAccessToken callback that returns a valid Directory-API bearer token.
- Or pass a static accessToken, understanding it will only work until expiry (and 401s surface as error 63 after this).
- Verify env vars (service account key, client email) are actually loaded where the provider is constructed.
- Validate options at startup so missing credentials fail fast rather than on first getRoles call.
Example fix
// before
const rbac = new MastraRBACGoogle({ roleMapping: mapping });
// after
const rbac = new MastraRBACGoogle({
serviceAccount: {
clientEmail: process.env.GOOGLE_SA_CLIENT_EMAIL!,
privateKey: process.env.GOOGLE_SA_PRIVATE_KEY!.replace(/\\n/g, '\n'),
subject: 'admin@mycompany.com',
},
roleMapping: mapping,
}); Defensive patterns
Strategy: validation
Validate before calling
function assertRbacAuthConfigured(opts: {
getAccessToken?: () => Promise<string>;
serviceAccount?: unknown;
accessToken?: string;
}): void {
if (!opts.getAccessToken && !opts.serviceAccount && !opts.accessToken) {
throw new Error('MastraRBACGoogle needs one of: getAccessToken, serviceAccount, or accessToken');
}
}
// call before constructing the provider Type guard
interface RbacAuthOptions {
getAccessToken?: () => Promise<string>;
serviceAccount?: { clientEmail: string; privateKey: string; subject?: string };
accessToken?: string;
}
function hasDirectoryAuth(o: RbacAuthOptions): boolean {
return Boolean(o.getAccessToken || o.serviceAccount || o.accessToken);
} Try / catch
try {
const roles = await rbac.getRoles(user);
} catch (err) {
if (err instanceof Error && err.message === 'Google Workspace Directory authentication is not configured.') {
// config bug, not transient: log loudly and fall back to default permissions
logger.error('RBAC provider missing Directory credentials');
return roleMapping['_default'] ?? [];
}
throw err;
} Prevention
- Prefer serviceAccount credentials — they self-refresh and outlive static access tokens
- If using a static accessToken, remember it expires; pair it with a getAccessToken callback for production
- Verify service-account env vars are loaded in the deployment before startup
- Construct the provider eagerly at boot so missing credentials fail fast
- Do not assume SSO provider tokens are shared with the RBAC provider — configure auth separately
When it happens
Trigger: getRoles/getPermissions called on a MastraRBACGoogle instance constructed without any of: options.getAccessToken, options.serviceAccount, options.accessToken — or with an accessToken that was consumed/expired and no refresh path (tokenExpiresAt passed, accessToken stale).
Common situations: Instantiating the RBAC provider with only roleMapping and forgetting credentials; assuming the SSO provider's tokens are shared with the RBAC provider (they are not); passing an expired accessToken with no serviceAccount fallback; env vars for the service account not loaded in the deployment.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Google RBAC roleMapping is required.
- Google client ID is required. Provide it in the options or s
- Redirect URI is required for Google SSO. Set GOOGLE_REDIRECT
- Google Directory groups.list failed (${response.status}): ${
- Google service account private key signing failed (${(err as
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1ceabf2464b04ec4.
Report an issue: GitHub.