Skip to content

Commit c5b2f64

Browse files
author
Theodore Li
committed
Merge branch 'staging' into feat/cloudwatch-block
2 parents eaca4fb + a78f3f9 commit c5b2f64

680 files changed

Lines changed: 54882 additions & 11080 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cursor/skills/add-hosted-key/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ In the block config (`blocks/blocks/{service}.ts`), add `hideWhenHosted: true` t
192192
},
193193
```
194194

195-
The visibility is controlled by `isSubBlockHiddenByHostedKey()` in `lib/workflows/subblocks/visibility.ts`, which checks the `isHosted` feature flag.
195+
The visibility is controlled by `isSubBlockHidden()` in `lib/workflows/subblocks/visibility.ts`, which checks both the `isHosted` feature flag (`hideWhenHosted`) and optional env var conditions (`hideWhenEnvSet`).
196196

197197
### Excluding Specific Operations from Hosted Key Support
198198

.github/workflows/ci.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: CI
22

33
on:
44
push:
5-
branches: [main, staging]
5+
branches: [main, staging, dev]
66
pull_request:
7-
branches: [main, staging]
7+
branches: [main, staging, dev]
88

99
concurrency:
1010
group: ci-${{ github.ref }}
@@ -23,7 +23,7 @@ jobs:
2323
detect-version:
2424
name: Detect Version
2525
runs-on: blacksmith-4vcpu-ubuntu-2404
26-
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging')
26+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/dev')
2727
outputs:
2828
version: ${{ steps.extract.outputs.version }}
2929
is_release: ${{ steps.extract.outputs.is_release }}
@@ -49,7 +49,7 @@ jobs:
4949
build-amd64:
5050
name: Build AMD64
5151
needs: [test-build, detect-version]
52-
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging')
52+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/dev')
5353
runs-on: blacksmith-8vcpu-ubuntu-2404
5454
permissions:
5555
contents: read
@@ -75,8 +75,8 @@ jobs:
7575
- name: Configure AWS credentials
7676
uses: aws-actions/configure-aws-credentials@v4
7777
with:
78-
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
79-
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || secrets.STAGING_AWS_REGION }}
78+
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || github.ref == 'refs/heads/dev' && secrets.DEV_AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
79+
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || github.ref == 'refs/heads/dev' && secrets.DEV_AWS_REGION || secrets.STAGING_AWS_REGION }}
8080

8181
- name: Login to Amazon ECR
8282
id: login-ecr
@@ -109,6 +109,8 @@ jobs:
109109
# ECR tags (always build for ECR)
110110
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
111111
ECR_TAG="latest"
112+
elif [ "${{ github.ref }}" = "refs/heads/dev" ]; then
113+
ECR_TAG="dev"
112114
else
113115
ECR_TAG="staging"
114116
fi

.github/workflows/images.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
- name: Configure AWS credentials
3737
uses: aws-actions/configure-aws-credentials@v4
3838
with:
39-
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
40-
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || secrets.STAGING_AWS_REGION }}
39+
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || github.ref == 'refs/heads/dev' && secrets.DEV_AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
40+
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || github.ref == 'refs/heads/dev' && secrets.DEV_AWS_REGION || secrets.STAGING_AWS_REGION }}
4141

4242
- name: Login to Amazon ECR
4343
id: login-ecr
@@ -70,6 +70,8 @@ jobs:
7070
# ECR tags (always build for ECR)
7171
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
7272
ECR_TAG="latest"
73+
elif [ "${{ github.ref }}" = "refs/heads/dev" ]; then
74+
ECR_TAG="dev"
7375
else
7476
ECR_TAG="staging"
7577
fi

apps/docs/components/icons.tsx

Lines changed: 111 additions & 28 deletions
Large diffs are not rendered by default.

apps/docs/components/ui/icon-mapping.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
EnrichSoIcon,
4646
EvernoteIcon,
4747
ExaAIIcon,
48+
ExtendIcon,
4849
EyeIcon,
4950
FathomIcon,
5051
FirecrawlIcon,
@@ -91,6 +92,7 @@ import {
9192
KalshiIcon,
9293
KetchIcon,
9394
LangsmithIcon,
95+
LaunchDarklyIcon,
9496
LemlistIcon,
9597
LinearIcon,
9698
LinkedInIcon,
@@ -126,6 +128,7 @@ import {
126128
PolymarketIcon,
127129
PostgresIcon,
128130
PosthogIcon,
131+
ProfoundIcon,
129132
PulseIcon,
130133
QdrantIcon,
131134
QuiverIcon,
@@ -139,6 +142,7 @@ import {
139142
S3Icon,
140143
SalesforceIcon,
141144
SearchIcon,
145+
SecretsManagerIcon,
142146
SendgridIcon,
143147
SentryIcon,
144148
SerperIcon,
@@ -154,6 +158,7 @@ import {
154158
StagehandIcon,
155159
StripeIcon,
156160
SupabaseIcon,
161+
TailscaleIcon,
157162
TavilyIcon,
158163
TelegramIcon,
159164
TextractIcon,
@@ -220,6 +225,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
220225
enrich: EnrichSoIcon,
221226
evernote: EvernoteIcon,
222227
exa: ExaAIIcon,
228+
extend_v2: ExtendIcon,
223229
fathom: FathomIcon,
224230
file_v3: DocumentIcon,
225231
firecrawl: FirecrawlIcon,
@@ -268,6 +274,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
268274
ketch: KetchIcon,
269275
knowledge: PackageSearchIcon,
270276
langsmith: LangsmithIcon,
277+
launchdarkly: LaunchDarklyIcon,
271278
lemlist: LemlistIcon,
272279
linear: LinearIcon,
273280
linkedin: LinkedInIcon,
@@ -302,6 +309,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
302309
polymarket: PolymarketIcon,
303310
postgresql: PostgresIcon,
304311
posthog: PosthogIcon,
312+
profound: ProfoundIcon,
305313
pulse_v2: PulseIcon,
306314
qdrant: QdrantIcon,
307315
quiver: QuiverIcon,
@@ -315,6 +323,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
315323
s3: S3Icon,
316324
salesforce: SalesforceIcon,
317325
search: SearchIcon,
326+
secrets_manager: SecretsManagerIcon,
318327
sendgrid: SendgridIcon,
319328
sentry: SentryIcon,
320329
serper: SerperIcon,
@@ -331,6 +340,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
331340
stripe: StripeIcon,
332341
stt_v2: STTIcon,
333342
supabase: SupabaseIcon,
343+
tailscale: TailscaleIcon,
334344
tavily: TavilyIcon,
335345
telegram: TelegramIcon,
336346
textract_v2: TextractIcon,

apps/docs/content/docs/de/blocks/guardrails.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Erkennt personenbezogene Daten mithilfe von Microsoft Presidio. Unterstützt üb
131131
**Anwendungsfälle:**
132132
- Blockieren von Inhalten mit sensiblen persönlichen Informationen
133133
- Maskieren von personenbezogenen Daten vor der Protokollierung oder Speicherung
134-
- Einhaltung der DSGVO, HIPAA und anderer Datenschutzbestimmungen
134+
- Einhaltung der DSGVO und anderer Datenschutzbestimmungen
135135
- Bereinigung von Benutzereingaben vor der Verarbeitung
136136

137137
## Konfiguration

apps/docs/content/docs/en/blocks/guardrails.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Detects personally identifiable information using Microsoft Presidio. Supports o
132132
**Use Cases:**
133133
- Block content containing sensitive personal information
134134
- Mask PII before logging or storing data
135-
- Compliance with GDPR, HIPAA, and other privacy regulations
135+
- Compliance with GDPR and other privacy regulations
136136
- Sanitize user inputs before processing
137137

138138
## Configuration
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
title: Google Service Accounts
3+
description: Set up Google service accounts with domain-wide delegation for Gmail, Sheets, Drive, Calendar, and other Google services
4+
---
5+
6+
import { Callout } from 'fumadocs-ui/components/callout'
7+
import { Step, Steps } from 'fumadocs-ui/components/steps'
8+
import { Image } from '@/components/ui/image'
9+
import { FAQ } from '@/components/ui/faq'
10+
11+
Google service accounts with domain-wide delegation let your workflows access Google APIs on behalf of users in your Google Workspace domain — without requiring each user to complete an OAuth consent flow. This is ideal for automated workflows that need to send emails, read spreadsheets, or manage files across your organization.
12+
13+
For example, you could build a workflow that iterates through a list of employees, impersonates each one to read their Google Docs, and uploads the contents to a shared knowledge base — all without requiring any of those users to sign in.
14+
15+
## Prerequisites
16+
17+
Before adding a service account to Sim, you need to configure it in the Google Cloud Console and Google Workspace Admin Console.
18+
19+
### 1. Create a Service Account in Google Cloud
20+
21+
<Steps>
22+
<Step>
23+
Go to the [Google Cloud Console](https://console.cloud.google.com/) and select your project (or create one)
24+
</Step>
25+
<Step>
26+
Navigate to **IAM & Admin****Service Accounts**
27+
</Step>
28+
<Step>
29+
Click **Create Service Account**, give it a name and description, then click **Create and Continue**
30+
31+
<div className="flex justify-center">
32+
<Image
33+
src="/static/credentials/gcp-create-service-account.png"
34+
alt="Google Cloud Console — Create service account form"
35+
width={700}
36+
height={500}
37+
className="my-4"
38+
/>
39+
</div>
40+
</Step>
41+
<Step>
42+
Skip the optional role and user access steps and click **Done**
43+
</Step>
44+
<Step>
45+
Click on the newly created service account, go to the **Keys** tab, and click **Add Key****Create new key**
46+
</Step>
47+
<Step>
48+
Select **JSON** as the key type and click **Create**. A JSON key file will download — keep this safe
49+
50+
<div className="flex justify-center">
51+
<Image
52+
src="/static/credentials/gcp-create-private-key.png"
53+
alt="Google Cloud Console — Create private key dialog with JSON selected"
54+
width={700}
55+
height={400}
56+
className="my-4"
57+
/>
58+
</div>
59+
</Step>
60+
</Steps>
61+
62+
<Callout type="warn">
63+
The JSON key file contains your service account's private key. Treat it like a password — do not commit it to source control or share it publicly.
64+
</Callout>
65+
66+
### 2. Enable the Required APIs
67+
68+
In the Google Cloud Console, go to **APIs & Services****Library** and enable the APIs for the services your workflows will use. See the [scopes reference](#scopes-reference) below for the full list of APIs by service.
69+
70+
### 3. Set Up Domain-Wide Delegation
71+
72+
<Steps>
73+
<Step>
74+
In the Google Cloud Console, go to **IAM & Admin****Service Accounts**, click on your service account, and copy the **Client ID** (the numeric ID, not the email)
75+
</Step>
76+
<Step>
77+
Open the [Google Workspace Admin Console](https://admin.google.com/) and navigate to **Security****Access and data control****API controls**
78+
</Step>
79+
<Step>
80+
Click **Manage Domain Wide Delegation**, then click **Add new**
81+
</Step>
82+
<Step>
83+
Paste the **Client ID** from your service account, then add the OAuth scopes for the services your workflows need. Copy the full scope URLs from the [scopes reference](#scopes-reference) below — only authorize scopes for services you plan to use.
84+
85+
<div className="flex justify-center">
86+
<Image
87+
src="/static/credentials/gcp-add-client-id.png"
88+
alt="Google Workspace Admin Console — Add a new client ID with OAuth scopes"
89+
width={350}
90+
height={300}
91+
className="my-4"
92+
/>
93+
</div>
94+
</Step>
95+
<Step>
96+
Click **Authorize**
97+
</Step>
98+
</Steps>
99+
100+
<Callout type="info">
101+
Domain-wide delegation must be configured by a Google Workspace admin. If you are not an admin, send the Client ID and required scopes to your admin.
102+
</Callout>
103+
104+
### Scopes Reference
105+
106+
The table below lists every Google service that supports service account authentication in Sim, the API to enable in Google Cloud Console, and the delegation scopes to authorize. Copy the scope string for each service you need and paste it into the Google Workspace Admin Console.
107+
108+
<table>
109+
<thead>
110+
<tr>
111+
<th className="whitespace-nowrap">Service</th>
112+
<th className="whitespace-nowrap">API to Enable</th>
113+
<th>Delegation Scopes</th>
114+
</tr>
115+
</thead>
116+
<tbody>
117+
<tr><td>Gmail</td><td>Gmail API</td><td><code>{'https://www.googleapis.com/auth/gmail.send'}</code><br/><code>{'https://www.googleapis.com/auth/gmail.modify'}</code><br/><code>{'https://www.googleapis.com/auth/gmail.labels'}</code></td></tr>
118+
<tr><td>Google Sheets</td><td>Google Sheets API, Google Drive API</td><td><code>{'https://www.googleapis.com/auth/drive'}</code><br/><code>{'https://www.googleapis.com/auth/drive.file'}</code></td></tr>
119+
<tr><td>Google Drive</td><td>Google Drive API</td><td><code>{'https://www.googleapis.com/auth/drive'}</code><br/><code>{'https://www.googleapis.com/auth/drive.file'}</code></td></tr>
120+
<tr><td>Google Docs</td><td>Google Docs API, Google Drive API</td><td><code>{'https://www.googleapis.com/auth/drive'}</code><br/><code>{'https://www.googleapis.com/auth/drive.file'}</code></td></tr>
121+
<tr><td>Google Slides</td><td>Google Slides API, Google Drive API</td><td><code>{'https://www.googleapis.com/auth/drive'}</code><br/><code>{'https://www.googleapis.com/auth/drive.file'}</code></td></tr>
122+
<tr><td>Google Forms</td><td>Google Forms API, Google Drive API</td><td><code>{'https://www.googleapis.com/auth/drive'}</code><br/><code>{'https://www.googleapis.com/auth/forms.body'}</code><br/><code>{'https://www.googleapis.com/auth/forms.responses.readonly'}</code></td></tr>
123+
<tr><td>Google Calendar</td><td>Google Calendar API</td><td><code>{'https://www.googleapis.com/auth/calendar'}</code></td></tr>
124+
<tr><td>Google Contacts</td><td>People API</td><td><code>{'https://www.googleapis.com/auth/contacts'}</code></td></tr>
125+
<tr><td>BigQuery</td><td>BigQuery API</td><td><code>{'https://www.googleapis.com/auth/bigquery'}</code></td></tr>
126+
<tr><td>Google Tasks</td><td>Tasks API</td><td><code>{'https://www.googleapis.com/auth/tasks'}</code></td></tr>
127+
<tr><td>Google Vault</td><td>Vault API, Cloud Storage API</td><td><code>{'https://www.googleapis.com/auth/ediscovery'}</code><br/><code>{'https://www.googleapis.com/auth/devstorage.read_only'}</code></td></tr>
128+
<tr><td>Google Groups</td><td>Admin SDK API</td><td><code>{'https://www.googleapis.com/auth/admin.directory.group'}</code><br/><code>{'https://www.googleapis.com/auth/admin.directory.group.member'}</code></td></tr>
129+
<tr><td>Google Meet</td><td>Google Meet API</td><td><code>{'https://www.googleapis.com/auth/meetings.space.created'}</code><br/><code>{'https://www.googleapis.com/auth/meetings.space.readonly'}</code></td></tr>
130+
</tbody>
131+
</table>
132+
133+
<Callout type="info">
134+
You only need to enable APIs and authorize scopes for the services you plan to use. When authorizing multiple services, combine their scope strings with commas into a single entry in the Admin Console.
135+
</Callout>
136+
137+
## Adding the Service Account to Sim
138+
139+
Once Google Cloud and Workspace are configured, add the service account as a credential in Sim.
140+
141+
<Steps>
142+
<Step>
143+
Open your workspace **Settings** and go to the **Integrations** tab
144+
</Step>
145+
<Step>
146+
Search for "Google Service Account" and click **Connect**
147+
148+
<div className="flex justify-center">
149+
<Image
150+
src="/static/credentials/integrations-service-account.png"
151+
alt="Integrations page showing Google Service Account"
152+
width={800}
153+
height={150}
154+
className="my-4"
155+
/>
156+
</div>
157+
</Step>
158+
<Step>
159+
Paste the full contents of your JSON key file into the text area
160+
<div className="flex justify-center">
161+
<Image
162+
src="/static/credentials/add-service-account.png"
163+
alt="Add Google Service Account dialog"
164+
width={350}
165+
height={420}
166+
className="my-6"
167+
/>
168+
</div>
169+
</Step>
170+
<Step>
171+
Give the credential a display name (the service account email is used by default)
172+
</Step>
173+
<Step>
174+
Click **Save**
175+
</Step>
176+
</Steps>
177+
178+
The JSON key file is validated for the required fields (`type`, `client_email`, `private_key`, `project_id`) and encrypted before being stored.
179+
180+
## Using Delegated Access in Workflows
181+
182+
When you use a Google block (Gmail, Sheets, Drive, etc.) in a workflow and select a service account credential, an **Impersonate User Email** field appears below the credential selector.
183+
184+
Enter the email address of the Google Workspace user you want the service account to act as. For example, if you enter `alice@yourcompany.com`, the workflow will send emails from Alice's account, read her spreadsheets, or access her calendar — depending on the scopes you authorized.
185+
186+
<div className="flex justify-center">
187+
<Image
188+
src="/static/credentials/workflow-impersonated-account.png"
189+
alt="Gmail block in a workflow showing the Impersonated Account field with a service account credential"
190+
width={800}
191+
height={350}
192+
className="my-4"
193+
/>
194+
</div>
195+
196+
<Callout type="warn">
197+
The impersonated email must belong to a user in the Google Workspace domain where you configured domain-wide delegation. Impersonating external email addresses will fail.
198+
</Callout>
199+
200+
<FAQ items={[
201+
{ question: "Can I use a service account without domain-wide delegation?", answer: "Yes, but it will only be able to access resources owned by the service account itself (e.g., spreadsheets shared directly with the service account email). Without delegation, you cannot impersonate users or access their personal data like Gmail." },
202+
{ question: "What happens if the impersonation email field is left blank?", answer: "The service account will authenticate as itself. This works for accessing shared resources (like a Google Sheet shared with the service account email) but will fail for user-specific APIs like Gmail." },
203+
{ question: "Can I use the same service account for multiple Google services?", answer: "Yes. A single service account can be used across Gmail, Sheets, Drive, Calendar, and other Google services — as long as the required API is enabled in Google Cloud and the corresponding scopes are authorized in the Workspace admin console." },
204+
{ question: "How do I rotate the service account key?", answer: "Create a new JSON key in the Google Cloud Console under your service account's Keys tab, then update the credential in Sim with the new key. Delete the old key from Google Cloud once the new one is working." },
205+
{ question: "Does the impersonated user need a Google Workspace license?", answer: "Yes. Domain-wide delegation only works with users who have a Google Workspace account in the domain. Consumer Gmail accounts (e.g., @gmail.com) cannot be impersonated." },
206+
]} />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"title": "Credentials",
3+
"pages": ["index", "google-service-account"],
4+
"defaultOpen": false
5+
}

0 commit comments

Comments
 (0)