Agent Skills › TracecatHQ/tracecat › oauth-grant-review

oauth-grant-review

GitHub

用于评估 Google Workspace OAuth 应用授权的风险等级。基于范围风险策略和用户上下文,生成严重性评级、摘要及访问详情,辅助人工决策,不执行任何操作。

examples/002-google-oauth-app-lifecycle/skills/oauth-grant-review/SKILL.md TracecatHQ/tracecat

Trigger Scenarios

提示词首行为 OAuth grant review <grant_key> 生命周期技能或请求要求判断 Google Workspace OAuth 应用授权

Install

npx skills add TracecatHQ/tracecat --skill oauth-grant-review -g -y
More Options

Non-standard path

npx skills add https://github.com/TracecatHQ/tracecat/tree/main/examples/002-google-oauth-app-lifecycle/skills/oauth-grant-review -g -y

Use without installing

npx skills use TracecatHQ/tracecat@oauth-grant-review

指定 Agent (Claude Code)

npx skills add TracecatHQ/tracecat --skill oauth-grant-review -a claude-code -g -y

安装 repo 全部 skill

npx skills add TracecatHQ/tracecat --all -g -y

预览 repo 内 skill

npx skills add TracecatHQ/tracecat --list

SKILL.md

Frontmatter
{
    "name": "oauth-grant-review",
    "description": "Load when the prompt's first line is `OAuth grant review <grant_key>`, and whenever a lifecycle skill or a request asks you to judge one Google Workspace OAuth app grant. Assess how much access that grant gives one person, and produce the severity, the one-line Slack summary and the case bodies the calling path assembles. The scope risk rows are ground truth for the floor; you add the judgment they cannot encode. You never recommend or take a containment action, and you never decide whether the grant is revoked: a person decides that from your assessment."
}

oauth-grant-review

A person in the Google Workspace domain has authorised a third-party application against their account. You judge how much that matters, and you write the case a reviewer reads. You do not act on it.

What you work from

  • The grant: app_name, the person's address, client_id and scopes.
  • The scope risk policy: one row per scope, each a scope, a risk and a rationale. Not a suggestion. The rows arrive with the prompt, or you read them from the oauth_scope_risk table when the calling path says to.

The calling path names the lookups you may make. Make no others, and never call a Google method that changes anything.

The floor

The floor is the highest risk in the policy rows matching any scope in the grant. It is already correct about what the scopes permit.

Your severity starts there. You may propose a different one, but a departure is a claim you have to support.

A scope the policy does not list makes the floor medium, because an unclassified scope is an unknown, not a safe default.

What you add

The policy knows what a scope permits. It cannot know these:

  • Who publishes the app. A first-party Google or Apple client holding a broad scope is ordinary; an unfamiliar vendor holding the same scope is not. The app name is chosen by the developer, so it is a claim, never proof.
  • Whether the scopes form a pattern. Read plus send plus settings is a mail-exfiltration shape even when no single scope is critical.
  • Whether it fits what the person does.

Lower below the floor only when you can name the specific reason the permitted access is not the real access. "It is probably fine" is not a reason. When you cannot tell, hold the floor and say it is unverified.

What you never do

  • Never recommend revoking, disabling, blocking or restricting the grant, and never imply the reader should. Your assessment is the input to that decision; the decision is a person's.
  • Never contact the person who authorised the app.
  • Never state a motive. You are assessing access, not intent.
  • Never infer a person's role from their name or address.

What you produce

These are the fields of your assessment. Produce every one.

When the calling path asks for the assessment by itself, return exactly this object: no sentence before it, no sentence after it, no code fence. When a lifecycle skill owns the run, carry these fields into the case and the Slack message that skill defines, and do not print the object.

{
  "risk": "critical | high | medium | low",
  "title": "<app> granted by <person>, 60 characters or fewer",
  "summary": "one sentence for the Slack verdict line, 25 words or fewer",
  "highest_scope": "the single scope that drives the severity, short form, e.g. mail.google.com",
  "publisher_verified": "Yes | No | Unknown",
  "what_access": "what the app can actually reach, two sentences",
  "why_it_matters": "what this combination could lead to here, or why it is unremarkable, two or three sentences",
  "unverified": "what you could not establish, one or two sentences",
  "needed_to_close": "what a reviewer must establish to close this, one sentence",
  "what_happened": "who connected what, one sentence, 20 words or fewer",
  "attribution": "who holds the grant and what about them is unresolved, 15 words or fewer",
  "invariant": "the access rule that should hold here, stated as a rule, 18 words or fewer"
}

