Skip to content

feature : external oauth#6292

Open
hsaxena0490 wants to merge 4 commits intoFlowiseAI:mainfrom
hsaxena0490:feature/external-oauth
Open

feature : external oauth#6292
hsaxena0490 wants to merge 4 commits intoFlowiseAI:mainfrom
hsaxena0490:feature/external-oauth

Conversation

@hsaxena0490
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for external OAuth 2.0 authentication (specifically targeting Okta) by allowing Flowise to act as a resource server. It includes new database entities for managing integrations and federated accounts, CRUD controllers, and middleware to validate JWT access tokens. Feedback focuses on security and performance: a potential IDOR vulnerability was identified where workspaceId is sourced from the request body, and several performance optimizations were suggested, including reducing redundant database saves during authentication, eager loading related entities to avoid queries within loops, lowering OIDC discovery timeouts, and caching subscription-related metadata.

Comment on lines +61 to +71
const row = await externalOAuthIntegrationService.create(app.AppDataSource, {
name: body.name,
issuerUrl: body.issuerUrl,
audiences: body.audiences,
allowedClientIds: body.allowedClientIds ?? null,
permissionScopeMap: body.permissionScopeMap || {},
organizationId: orgId,
workspaceId: body.workspaceId,
customPermissionsClaimName: body.customPermissionsClaimName,
enabled: body.enabled
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The workspaceId is being sourced from the request body. According to repository security rules, sensitive fields like workspaceId must be set on the server from a trusted source (such as the user's session or organization context) rather than being passed from the client to prevent IDOR vulnerabilities.

References
  1. Sensitive fields like workspaceId must be set on the server from a trusted source (e.g., user session), not from the client request body, to prevent IDOR vulnerabilities.

Comment on lines +23 to +29
if (existing) {
existing.email = params.email ?? existing.email
existing.userId = params.userId ?? existing.userId
existing.organizationId = params.organizationId
existing.workspaceId = params.workspaceId
await repo.save(existing)
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Performing a database save operation on every successful authentication request will significantly impact API performance. Since most authentication events for the same user won't change the federated account details, you should check if the existing record actually needs updating (e.g., if the email has changed) before calling repo.save. Alternatively, consider throttling updates to a 'last login' timestamp.

Suggested change
if (existing) {
existing.email = params.email ?? existing.email
existing.userId = params.userId ?? existing.userId
existing.organizationId = params.organizationId
existing.workspaceId = params.workspaceId
await repo.save(existing)
return
if (existing) {
const hasChanges = (params.email && existing.email !== params.email) || (params.userId && existing.userId !== params.userId);
if (hasChanges) {
existing.email = params.email ?? existing.email;
existing.userId = params.userId ?? existing.userId;
existing.organizationId = params.organizationId;
existing.workspaceId = params.workspaceId;
await repo.save(existing);
}
return;
}

Comment on lines +39 to +52
const workspace = await dataSource.getRepository(Workspace).findOne({
where: { id: integration.workspaceId }
})
if (!workspace || workspace.organizationId !== integration.organizationId) {
logger.warn(`[external-oauth]: Invalid workspace binding for integration ${integration.id}`)
continue
}
const org = await dataSource.getRepository(Organization).findOne({
where: { id: integration.organizationId }
})
if (!org) {
logger.warn(`[external-oauth]: Organization missing for integration ${integration.id}`)
continue
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing separate database queries for Workspace and Organization inside a loop on every authenticated request is inefficient. These entities should be eagerly loaded or joined during the initial findEnabledByIssuerUrl call to reduce the number of round-trips to the database.


const url = wellKnownUrl(issuerUrl)
try {
const { data } = await axios.get<OidcMetadata>(url, { timeout: 10000 })
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

A 10-second timeout for an OIDC discovery request is quite long for a blocking authentication middleware. If the external provider is slow or unresponsive, it will hang the client request. Consider reducing this timeout to a more aggressive value (e.g., 2-3 seconds) and ensure the failure is handled gracefully.

Suggested change
const { data } = await axios.get<OidcMetadata>(url, { timeout: 10000 })
const { data } = await axios.get<OidcMetadata>(url, { timeout: 3000 })

Comment on lines +32 to +34
features = await identityManager.getFeaturesByPlan(subscriptionId)
}
const productId = await identityManager.getProductIdFromSubscription(subscriptionId)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The calls to getFeaturesByPlan and getProductIdFromSubscription are performed on every request. These values are typically static for a given organization/subscription and should be cached to avoid unnecessary overhead during the authentication process.

@hsaxena0490 hsaxena0490 marked this pull request as ready for review April 28, 2026 14:59
@hsaxena0490 hsaxena0490 changed the title Feature/external oauth feature : external oauth Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant