From gamma-pack
Implement security best practices for Gamma integration. Use when securing API keys, implementing access controls, or auditing Gamma security configuration. Trigger with phrases like "gamma security", "gamma API key security", "gamma secure", "gamma credentials", "gamma access control".
npx claudepluginhub flight505/skill-forge --plugin gamma-packThis skill is limited to using the following tools:
Security best practices for Gamma API integration to protect credentials and data.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Security best practices for Gamma API integration to protect credentials and data.
// NEVER do this
const gamma = new GammaClient({
apiKey: 'gamma_live_abc123...', // Hardcoded - BAD!
});
// DO this instead
const gamma = new GammaClient({
apiKey: process.env.GAMMA_API_KEY,
});
Environment Setup:
# .env (add to .gitignore!)
GAMMA_API_KEY=gamma_live_abc123...
# Load in application
import 'dotenv/config';
// Support multiple keys for rotation
const gamma = new GammaClient({
apiKey: process.env.GAMMA_API_KEY_PRIMARY
|| process.env.GAMMA_API_KEY_SECONDARY,
});
// Rotation script
async function rotateApiKey() {
// 1. Generate new key in Gamma dashboard
// 2. Update GAMMA_API_KEY_SECONDARY
// 3. Deploy and verify
// 4. Swap PRIMARY and SECONDARY
// 5. Revoke old key
}
import crypto from 'crypto';
function signRequest(payload: object, secret: string): string {
const timestamp = Date.now().toString();
const message = timestamp + JSON.stringify(payload);
return crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
}
// Usage with webhook verification
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Scoped API keys (if supported)
const readOnlyGamma = new GammaClient({
apiKey: process.env.GAMMA_API_KEY_READONLY,
scopes: ['presentations:read', 'exports:read'],
});
const fullAccessGamma = new GammaClient({
apiKey: process.env.GAMMA_API_KEY_FULL,
});
// Permission check before operations
async function createPresentation(user: User, data: object) {
if (!user.permissions.includes('gamma:create')) {
throw new Error('Insufficient permissions');
}
return fullAccessGamma.presentations.create(data);
}
import { GammaClient } from '@gamma/sdk';
function createAuditedClient(userId: string) {
return new GammaClient({
apiKey: process.env.GAMMA_API_KEY,
interceptors: {
request: (config) => {
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
userId,
action: `${config.method} ${config.path}`,
type: 'gamma_api_request',
}));
return config;
},
},
});
}
| Security Issue | Detection | Remediation |
|---|---|---|
| Exposed key | GitHub scanning | Rotate immediately |
| Key in logs | Log audit | Filter sensitive data |
| Unauthorized access | Audit logs | Revoke and investigate |
| Weak permissions | Access review | Apply least privilege |
Proceed to gamma-prod-checklist for production readiness.