IAV-1045/feat: secondary credentials support for AgentIntegration
Summary
This MR introduces secondary credentials for AgentIntegration. Some N8N workflows
require more than one credential to operate (e.g. a WhatsApp automation needing both a
WHATSAPP token and a WHATSAPP_OAUTH credentials). Previously, only one primary credential
could be attached per integration. This change makes the model fully extensible.
What Changed
New capability — secondary credentials
A new AgentIntegrationSecondaryCredential entity, service, and repository allow attaching
additional credentials to any AgentIntegration. Two modes are supported per secondary:
-
Mode 1 — reference an already-existing
credentialInstanceUid -
Mode 2 — provide
credentialName+credentialDataand let the service create the credential in core-n8n-service on the fly.
Secondary credentials can be supplied inline at integration creation time via the new
secondaryCredentials list on CreateAgentIntegrationRequestDTO and
CreateUserIntegrationRequestDTO, or added later via the dedicated
AgentIntegrationSecondaryCredentialService.
Global uniqueness enforcement
A new CredentialInstanceUniquenessChecker component ensures that no
credentialInstanceUid is shared between two entities (whether primary or secondary).
This check is applied on create, update, and replicate flows.
Cascade and replication
-
Delete: when an
AgentIntegrationis deleted, all its secondary credential instances are deleted in core-n8n-service (best-effort, non-blocking) before the DB record is removed. -
Replicate:
replicateIntegrationnow replicates every secondary credential alongside the primary one, so a replicated integration arrives fully configured in the target N8N instance.
Performance — batch loading of secondaries
Listing endpoints (getIntegrationsByAgentUid, getIntegrationsByUserUid) now load all
secondary credentials for the current page in a single query using
findByAgentIntegrationUidIn, eliminating the previous N+1 pattern.
Bug fixes
Two methods (createIntegration, validateCredentialDataAgainstSchema) were swallowing
FunctionalException and TechnicalException inside a broad catch (Exception e) block.
Both are now fixed by re-throwing typed exceptions before the generic handler.
Files Changed
| File | Type |
|---|---|
AgentIntegrationSecondaryCredentialService.java |
|
AgentIntegrationSecondaryCredentialServiceImpl.java |
|
AgentIntegrationSecondaryCredentialRepository.java |
|
CredentialInstanceUniquenessChecker.java |
|
SecondaryCredentialRequestDTO.java |
|
AgentIntegrationSecondaryCredentialResponse.java |
|
ValidSecondaryCredentialFields.java |
|
SecondaryCredentialFieldsValidator.java |
|
AgentIntegrationServiceImpl.java |
|
UserIntegrationServiceImpl.java |
|
AgentIntegrationRepository.java |
|
CreateAgentIntegrationRequestDTO.java |
|
CreateUserIntegrationRequestDTO.java |
|
AgentIntegrationResponseDTO.java |
|
UserIntegrationResponseDTO.java |
|
OrchestrationFunctionalError.java |
|
Breaking Changes
None. The secondaryCredentials list defaults to an empty ArrayList on all response and
request DTOs, ensuring full backward compatibility with existing clients.
Testing Checklist
-
Create integration with inline secondary credentials (Mode 1 and Mode 2) -
Attempt to reuse a credentialInstanceUidalready in use — expectORCH_035 -
Delete integration — verify secondary credential instances removed in N8N -
Replicate integration — verify secondary credentials replicated to target instance -
List integrations — confirm secondaries present and no N+1 queries in logs -
Update integration with new credentialInstanceUidalready used elsewhere — expectORCH_035 -
Create integration with invalid secondary credential (missing credentialName) — expect validation error