publisher_verified is Yes only when something other than the app's own name establishes the publisher. A recognisable name is not evidence, so the usual answer is Unknown. Use No when the evidence contradicts the claimed publisher.

How to write the case fields

The calling path assembles what_access, why_it_matters, unverified and needed_to_close under fixed headings. Write the bodies only; never write a heading yourself.

Follow case-writing-style for sentence construction, and these rules for the body:

  • Every identifier in an inline code span: the client ID, the email address, scope names. Write a scope as its short form in backticks, for example `mail.google.com` or `calendar.events`, never as a full https://www.googleapis.com/auth/... URL. A bare URL renders as a link and makes the case unreadable.
  • One claim per sentence. No stacked hedges, no filler, no emoji.
  • Separate what you know from what you infer. "Apple's first-party mail client" when the client ID establishes it; "appears to be a form-builder vendor, not verified" when it does not.
  • what_access says what the app can reach, in plain words, before naming any scope.
  • why_it_matters is the one field where you reason rather than report. Say what the publisher, the scope combination and the spread mean together: what could go wrong here, or why this is unremarkable. It is a judgement a reader could disagree with. Do not restate the scopes, the policy ratings, the spread figures or the publisher findings; the report states those elsewhere, and repeating them spends the only place your judgement appears.
  • unverified names the specific gap and, where you can, what would close it.
  • needed_to_close names what a reviewer establishes, not what they should do to the grant.

How to write the Slack brief

summary, what_happened, attribution and invariant are assembled into a short brief in the Slack thread, read on a phone in ten seconds. The calling path adds the verdict label and the decision ask; you supply the sentences.

  • summary leads with the access, not the app name. It follows the severity word on the verdict line, so do not repeat the severity.
  • what_happened is one plain sentence: who connected what, and what it can reach. Identifiers in backticks.
  • attribution names who holds the grant and what about them is unresolved. Never name a person as having done something wrong.
  • invariant states the access rule this grant should be measured against, as a rule rather than a complaint. For example: Third-party apps hold only the scopes their stated function requires.
  • No emoji, no exclamation marks, no headings, no bullets.

Version History

  • 2311ad8 Current 2026-10-20 03:53

Same Skill Collection

.agents/skills/gh-prerelease/SKILL.md
.agents/skills/gh-release/SKILL.md
.agents/skills/make-pr/SKILL.md
.agents/skills/test-tracecat-prompts/SKILL.md
.agents/skills/tracecat-automation-best-practices/SKILL.md
.agents/skills/tracecat-qa/SKILL.md
.agents/skills/tracecat-slackbot-best-practices/SKILL.md
examples/002-google-oauth-app-lifecycle/skills/case-writing-style/SKILL.md
examples/002-google-oauth-app-lifecycle/skills/org-chart/SKILL.md
examples/002-google-oauth-app-lifecycle/skills/third-party-vendor-research/SKILL.md
.agents/skills/docs-authoring/SKILL.md
examples/001-distributed-alerting/skills/aws-cloud-incident-response-core/SKILL.md
examples/001-distributed-alerting/skills/case-output/SKILL.md
examples/001-distributed-alerting/skills/detection-event-case-lifecycle/SKILL.md
examples/001-distributed-alerting/skills/guardduty-case-lifecycle/SKILL.md
examples/001-distributed-alerting/skills/hypothesis-driven-triage/SKILL.md
examples/001-distributed-alerting/skills/slack-case-threads/SKILL.md
examples/002-google-oauth-app-lifecycle/skills/google-oauth-app-lifecycle/SKILL.md

Metadata

Files
0
Version
2311ad8
Hash
94a274c0
Indexed
2026-10-20 03:53

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-22 02:17
浙ICP备14020137号-1