Skip to content

Commit 0c86cb6

Browse files
fix(credentials): make Claude Platform API keys available in the provider catalog (#8593)
1 parent d3bf864 commit 0c86cb6

3 files changed

Lines changed: 53 additions & 34 deletions

File tree

‎apps/sim/lib/integrations/credential-display.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const EXPECTED_COVERAGE: Record<string, string[]> = {
3737
'attio-service-account': ['attio'],
3838
'box-service-account': ['box'],
3939
'calcom-service-account': ['cal-com'],
40-
'claude-platform-service-account': [],
40+
'claude-platform-service-account': ['claude-managed-agents'],
4141
'clickup-service-account': ['clickup'],
4242
'coda-service-account': ['coda'],
4343
'github-app-installation': ['github'],

‎apps/sim/lib/integrations/credential-visibility.server.test.ts‎

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,40 +67,56 @@ describe('integration credential visibility', () => {
6767
])
6868
})
6969

70-
it('exposes Coda token credentials without OAuth while honoring integration policy and visibility', () => {
71-
const catalog = resolveIntegrationAvailability({})
72-
expect(catalog.find((entry) => entry.type === 'coda')).toMatchObject({
73-
state: 'ready',
74-
oauthAvailable: false,
75-
serviceAccountAvailable: true,
76-
})
77-
getIntegrationAvailabilityMock.mockReturnValue(catalog)
78-
const service: OAuthServiceMetadata = {
70+
it.each([
71+
{
7972
serviceId: 'coda',
80-
providerId: 'coda',
81-
serviceAccountProviderId: 'coda-service-account',
82-
authType: 'service_account',
73+
providerId: 'coda-service-account',
74+
blockType: 'coda',
8375
name: 'Coda',
84-
description: 'Coda token',
85-
baseProvider: 'coda',
86-
}
87-
const identity = { providerId: 'coda-service-account', type: 'service_account' } as const
88-
const visibility = (allowed: ReadonlySet<string> | null, disabled: boolean) =>
89-
createIntegrationCredentialVisibility({
90-
allowedIntegrationTypes: allowed,
91-
oauthServices: [service],
92-
blockVisibility: {
93-
revealed: new Set(),
94-
previewTagged: new Set(),
95-
disabled: new Set(disabled ? ['coda'] : []),
96-
},
76+
},
77+
{
78+
serviceId: 'claude-platform',
79+
providerId: 'claude-platform-service-account',
80+
blockType: 'managed_agent',
81+
name: 'Claude Platform',
82+
},
83+
])(
84+
'exposes $name token credentials without OAuth while honoring integration policy and visibility',
85+
({ serviceId, providerId, blockType, name }) => {
86+
const catalog = resolveIntegrationAvailability({})
87+
expect(catalog.find((entry) => entry.type === blockType)).toMatchObject({
88+
state: 'ready',
89+
oauthAvailable: false,
90+
serviceAccountAvailable: true,
9791
})
98-
expect(visibility(new Set(['coda']), false).isCredentialVisible(identity)).toBe(true)
99-
expect(visibility(new Set(['slack_v2']), false).isCredentialVisible(identity)).toBe(false)
100-
expect(visibility(null, true).isCredentialVisible(identity)).toBe(false)
101-
getBlockMock.mockReturnValue({ type: 'coda', preview: true } as never)
102-
expect(visibility(null, false).isCredentialVisible(identity)).toBe(false)
103-
})
92+
getIntegrationAvailabilityMock.mockReturnValue(catalog)
93+
const service: OAuthServiceMetadata = {
94+
serviceId,
95+
providerId: serviceId,
96+
serviceAccountProviderId: providerId,
97+
authType: 'service_account',
98+
name,
99+
description: `${name} token`,
100+
baseProvider: serviceId,
101+
}
102+
const identity = { providerId, type: 'service_account' } as const
103+
const visibility = (allowed: ReadonlySet<string> | null, disabled: boolean) =>
104+
createIntegrationCredentialVisibility({
105+
allowedIntegrationTypes: allowed,
106+
oauthServices: [service],
107+
blockVisibility: {
108+
revealed: new Set(),
109+
previewTagged: new Set(),
110+
disabled: new Set(disabled ? [blockType] : []),
111+
},
112+
})
113+
expect(visibility(new Set([blockType]), false).isCredentialVisible(identity)).toBe(true)
114+
expect(visibility(new Set(['slack_v2']), false).isCredentialVisible(identity)).toBe(false)
115+
expect(visibility(null, true).isCredentialVisible(identity)).toBe(false)
116+
getBlockMock.mockReturnValue({ type: blockType, preview: true } as never)
117+
expect(visibility(null, false).isCredentialVisible(identity)).toBe(false)
118+
}
119+
)
104120

105121
it('applies the integration allowlist to OAuth and service-account credentials', () => {
106122
const visibility = createIntegrationCredentialVisibility({

‎packages/deployment-config/src/integration-availability.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ const deploymentGatedIntegrationTypes = new Set(
2929
const integrationTypesByOAuthServiceId = new Map<string, readonly string[]>()
3030
/** Search authorization shares GitHub's integration policy while its workflow tools retain PAT auth. */
3131
integrationTypesByOAuthServiceId.set('github-repositories', ['github_v2'])
32-
/** Coda's stored API-token credential is available without a deployment OAuth client. */
33-
const tokenCredentialIntegrationTypes = new Map([['coda', 'coda']])
32+
/** Stored API-token credentials for api-key blocks are available without a deployment OAuth client. */
33+
const tokenCredentialIntegrationTypes = new Map([
34+
['coda', 'coda'],
35+
['claude-platform', 'managed_agent'],
36+
])
3437
for (const [serviceId, integrationType] of tokenCredentialIntegrationTypes) {
3538
integrationTypesByOAuthServiceId.set(serviceId, [integrationType])
3639
}

0 commit comments

Comments
 (0)