Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes a gRPC service or interceptor, a GraphQL resolver or subscription, a protobuf/Thrift schema, a queue or pub/sub producer or consumer, an event handler or an inbound webhook - peer identity vs claimed principal, interceptor gaps, per-item and stream authorization, webhook signatures, untrusted producers, enum defaults, replay, duplicate delivery and ordering
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Behind the HTTP edge, services talk through RPC calls, queues and callbacks, and two beliefs keep failing there: "it is internal, so it is authenticated" and "it passed the schema, so it is safe". A schema proves a message's shape — not who sent it, which tenant it may touch, whether it was already processed, or whether it is still current.
Core principle: at every hop, name the authenticated peer and show how it becomes the principal the handler authorizes. A field inside the message that names a user or tenant is a claim, not an identity.
// ❌ only unary calls are authenticated; every streaming method is open
srv := grpc.NewServer(grpc.UnaryInterceptor(authUnary))
// ✅ both kinds, and the skip list is exact method names, not prefixes
srv := grpc.NewServer(
grpc.ChainUnaryInterceptor(authUnary),
grpc.ChainStreamInterceptor(authStream),
)
Also: a skip list matched with strings.HasPrefix(info.FullMethod, "/pkg.Health") that also matches /pkg.HealthAdmin/…; server reflection registered on a public listener next to unauthenticated methods; grpc-gateway or Connect transcoding that reaches the same handler through an HTTP route the interceptor does not see; identity read from metadata such as x-user-id that any client can send.
A stream, subscription or batch is authorized once, then later items name different resources:
repeated string ids checks ids[0];"org." + msg.org).Re-check where the scope can change, and bind a subscription to the principal and resources it started with.
Query but not to Mutation or Subscription.id lookups (node(id:)) that resolve any type by global id without the type's own check.// ❌ JSON re-serialized before verifying; tenant chosen by the body, then its secret used
const evt = JSON.parse(req.body);
const secret = await secrets.forAccount(evt.account_id);
if (sign(JSON.stringify(evt), secret) !== req.header("X-Signature")) return res.sendStatus(401);
// ✅ verify the raw bytes with the secret bound to the endpoint, then parse
const secret = await secrets.forEndpoint(req.params.endpointId);
if (!timingSafeEqualHex(hmac(req.rawBody, secret), req.header("X-Signature"))) return res.sendStatus(401);
const evt = JSON.parse(req.rawBody);
if (evt.account_id !== endpoint.accountId) return res.sendStatus(403);
type: "admin.grant" — while any lower-trust service, a user-facing API or a public webhook relay can publish to that topic.#, *, >) let one tenant subscribe to all.// ❌ proto3 sends 0 when the field is unset — an old or careless client becomes an owner
enum Role { OWNER = 0; EDITOR = 1; VIEWER = 2; }
// ✅ zero is the meaningless, least-privileged value
enum Role { ROLE_UNSPECIFIED = 0; VIEWER = 1; EDITOR = 2; OWNER = 3; }
Also: a switch on a message type whose default branch performs the privileged handling; unknown fields kept and forwarded to a consumer that trusts them; a new field that old consumers ignore while it was meant to restrict them (readonly: true added to the producer only).
An unauthenticated RPC, stream or webhook that changes state → CRITICAL. A forged or cross-tenant event accepted by a privileged consumer → HIGH to CRITICAL. A non-idempotent duplicate with money or privilege impact → HIGH. Replay of a low-impact notification → MEDIUM at most.
grpc.UnaryInterceptor with no stream interceptor; HasPrefix on FullMethod.user_id, tenant_id, org or role read from RPC metadata or a message body and used for authorization.gRPC authentication guide · OWASP GraphQL Cheat Sheet · OWASP API Security Top 10 2023 · CWE-294, 306, 345, 347, 862 · Cloudflare security-audit-skill
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。