feat(oci): add native foundation - #7444
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Greptile SummaryThe PR establishes native server-side OCI API-key credentials, including validation, request signing, endpoint resolution, encrypted persistence, credential rotation, API contracts, catalog metadata, and client setup.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains in the eligible follow-up review scope. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| apps/sim/lib/credentials/oci-api-key-service-account.server.ts | Adds strict OCI credential normalization, RSA and fingerprint verification, sanitized provider-error mapping, and encryption after successful verification. |
| apps/sim/lib/internal/oci/client.server.ts | Adds OCI request signing and bounded transport with cancellation, retry, redirect, and response-size controls. |
| apps/sim/lib/internal/oci/endpoints.ts | Adds a snapshot-backed OCI region and realm registry with constrained service endpoint construction. |
| apps/sim/lib/credentials/service-account-secret.ts | Integrates OCI API-key material into the shared server-side service-account verification and secret-building boundary. |
| apps/sim/lib/credentials/orchestration/index.ts | Adds complete-tuple OCI credential rotation while preserving the old secret when verification fails. |
| apps/sim/lib/api/contracts/v2/credentials.ts | Extends v2 credential create and update contracts with bounded OCI fields and write-only secret annotations. |
| apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsx | Adds the OCI API-key setup and reconnect form using the existing credential mutation hooks. |
| apps/sim/lib/credentials/application/provider-catalog.ts | Publishes OCI credential field metadata while retaining independent provider-availability gating. |
| packages/sim-cli/src/generated/v2-api.ts | Extends the generated CLI update operation with the OCI credential fields. |
Sequence Diagram
sequenceDiagram
participant User
participant API as Credential API
participant Service as OCI Credential Service
participant OCI as OCI Object Storage
participant Store as Encrypted Credential Store
User->>API: Submit OCI signing tuple
API->>Service: Validate and normalize fields
Service->>Service: Parse RSA key and verify fingerprint
Service->>OCI: Signed GetNamespace request
OCI-->>Service: Valid namespace response
Service->>Store: Encrypt and persist credential
Store-->>API: Credential metadata
API-->>User: Sanitized credential response
Reviews (11): Last reviewed commit: "fix(oci): preserve endpoint and failure ..." | Re-trigger Greptile
There was a problem hiding this comment.
All reported issues were addressed across 12 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
d7a3b4f to
d2d066d
Compare
|
@greptile review this PR |
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
d2d066d to
77e26a0
Compare
|
@greptile review this PR |
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
|
@greptile review this PR |
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
b1c7879 to
a48813a
Compare
|
@greptile review this PR |
|
@cubic-dev-ai review this PR |
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 36895932 | Triggered | Generic Private Key | 1335344 | apps/sim/lib/internal/oci/client.server.test.ts | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
There was a problem hiding this comment.
All reported issues were addressed
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 42 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
4 issues found across 38 files
Confidence score: 2/5
apps/sim/lib/oauth/token-resolution.tsstill refreshes and returns an OAuth token when the tool requires a service-account credential, weakening credential-kind enforcement; reject mismatched credentials before entering the OAuth refresh branch.apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsxleaves OCI private keys fully visible after focus is lost, exposing secret material on screen; use a masked multiline secret control.apps/sim/lib/oauth/token-resolution.tsreturnsOCI_CREDENTIAL_TOOL_UNSUPPORTEDbeforeinput.authenticate()andauthorizeCredentialUseForAuth()for service-account IDs paired with non-OCI or unknown tools, bypassing the intended authentication and authorization flow; reorder the validation so those checks run first.apps/sim/components/icons.tsxaliasesOracleIcontoNetSuiteIcon, causing OCI integrations to display the wrong provider branding; add a dedicated Oracle/OCI SVG.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/components/icons.tsx">
<violation number="1" location="apps/sim/components/icons.tsx:9336">
P2: The OCI provider now displays the NetSuite logo because `OracleIcon` is an alias of `NetSuiteIcon`. Add a dedicated Oracle/OCI SVG instead, so the new OCI integration is not branded as NetSuite.</violation>
</file>
<file name="apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsx">
<violation number="1" location="apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsx:387">
P2: The OCI private key remains fully visible in the modal after the field loses focus, even though the provider catalog marks it as secret. Use a masked multiline secret control so the key is not left exposed on screen while preserving PEM paste/editing.</violation>
</file>
<file name="apps/sim/lib/oauth/token-resolution.ts">
<violation number="1" location="apps/sim/lib/oauth/token-resolution.ts:377">
P2: When an OCI tool declares `credentialKind: 'service-account'` but the caller supplies an OAuth credential, this expectation is passed through and the OAuth branch still refreshes and returns the token. Reject the credential-kind mismatch after authorization instead of allowing an OAuth credential for a service-account-only tool.</violation>
<violation number="2" location="apps/sim/lib/oauth/token-resolution.ts:382">
P2: When a caller supplies an OCI service-account ID with a non-OCI or unknown `toolId`, this branch returns `OCI_CREDENTIAL_TOOL_UNSUPPORTED` before `input.authenticate()` and `authorizeCredentialUseForAuth()` run, exposing provider-mismatch details to unauthenticated callers. Authenticate and authorize first, then apply this mismatch response only for an authorized caller.
(Based on your team's feedback about authorization before mismatch details.)</violation>
</file>
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Fix all with cubic | Re-trigger cubic
| ) | ||
| } | ||
|
|
||
| export const OracleIcon = NetSuiteIcon |
There was a problem hiding this comment.
P2: The OCI provider now displays the NetSuite logo because OracleIcon is an alias of NetSuiteIcon. Add a dedicated Oracle/OCI SVG instead, so the new OCI integration is not branded as NetSuite.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/components/icons.tsx, line 9336:
<comment>The OCI provider now displays the NetSuite logo because `OracleIcon` is an alias of `NetSuiteIcon`. Add a dedicated Oracle/OCI SVG instead, so the new OCI integration is not branded as NetSuite.</comment>
<file context>
@@ -9333,6 +9333,8 @@ export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
)
}
+export const OracleIcon = NetSuiteIcon
+
export function WizaIcon(props: SVGProps<SVGSVGElement>) {
</file context>
| required | ||
| /> | ||
| <ChipModalField | ||
| type='textarea' |
There was a problem hiding this comment.
P2: The OCI private key remains fully visible in the modal after the field loses focus, even though the provider catalog marks it as secret. Use a masked multiline secret control so the key is not left exposed on screen while preserving PEM paste/editing.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsx, line 387:
<comment>The OCI private key remains fully visible in the modal after the field loses focus, even though the provider catalog marks it as secret. Use a masked multiline secret control so the key is not left exposed on screen while preserving PEM paste/editing.</comment>
<file context>
@@ -241,6 +263,196 @@ interface ProviderModalProps {
+ required
+ />
+ <ChipModalField
+ type='textarea'
+ title='Private key'
+ value={privateKey}
</file context>
| : undefined | ||
|
|
||
| if ( | ||
| resolved?.credentialType === 'service_account' && |
There was a problem hiding this comment.
P2: When a caller supplies an OCI service-account ID with a non-OCI or unknown toolId, this branch returns OCI_CREDENTIAL_TOOL_UNSUPPORTED before input.authenticate() and authorizeCredentialUseForAuth() run, exposing provider-mismatch details to unauthenticated callers. Authenticate and authorize first, then apply this mismatch response only for an authorized caller.
(Based on your team's feedback about authorization before mismatch details.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/lib/oauth/token-resolution.ts, line 382:
<comment>When a caller supplies an OCI service-account ID with a non-OCI or unknown `toolId`, this branch returns `OCI_CREDENTIAL_TOOL_UNSUPPORTED` before `input.authenticate()` and `authorizeCredentialUseForAuth()` run, exposing provider-mismatch details to unauthenticated callers. Authenticate and authorize first, then apply this mismatch response only for an authorized caller.
(Based on your team's feedback about authorization before mismatch details.) </comment>
<file context>
@@ -346,6 +367,34 @@ export async function resolveCredentialAccessToken(
+ : undefined
+
+ if (
+ resolved?.credentialType === 'service_account' &&
+ resolved.providerId === OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID &&
+ !isOciServiceAccountTool
</file context>
| toolMetadata?.oauth?.required === true && | ||
| toolMetadata.oauth.credentialKind === 'service-account' && | ||
| service?.serviceAccountProviderId === OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID | ||
| const expectedServiceAccountProviderId = isOciServiceAccountTool |
There was a problem hiding this comment.
P2: When an OCI tool declares credentialKind: 'service-account' but the caller supplies an OAuth credential, this expectation is passed through and the OAuth branch still refreshes and returns the token. Reject the credential-kind mismatch after authorization instead of allowing an OAuth credential for a service-account-only tool.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/lib/oauth/token-resolution.ts, line 377:
<comment>When an OCI tool declares `credentialKind: 'service-account'` but the caller supplies an OAuth credential, this expectation is passed through and the OAuth branch still refreshes and returns the token. Reject the credential-kind mismatch after authorization instead of allowing an OAuth credential for a service-account-only tool.</comment>
<file context>
@@ -346,6 +367,34 @@ export async function resolveCredentialAccessToken(
+ toolMetadata?.oauth?.required === true &&
+ toolMetadata.oauth.credentialKind === 'service-account' &&
+ service?.serviceAccountProviderId === OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID
+ const expectedServiceAccountProviderId = isOciServiceAccountTool
+ ? OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID
+ : undefined
</file context>
|
@cubic-dev-ai review this PR |
@BillLeoutsakosvl346 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
2 issues found across 38 files
Confidence score: 3/5
- In
apps/sim/lib/internal/oci/endpoints.ts, Identity requests can resolve to a nonexistent or incorrect host becauseregionalOciHostnameomits OCI’s required.ocicomponent; add a service-specific Identity endpoint template. - In
apps/sim/lib/credentials/service-account-secret.ts, semantically invalid OCI fields can throw a plainErrorbeforeOciCredentialVerificationErroris produced, causing create and reconnect flows to bypass expected verification handling; validate or normalize the error path beforebuildSecretthrows.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/lib/internal/oci/endpoints.ts">
<violation number="1" location="apps/sim/lib/internal/oci/endpoints.ts:268">
P2: When `serviceName` is `identity`, `regionalOciHostname` omits OCI's required `.oci` host component, so Identity requests target a nonexistent or incorrect endpoint. Add a service-specific endpoint template for Identity instead of applying the generic hostname format to every service.</violation>
</file>
<file name="apps/sim/lib/credentials/service-account-secret.ts">
<violation number="1" location="apps/sim/lib/credentials/service-account-secret.ts:243">
P2: When a syntactically valid but semantically invalid OCI field is submitted, `buildSecret` throws a plain `Error` before this call can produce `OciCredentialVerificationError`. The create and reconnect paths then bypass `ServiceAccountSecretError` handling and return a generic 500 instead of a validation response; classify verifier input-validation failures as `invalid_credentials` without catching encryption failures.</violation>
</file>
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Fix all with cubic | Re-trigger cubic
|
|
||
| export function regionalOciHostname(serviceName: string, region: OciRegion): string { | ||
| assertServiceName(serviceName) | ||
| return `${serviceName}.${region.id}.${region.realm.domain}` |
There was a problem hiding this comment.
P2: When serviceName is identity, regionalOciHostname omits OCI's required .oci host component, so Identity requests target a nonexistent or incorrect endpoint. Add a service-specific endpoint template for Identity instead of applying the generic hostname format to every service.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/lib/internal/oci/endpoints.ts, line 268:
<comment>When `serviceName` is `identity`, `regionalOciHostname` omits OCI's required `.oci` host component, so Identity requests target a nonexistent or incorrect endpoint. Add a service-specific endpoint template for Identity instead of applying the generic hostname format to every service.</comment>
<file context>
@@ -0,0 +1,351 @@
+
+export function regionalOciHostname(serviceName: string, region: OciRegion): string {
+ assertServiceName(serviceName)
+ return `${serviceName}.${region.id}.${region.realm.domain}`
+}
+
</file context>
| ) | ||
| } | ||
| try { | ||
| const result = await verifyAndEncryptOciApiKeyCredential({ |
There was a problem hiding this comment.
P2: When a syntactically valid but semantically invalid OCI field is submitted, buildSecret throws a plain Error before this call can produce OciCredentialVerificationError. The create and reconnect paths then bypass ServiceAccountSecretError handling and return a generic 500 instead of a validation response; classify verifier input-validation failures as invalid_credentials without catching encryption failures.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/lib/credentials/service-account-secret.ts, line 243:
<comment>When a syntactically valid but semantically invalid OCI field is submitted, `buildSecret` throws a plain `Error` before this call can produce `OciCredentialVerificationError`. The create and reconnect paths then bypass `ServiceAccountSecretError` handling and return a generic 500 instead of a validation response; classify verifier input-validation failures as `invalid_credentials` without catching encryption failures.</comment>
<file context>
@@ -217,6 +230,48 @@ async function buildGoogleServiceAccountSecret(
+ )
+ }
+ try {
+ const result = await verifyAndEncryptOciApiKeyCredential({
+ tenancyOcid,
+ userOcid,
</file context>
Summary
Type of Change
Testing
Checklist
Screenshots/Videos
Not applicable; this change is server-only.