feat(gmail): new Gmail integration

Gmail API + Directory API (27 commands): mailbox search/read/send/
trash/label/move, attachments retrieval, vacation auto-reply, filters,
forwarding addresses, delegates, and Workspace user administration;
message ingestion (get_incidents) with a bundled OCSF mapper.
Service-account auth with domain-wide delegation (JWT RS256), runs on
a remote engine (requires PyJWT + cryptography).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Guillaume BOURGEOIS
2026-07-10 23:18:07 +02:00
parent 3f754d14e9
commit 27615636e3
30 changed files with 2974 additions and 0 deletions
+339
View File
@@ -0,0 +1,339 @@
id: gmail
name: Gmail
version: 1.0.0
description: "Gmail API + Directory API — mailbox search/read/send/trash/labels, attachments retrieval, vacation auto-reply, filters, forwarding addresses, delegates, and Workspace user administration; message ingestion (get_incidents) with an OCSF mapper; service-account auth with domain-wide delegation. Runs on a remote engine. Requires the Python 'PyJWT' and 'cryptography' libraries on the engine host (pip install pyjwt cryptography)."
changelog: "1.0.0 — Initial release: mailbox commands (search, get mail/thread, send with attachments, trash/permanent delete, label moves, attachments download, labels list), vacation auto-reply get/set, mail filters (add/list/remove), forwarding addresses and auto-forwarding, delegates, Workspace user administration (list/get/create/delete, password reset, directory visibility), and message ingestion with a bundled OCSF mapper."
category: email
# Authentication: Google service account with domain-wide delegation.
# Every command builds a JWT (RS256, signed locally with the service account
# private key from service_account_json), sets `sub` to the mailbox being
# impersonated, exchanges it at https://oauth2.googleapis.com/token
# (grant_type=jwt-bearer) for an access token, then calls the Gmail /
# Admin SDK Directory REST APIs with that bearer token.
# The service account's client ID must be granted the Gmail scopes (and the
# Directory scopes for user-administration commands) in the Google Workspace
# Admin console: Security → API controls → Domain-wide delegation.
config_schema:
properties:
service_account_json:
type: string
description: "Google service account key file content (full JSON) — the account must have domain-wide delegation enabled"
x-soar-sensitive: true
user_id:
type: string
description: "Default mailbox to impersonate — also the admin account for user-administration commands"
required:
- service_account_json
- user_id
commands:
# ── Ingestion ─────────────────────────────────────────────────────────────
- id: get_incidents
name: gmail-get-incidents
description: "Fetch messages from a mailbox for ingestion (Gmail search query + time watermark). Returns {result:[flattened messages]}; use result as the alert rule results path."
risk: read
inputs_schema:
properties:
query: { type: string, description: "Gmail search query (e.g. is:unread in:inbox has:attachment)" }
after: { type: string, description: "Lower time bound — epoch seconds, epoch ms or ISO8601 (incremental fetch watermark, appended as after:<epoch>)" }
max: { type: number, description: "Maximum messages to fetch (default 50)" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
ingest:
results_path: result
dedup_key: id
incremental_field: after
# ── Mailbox ───────────────────────────────────────────────────────────────
- id: search
name: gmail-search
description: "Search messages with a Gmail query and return them flattened (headers, bodies, attachment metadata) plus a next_page_token for pagination."
risk: read
inputs_schema:
properties:
query: { type: string, description: "Gmail search query (e.g. from:alice@example.com subject:invoice newer_than:7d)" }
max_results: { type: number, description: "Maximum messages to return (default 100, capped at 500)" }
page_token: { type: string, description: "Page token from a previous call (next_page_token)" }
label_id: { type: string, description: "Restrict to a single label ID (e.g. INBOX, SPAM or a user label ID from gmail-list-labels)" }
include_spam_trash: { type: boolean, description: "Include messages from SPAM and TRASH" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
- id: get_mail
name: gmail-get-mail
description: "Retrieve a single message by ID, flattened (subject/from/to/cc, text and HTML bodies, attachment metadata)."
risk: read
inputs_schema:
properties:
message_id: { type: string, description: "Gmail message ID" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [message_id]
outputs_schema: { properties: {} }
- id: get_thread
name: gmail-get-thread
description: "Retrieve a conversation thread by ID with every message flattened."
risk: read
inputs_schema:
properties:
thread_id: { type: string, description: "Gmail thread ID" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [thread_id]
outputs_schema: { properties: {} }
- id: send_mail
name: gmail-send-mail
description: "Send an email from the impersonated mailbox — plain text and/or HTML body, optional single attachment (base64), reply threading via In-Reply-To/References."
inputs_schema:
properties:
to: { type: string, description: "Recipients, comma-separated" }
cc: { type: string, description: "Cc recipients, comma-separated" }
bcc: { type: string, description: "Bcc recipients, comma-separated" }
subject: { type: string, description: "Message subject" }
body: { type: string, description: "Plain-text body" }
html_body: { type: string, description: "HTML body (sent alongside the plain-text part when both are given)" }
reply_to: { type: string, description: "Reply-To header" }
in_reply_to: { type: string, description: "In-Reply-To header (Message-ID of the message being answered — see message_id_header)" }
references: { type: string, description: "References header (thread Message-ID chain)" }
attachment_name: { type: string, description: "Attachment file name (with attachment_base64)" }
attachment_base64: { type: string, description: "Attachment content, base64-encoded" }
user_id: { type: string, description: "Sender mailbox to impersonate (default from instance config)" }
required: [to, subject]
outputs_schema: { properties: {} }
- id: delete_mail
name: gmail-delete-mail
description: "Move a message to Trash, or delete it permanently (bypasses Trash) when permanent is true."
inputs_schema:
properties:
message_id: { type: string, description: "Gmail message ID" }
permanent: { type: boolean, description: "Permanently delete instead of moving to Trash (irreversible)" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [message_id]
outputs_schema: { properties: {} }
- id: move_mail
name: gmail-move-mail
description: "Add and/or remove labels on a message (move between folders — e.g. remove INBOX, add SPAM or a quarantine label)."
inputs_schema:
properties:
message_id: { type: string, description: "Gmail message ID" }
add_labels: { type: string, description: "Label IDs to add, comma-separated" }
remove_labels: { type: string, description: "Label IDs to remove, comma-separated" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [message_id]
outputs_schema: { properties: {} }
- id: get_attachments
name: gmail-get-attachments
description: "Download every attachment of a message; returns name, MIME type, size and base64 content for each."
risk: read
inputs_schema:
properties:
message_id: { type: string, description: "Gmail message ID" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [message_id]
outputs_schema: { properties: {} }
- id: list_labels
name: gmail-list-labels
description: "List the mailbox's labels (system and user labels with their IDs)."
risk: read
inputs_schema:
properties:
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
# ── Auto-reply (vacation responder) ───────────────────────────────────────
- id: autoreply_get
name: gmail-autoreply-get
description: "Get the mailbox's vacation auto-reply settings."
risk: read
inputs_schema:
properties:
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
- id: autoreply_set
name: gmail-autoreply-set
description: "Enable, update or disable the mailbox's vacation auto-reply."
inputs_schema:
properties:
enable: { type: boolean, description: "Enable the auto-reply (default true; false disables it)" }
response_subject: { type: string, description: "Auto-reply subject" }
response_body: { type: string, description: "Auto-reply plain-text body" }
response_body_html: { type: string, description: "Auto-reply HTML body" }
contacts_only: { type: boolean, description: "Only reply to senders in the user's contacts" }
domain_only: { type: boolean, description: "Only reply to senders in the same domain" }
start_time: { type: string, description: "Start time — epoch ms or ISO8601" }
end_time: { type: string, description: "End time — epoch ms or ISO8601" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
# ── Filters ───────────────────────────────────────────────────────────────
- id: add_filter
name: gmail-add-filter
description: "Create a mail filter on the mailbox (criteria: from/to/subject/query/has_attachment; actions: add/remove labels, forward)."
inputs_schema:
properties:
from: { type: string, description: "Criteria — sender address" }
to: { type: string, description: "Criteria — recipient address" }
subject: { type: string, description: "Criteria — subject contains" }
query: { type: string, description: "Criteria — Gmail search query" }
has_attachment: { type: boolean, description: "Criteria — only messages with attachments" }
add_labels: { type: string, description: "Action — label IDs to add, comma-separated" }
remove_labels: { type: string, description: "Action — label IDs to remove, comma-separated (e.g. INBOX to archive)" }
forward: { type: string, description: "Action — forward to this address (must be a verified forwarding address)" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
- id: list_filters
name: gmail-list-filters
description: "List the mailbox's mail filters."
risk: read
inputs_schema:
properties:
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
- id: remove_filter
name: gmail-remove-filter
description: "Delete a mail filter by ID."
inputs_schema:
properties:
filter_id: { type: string, description: "Filter ID (from gmail-list-filters)" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [filter_id]
outputs_schema: { properties: {} }
# ── Forwarding ────────────────────────────────────────────────────────────
- id: forwarding_add
name: gmail-forwarding-add
description: "Register a forwarding address on the mailbox (Google may require verification before it becomes usable)."
inputs_schema:
properties:
forwarding_email: { type: string, description: "Forwarding address to register" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [forwarding_email]
outputs_schema: { properties: {} }
- id: forwarding_list
name: gmail-forwarding-list
description: "List the mailbox's registered forwarding addresses and their verification status."
risk: read
inputs_schema:
properties:
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: []
outputs_schema: { properties: {} }
- id: forwarding_remove
name: gmail-forwarding-remove
description: "Delete a forwarding address from the mailbox."
inputs_schema:
properties:
forwarding_email: { type: string, description: "Forwarding address to remove" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [forwarding_email]
outputs_schema: { properties: {} }
- id: forwarding_update
name: gmail-forwarding-update
description: "Enable auto-forwarding of the mailbox to a verified forwarding address, with a disposition for the forwarded copy."
inputs_schema:
properties:
forwarding_email: { type: string, description: "Verified forwarding address to auto-forward to" }
disposition: { type: string, description: "What happens to the forwarded message in the mailbox: leaveInInbox, archive, trash or markRead" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [forwarding_email]
outputs_schema: { properties: {} }
# ── Delegates ─────────────────────────────────────────────────────────────
- id: delegate_add
name: gmail-delegate-add
description: "Grant a delegate access to the mailbox (delegate can read, send and delete on the owner's behalf)."
inputs_schema:
properties:
delegate_email: { type: string, description: "Delegate's email address (same Workspace domain)" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [delegate_email]
outputs_schema: { properties: {} }
- id: delegate_remove
name: gmail-delegate-remove
description: "Revoke a delegate's access to the mailbox."
inputs_schema:
properties:
delegate_email: { type: string, description: "Delegate's email address to revoke" }
user_id: { type: string, description: "Mailbox to impersonate (default from instance config)" }
required: [delegate_email]
outputs_schema: { properties: {} }
# ── Workspace user administration (Directory API — runs as the admin) ────
- id: list_users
name: gmail-list-users
description: "List Workspace users in a domain (Directory API, impersonates the configured admin account)."
risk: read
inputs_schema:
properties:
domain: { type: string, description: "Domain to list (defaults to the admin account's domain)" }
query: { type: string, description: "Directory search query (e.g. email:john* or name:'Jane Doe')" }
max_results: { type: number, description: "Maximum users per page (default 100, max 500)" }
page_token: { type: string, description: "Page token from a previous call" }
show_deleted: { type: boolean, description: "List recently deleted users instead of active ones" }
required: []
outputs_schema: { properties: {} }
- id: get_user
name: gmail-get-user
description: "Get a Workspace user by primary email, alias or unique ID (Directory API)."
risk: read
inputs_schema:
properties:
user_key: { type: string, description: "User's primary email, alias email or unique ID" }
required: [user_key]
outputs_schema: { properties: {} }
- id: create_user
name: gmail-create-user
description: "Create a Workspace user (Directory API)."
inputs_schema:
properties:
email: { type: string, description: "New user's primary email address" }
first_name: { type: string, description: "Given name" }
last_name: { type: string, description: "Family name" }
password: { type: string, description: "Initial password" }
required: [email, first_name, last_name, password]
outputs_schema: { properties: {} }
- id: delete_user
name: gmail-delete-user
description: "Delete a Workspace user (Directory API)."
inputs_schema:
properties:
user_key: { type: string, description: "User's primary email, alias email or unique ID" }
required: [user_key]
outputs_schema: { properties: {} }
- id: set_password
name: gmail-set-password
description: "Reset a Workspace user's password (Directory API) — a common containment step for a compromised account."
inputs_schema:
properties:
user_key: { type: string, description: "User's primary email, alias email or unique ID" }
password: { type: string, description: "New password" }
required: [user_key, password]
outputs_schema: { properties: {} }
- id: hide_user
name: gmail-hide-user
description: "Set a Workspace user's global directory visibility (Directory API)."
inputs_schema:
properties:
user_key: { type: string, description: "User's primary email, alias email or unique ID" }
visible: { type: boolean, description: "true to show the user in the global directory, false to hide" }
required: [user_key]
outputs_schema: { properties: {} }
- id: test_connection
name: gmail-test-connection
description: "Verify the service account credentials and delegation by fetching the configured mailbox's 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 Message"