Skip to main content 用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-graphql --skill graphql-security命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。

pluginagentmarketplace
pluginagentmarketplace/custom-plugin-graphql
打开 GitHub 仓库| name | graphql-security |
| description | Secure GraphQL APIs - authentication, authorization, rate limiting, and validation |
| sasmp_version | 1.3.0 |
| bonded_agent | 06-graphql-security |
| bond_type | PRIMARY_BOND |
| version | 2.0.0 |
| complexity | advanced |
| estimated_time | 5-7 hours |
| prerequisites | ["graphql-fundamentals","graphql-resolvers","graphql-apollo-server"] |
GraphQL Security Skill
Protect your GraphQL APIs from attacks
Overview
Learn essential security patterns for GraphQL: JWT authentication, role-based authorization, rate limiting, query complexity limits, and input validation.
Security Checklist
| Check | Priority | Implementation |
|---|
| Authentication | Critical | JWT with refresh tokens |
| Authorization | Critical | Field-level with graphql-shield |
| Rate Limiting | Critical | Per-user/IP with Redis |
| Query Depth | High | graphql-depth-limit |
| Query Complexity | High | graphql-query-complexity |
| Introspection | High | Disable in production |
| Input Validation | High | Validate all inputs |
| Error Masking | Medium | Hide internal errors |
Core Patterns
1. JWT Authentication
import jwt from 'jsonwebtoken';
function createTokens(user) {
const accessToken = jwt.sign(
{ userId: user.id, roles: user.roles },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId: user.id },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: }
);
{ accessToken, refreshToken };
}
= () => {
token = req..?.(, );
user = ;
(token) {
{
payload = jwt.(token, process..);
user = db..(payload.);
} (e) {
}
}
{ user };
};
resolvers = {
: {
: (_, { email, password }) => {
user = db..(email);
(!user || ! bcrypt.(password, user.)) {
(, {
: { : }
});
}
{ ...(user), user };
},
},
};
'7d'
return
const
context
async
{ req }
const
headers
authorization
replace
'Bearer '
''
let
null
if
try
const
verify
env
JWT_SECRET
await
users
findById
userId
catch
return
const
Mutation
login
async
const
await
users
findByEmail
if
await
compare
passwordHash
throw
new
GraphQLError
'Invalid credentials'
extensions
code
'UNAUTHORIZED'
return
createTokens
2. Authorization with graphql-shield
import { rule, shield, and, or } from 'graphql-shield';
const isAuthenticated = rule()((_, __, { user }) => user !== null);
const isAdmin = rule()((_, __, { user }) =>
user?.roles?.includes('ADMIN')
);
const isOwner = rule()(async (_, { id }, { user, dataSources }) => {
const resource = await dataSources.findById(id);
return resource?.userId === user?.id;
});
const permissions = shield({
Query: {
me: isAuthenticated,
users: and(isAuthenticated, isAdmin),
user: and(isAuthenticated, or(isOwner, isAdmin)),
},
Mutation: {
updateUser: and(isAuthenticated, or(isOwner, isAdmin)),
deleteUser: and(isAuthenticated, isAdmin),
},
User: {
email: or(isOwner, isAdmin),
privateField: isOwner,
},
}, {
fallbackError: new GraphQLError('Not authorized'),
});
import { applyMiddleware } from 'graphql-middleware';
const protectedSchema = applyMiddleware(schema, permissions);
3. Rate Limiting
import rateLimit from 'express-rate-limit';
app.use('/graphql', rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
keyGenerator: (req) => req.user?.id || req.ip,
}));
const typeDefs = gql`
directive @rateLimit(max: Int!, window: String!) on FIELD_DEFINITION
type Mutation {
login(email: String!, password: String!): AuthPayload!
@rateLimit(max: 5, window: "15m")
sendEmail(input: SendEmailInput!): Boolean!
@rateLimit(max: 10, window: "1h")
}
`;
4. Query Limits
import depthLimit from 'graphql-depth-limit';
import { createComplexityLimitRule } from 'graphql-validation-complexity';
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(10),
createComplexityLimitRule(1000, {
scalarCost: 1,
objectCost: 2,
listFactor: 10,
}),
],
introspection: process.env.NODE_ENV !== 'production',
});
5. Input Validation
import validator from 'validator';
import xss from 'xss';
const validate = {
email: (v) => {
if (!validator.isEmail(v)) throw new Error('Invalid email');
return validator.normalizeEmail(v);
},
password: (v) => {
if (v.length < 8) throw new Error('Password too short');
if (!/[A-Z]/.test(v)) throw new Error('Need uppercase');
if (!/[0-9]/.test(v)) throw new Error('Need number');
return v;
},
html: (v) => xss(v),
};
const resolvers = {
Mutation: {
createUser: async (_, { input }) => {
const clean = {
email: validate.email(input.email),
password: validate.password(input.password),
bio: input.bio ? validate.html(input.bio) : null,
};
return db.users.create(clean);
},
},
};
6. Error Masking
const server = new ApolloServer({
formatError: (error) => {
console.error(error);
if (process.env.NODE_ENV === 'production') {
if (error.extensions?.code === 'INTERNAL_SERVER_ERROR') {
return { message: 'Internal error', extensions: { code: 'INTERNAL_ERROR' } };
}
}
return error;
},
});
Security Headers
import helmet from 'helmet';
import cors from 'cors';
app.use(helmet());
app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(','),
credentials: true,
}));
app.use(express.json({ limit: '100kb' }));
Troubleshooting
| Issue | Cause | Solution |
|---|
| Token always invalid | Clock skew | Add grace period |
| Rate limit bypass | Wrong key | Use user ID when authenticated |
| Auth not working | Context async | Await context setup |
| Introspection exposed | Wrong env check | Verify NODE_ENV |
Security Testing
curl -X POST $API \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { types { name } } }"}'
for i in {1..20}; do
curl -X POST $API \
-d '{"query":"mutation { login(email:\"x\",password:\"y\") { token } }"}'
done
curl -X POST $API \
-d '{"query":"{ user { posts { author { posts { author { id } } } } } }"}'
Usage
Skill("graphql-security")
Related Skills
graphql-apollo-server - Server configuration
graphql-resolvers - Auth in resolvers
graphql-schema-design - Auth-aware schema
Related Agent
06-graphql-security - For detailed guidance