feat(gmail-single-user): new single-mailbox Gmail integration
Gmail for one mailbox over OAuth 2.0 (no service account / delegation): auth-link + exchange-code to obtain a refresh token, connectivity test, message search/get, send/reply with attachments, attachment retrieval, and get_incidents ingestion with an OCSF mapper. Refresh-token grant, stdlib-only (no extra Python dependencies). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
id: gmail_single_user
|
||||
name: Gmail Single User
|
||||
version: 1.0.0
|
||||
description: "Gmail for a single mailbox over OAuth 2.0 (no service account, no domain-wide delegation) — search/read messages, send and reply (with attachments), retrieve attachments, and ingest messages (get_incidents) with an OCSF mapper. Uses a per-mailbox OAuth refresh token; stdlib-only, no extra Python dependencies."
|
||||
changelog: "1.0.0 — Initial release: OAuth authorization link + code exchange, connectivity test, message ingestion with OCSF mapper, send/reply mail with attachments, and attachment retrieval."
|
||||
category: email
|
||||
|
||||
# Per-instance configuration. This integration authenticates as ONE Gmail user
|
||||
# via OAuth 2.0 (not a service account). One-time setup:
|
||||
# 1. Create an OAuth client (type: Web application) in Google Cloud, authorize
|
||||
# the Gmail scopes, and note the Client ID / Client Secret. Add the redirect
|
||||
# URI below to the client's authorized redirect URIs.
|
||||
# 2. Run gmail-single-user-auth-link, open the URL, consent, and copy the
|
||||
# "code" value from the redirect.
|
||||
# 3. Run gmail-single-user-exchange-code with that code to get a refresh_token.
|
||||
# 4. Paste the refresh_token into the config below and save.
|
||||
# Every command then exchanges the refresh token for a short-lived access token.
|
||||
config_schema:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
description: "The Gmail address of the mailbox (used as the default From address)"
|
||||
client_id:
|
||||
type: string
|
||||
description: "OAuth client ID"
|
||||
client_secret:
|
||||
type: string
|
||||
description: "OAuth client secret"
|
||||
x-soar-sensitive: true
|
||||
refresh_token:
|
||||
type: string
|
||||
description: "OAuth refresh token (obtain it once with gmail-single-user-exchange-code, then paste it here)"
|
||||
x-soar-sensitive: true
|
||||
redirect_uri:
|
||||
type: string
|
||||
description: "OAuth redirect URI registered on the client (must match at auth-link and exchange-code time)"
|
||||
default: http://localhost
|
||||
send_as:
|
||||
type: string
|
||||
description: "Optional address to send from (a verified send-as alias of the mailbox)"
|
||||
required:
|
||||
- email
|
||||
- client_id
|
||||
- client_secret
|
||||
|
||||
commands:
|
||||
- id: auth_link
|
||||
name: gmail-single-user-auth-link
|
||||
description: "Generate the OAuth consent URL. Open it, approve access, and copy the returned code for gmail-single-user-exchange-code."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties: {}
|
||||
required: []
|
||||
outputs_schema: { properties: {} }
|
||||
- id: exchange_code
|
||||
name: gmail-single-user-exchange-code
|
||||
description: "Exchange an OAuth authorization code for a refresh token (paste the refresh_token into the instance config afterwards)."
|
||||
inputs_schema:
|
||||
properties:
|
||||
code: { type: string, description: "Authorization code from the consent redirect" }
|
||||
redirect_uri: { type: string, description: "Override the configured redirect URI (must match the one used for auth-link)" }
|
||||
required: [code]
|
||||
outputs_schema: { properties: {} }
|
||||
- id: get_incidents
|
||||
name: gmail-single-user-get-incidents
|
||||
description: "Fetch messages from the mailbox for ingestion. Returns {result:[...]}; use result as the alert rule results path."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties:
|
||||
query: { type: string, description: "Extra Gmail search query (same syntax as the Gmail search box)" }
|
||||
after: { type: string, description: "Lower bound on message date, epoch (s/ms) or ISO8601 (incremental fetch watermark)" }
|
||||
subject: { type: string, description: "Filter by subject" }
|
||||
from: { type: string, description: "Filter by sender" }
|
||||
to: { type: string, description: "Filter by recipient" }
|
||||
filename: { type: string, description: "Filter by attachment filename or type" }
|
||||
label_id: { type: string, description: "Restrict to a label ID" }
|
||||
has_attachments: { type: boolean, description: "Only messages with attachments" }
|
||||
max: { type: number, description: "Maximum messages to fetch (default 50)" }
|
||||
required: []
|
||||
outputs_schema: { properties: {} }
|
||||
ingest:
|
||||
results_path: result
|
||||
dedup_key: id
|
||||
incremental_field: after
|
||||
- id: search
|
||||
name: gmail-single-user-search
|
||||
description: "Search the mailbox and return flattened messages (subject/from/to/body/attachments)."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties:
|
||||
query: { type: string, description: "Gmail search query" }
|
||||
subject: { type: string, description: "Filter by subject" }
|
||||
from: { type: string, description: "Filter by sender" }
|
||||
to: { type: string, description: "Filter by recipient" }
|
||||
filename: { type: string, description: "Filter by attachment filename or type" }
|
||||
label_id: { type: string, description: "Restrict to a label ID" }
|
||||
has_attachments: { type: boolean, description: "Only messages with attachments" }
|
||||
max_results: { type: number, description: "Maximum messages (default 100, max 500)" }
|
||||
page_token: { type: string, description: "Page token for the next results page" }
|
||||
include_spam_trash: { type: boolean, description: "Include SPAM and TRASH" }
|
||||
required: []
|
||||
outputs_schema: { properties: {} }
|
||||
- id: get_mail
|
||||
name: gmail-single-user-get-mail
|
||||
description: "Retrieve a single message (flattened) by ID."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties:
|
||||
message_id: { type: string, description: "Message ID" }
|
||||
required: [message_id]
|
||||
outputs_schema: { properties: {} }
|
||||
- id: send_mail
|
||||
name: gmail-single-user-send-mail
|
||||
description: "Send an email from the mailbox (optional single attachment as base64)."
|
||||
inputs_schema:
|
||||
properties:
|
||||
to: { type: string, description: "Recipient(s), comma-separated" }
|
||||
subject: { type: string, description: "Subject" }
|
||||
body: { type: string, description: "Plain-text body" }
|
||||
html_body: { type: string, description: "HTML body" }
|
||||
cc: { type: string, description: "CC recipient(s), comma-separated" }
|
||||
bcc: { type: string, description: "BCC recipient(s), comma-separated" }
|
||||
reply_to: { type: string, description: "Reply-To address" }
|
||||
attachment_name: { type: string, description: "Attachment file name (with attachment_base64)" }
|
||||
attachment_base64: { type: string, description: "Attachment content, base64-encoded" }
|
||||
required: [to, subject]
|
||||
outputs_schema: { properties: {} }
|
||||
- id: reply_mail
|
||||
name: gmail-single-user-reply-mail
|
||||
description: "Reply to a message (sets In-Reply-To/References so it threads correctly)."
|
||||
inputs_schema:
|
||||
properties:
|
||||
to: { type: string, description: "Recipient(s), comma-separated" }
|
||||
subject: { type: string, description: "Subject (keep the original for correct threading)" }
|
||||
in_reply_to: { type: string, description: "Message-ID header of the message being replied to" }
|
||||
references: { type: string, description: "References header (space-separated Message-IDs)" }
|
||||
body: { type: string, description: "Plain-text body" }
|
||||
html_body: { type: string, description: "HTML body" }
|
||||
cc: { type: string, description: "CC recipient(s), comma-separated" }
|
||||
bcc: { type: string, description: "BCC recipient(s), comma-separated" }
|
||||
reply_to: { type: string, description: "Reply-To address" }
|
||||
attachment_name: { type: string, description: "Attachment file name (with attachment_base64)" }
|
||||
attachment_base64: { type: string, description: "Attachment content, base64-encoded" }
|
||||
required: [to, subject, in_reply_to]
|
||||
outputs_schema: { properties: {} }
|
||||
- id: get_attachments
|
||||
name: gmail-single-user-get-attachments
|
||||
description: "Retrieve a message's attachments as base64."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties:
|
||||
message_id: { type: string, description: "Message ID" }
|
||||
required: [message_id]
|
||||
outputs_schema: { properties: {} }
|
||||
|
||||
- id: test_connection
|
||||
name: gmail-single-user-test-connection
|
||||
description: "Verify the OAuth refresh token by reading the mailbox profile (used by the Test button)."
|
||||
risk: read
|
||||
inputs_schema:
|
||||
properties: {}
|
||||
required: []
|
||||
outputs_schema: { properties: {} }
|
||||
|
||||
ingestion:
|
||||
command: get_incidents
|
||||
mapper: get_incidents
|
||||
default_incident_type: "Gmail Single User Message"
|
||||
Reference in New Issue
Block a user