mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
requested changes
This commit is contained in:
@@ -28,6 +28,7 @@ import { githubConnectionService } from "@app/services/app-connection/github/git
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
|
||||
import { TAppConnectionDALFactory } from "./app-connection-dal";
|
||||
import { ValidateAzureAppConfigurationConnectionCredentialsSchema } from "./azure-app-configuration";
|
||||
import { ValidateAzureKeyVaultConnectionCredentialsSchema } from "./azure-key-vault";
|
||||
import { ValidateGcpConnectionCredentialsSchema } from "./gcp";
|
||||
import { gcpConnectionService } from "./gcp/gcp-connection-service";
|
||||
@@ -45,7 +46,7 @@ const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record<AppConnection, TValidateAp
|
||||
[AppConnection.GitHub]: ValidateGitHubConnectionCredentialsSchema,
|
||||
[AppConnection.GCP]: ValidateGcpConnectionCredentialsSchema,
|
||||
[AppConnection.AzureKeyVault]: ValidateAzureKeyVaultConnectionCredentialsSchema,
|
||||
[AppConnection.AzureAppConfiguration]: ValidateAzureKeyVaultConnectionCredentialsSchema
|
||||
[AppConnection.AzureAppConfiguration]: ValidateAzureAppConfigurationConnectionCredentialsSchema
|
||||
};
|
||||
|
||||
export const appConnectionServiceFactory = ({
|
||||
|
||||
@@ -63,7 +63,6 @@ export const SanitizedAzureAppConfigurationConnectionSchema = z.discriminatedUni
|
||||
BaseAzureAppConfigurationConnectionSchema.extend({
|
||||
method: z.literal(AzureAppConfigurationConnectionMethod.OAuth),
|
||||
credentials: AzureAppConfigurationConnectionOAuthOutputCredentialsSchema.pick({
|
||||
resource: true,
|
||||
tenantId: true
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,7 +63,6 @@ export const SanitizedAzureKeyVaultConnectionSchema = z.discriminatedUnion("meth
|
||||
BaseAzureKeyVaultConnectionSchema.extend({
|
||||
method: z.literal(AzureKeyVaultConnectionMethod.OAuth),
|
||||
credentials: AzureKeyVaultConnectionOAuthOutputCredentialsSchema.pick({
|
||||
resource: true,
|
||||
tenantId: true
|
||||
})
|
||||
})
|
||||
|
||||
@@ -19,6 +19,7 @@ type TAzureAppConfigurationSecretSyncFactoryDeps = {
|
||||
interface AzureAppConfigKeyValue {
|
||||
key: string;
|
||||
value: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export const azureAppConfigurationSecretSyncFactory = ({
|
||||
@@ -78,7 +79,9 @@ export const azureAppConfigurationSecretSyncFactory = ({
|
||||
secretSync.destinationConfig.label ? `&label=${secretSync.destinationConfig.label}` : "&label=%00"
|
||||
}`;
|
||||
|
||||
const azureAppConfigSecrets = Object.fromEntries(
|
||||
const azureAppConfigValuesUrlAllSecrets = `/kv?api-version=2023-11-01`;
|
||||
|
||||
const azureAppConfigSecretsLabeled = Object.fromEntries(
|
||||
(
|
||||
await $getCompleteAzureAppConfigValues(
|
||||
accessToken,
|
||||
@@ -88,9 +91,25 @@ export const azureAppConfigurationSecretSyncFactory = ({
|
||||
).map((entry) => [entry.key, entry.value])
|
||||
);
|
||||
|
||||
const azureAppConfigSecrets = Object.fromEntries(
|
||||
(
|
||||
await $getCompleteAzureAppConfigValues(
|
||||
accessToken,
|
||||
secretSync.destinationConfig.configurationUrl,
|
||||
azureAppConfigValuesUrlAllSecrets
|
||||
)
|
||||
).map((entry) => [
|
||||
entry.key,
|
||||
{
|
||||
value: entry.value,
|
||||
label: entry.label
|
||||
}
|
||||
])
|
||||
);
|
||||
|
||||
// add the secrets to azure app config, that are in infisical
|
||||
for await (const key of Object.keys(secretMap)) {
|
||||
if (!(key in azureAppConfigSecrets) || secretMap[key]?.value !== azureAppConfigSecrets[key]) {
|
||||
if (!(key in azureAppConfigSecretsLabeled) || secretMap[key]?.value !== azureAppConfigSecretsLabeled[key]) {
|
||||
await request.put(
|
||||
`${secretSync.destinationConfig.configurationUrl}/kv/${key}?api-version=2023-11-01`,
|
||||
{
|
||||
@@ -117,14 +136,14 @@ export const azureAppConfigurationSecretSyncFactory = ({
|
||||
}
|
||||
}
|
||||
|
||||
// delete the secrets that are in azure app config, but not in infisical
|
||||
for await (const key of Object.keys(azureAppConfigSecrets)) {
|
||||
if (!(key in secretMap) || secretMap[key] === null) {
|
||||
const azureSecret = azureAppConfigSecrets[key];
|
||||
if (!(key in secretMap) || secretMap[key] === null || azureSecret.label !== secretSync.destinationConfig.label) {
|
||||
await $deleteAzureSecret(
|
||||
accessToken,
|
||||
secretSync.destinationConfig.configurationUrl,
|
||||
key,
|
||||
secretSync.destinationConfig.label
|
||||
azureSecret.label // use the secret's actual label for deletion
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { getAzureConnectionAccessToken } from "@app/services/app-connection/azur
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TSecretMap } from "@app/services/secret-sync/secret-sync-types";
|
||||
|
||||
import { SecretSyncError } from "../secret-sync-errors";
|
||||
import { GetAzureKeyVaultSecret, TAzureKeyVaultSyncWithCredentials } from "./azure-key-vault-sync-types";
|
||||
|
||||
type TAzureKeyVaultSecretSyncFactoryDeps = {
|
||||
@@ -127,6 +128,7 @@ export const azureKeyVaultSecretSyncFactory = ({
|
||||
|
||||
const setSecretAzureKeyVault = async ({ key, value }: { key: string; value: string }) => {
|
||||
let isSecretSet = false;
|
||||
let syncError: Error | null = null;
|
||||
let maxTries = 6;
|
||||
if (disabledAzureKeyVaultSecretKeys.includes(key)) return;
|
||||
|
||||
@@ -147,6 +149,7 @@ export const azureKeyVaultSecretSyncFactory = ({
|
||||
|
||||
isSecretSet = true;
|
||||
} catch (err) {
|
||||
syncError = err as Error;
|
||||
if (err instanceof AxiosError) {
|
||||
// eslint-disable-next-line
|
||||
if (err.response?.data?.error?.innererror?.code === "ObjectIsDeletedButRecoverable") {
|
||||
@@ -174,7 +177,10 @@ export const azureKeyVaultSecretSyncFactory = ({
|
||||
}
|
||||
|
||||
if (!isSecretSet) {
|
||||
throw new Error(`Failed to set secret ${key}`);
|
||||
throw new SecretSyncError({
|
||||
error: syncError,
|
||||
secretKey: key
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Available"
|
||||
openapi: "GET /api/v1/app-connections/azure-app-configuration/available"
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Create"
|
||||
openapi: "POST /api/v1/app-connections/azure-app-configuration"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Azure App Configuration Connections must be created through the Infisical UI.
|
||||
Check out the configuration docs for [Azure App Configuration Connections](/integrations/app-connections/azure-app-configuration) for a step-by-step
|
||||
guide.
|
||||
</Note>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Delete"
|
||||
openapi: "DELETE /api/v1/app-connections/azure-app-configuration/{connectionId}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get by ID"
|
||||
openapi: "GET /api/v1/app-connections/azure-app-configuration/{connectionId}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get by Name"
|
||||
openapi: "GET /api/v1/app-connections/azure-app-configuration/connection-name/{connectionName}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "List"
|
||||
openapi: "GET /api/v1/app-connections/azure-app-configuration"
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Update"
|
||||
openapi: "PATCH /api/v1/app-connections/azure-app-configuration/{connectionId}"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Azure App Configuration Connections must be updated through the Infisical UI.
|
||||
Check out the configuration docs for [Azure App Configuration Connections](/integrations/app-connections/azure-app-configuration) for a step-by-step
|
||||
guide.
|
||||
</Note>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Available"
|
||||
openapi: "GET /api/v1/app-connections/azure-key-vault/available"
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Create"
|
||||
openapi: "POST /api/v1/app-connections/azure-key-vault"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Azure Key Vault Connections must be created through the Infisical UI.
|
||||
Check out the configuration docs for [Azure Key Vault Connections](/integrations/app-connections/azure-key-vault) for a step-by-step
|
||||
guide.
|
||||
</Note>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Delete"
|
||||
openapi: "DELETE /api/v1/app-connections/azure-key-vault/{connectionId}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get by ID"
|
||||
openapi: "GET /api/v1/app-connections/azure-key-vault/{connectionId}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get by Name"
|
||||
openapi: "GET /api/v1/app-connections/azure-key-vault/connection-name/{connectionName}"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "List"
|
||||
openapi: "GET /api/v1/app-connections/azure-key-vault"
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Update"
|
||||
openapi: "PATCH /api/v1/app-connections/azure-key-vault/{connectionId}"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Azure Key Vault Connections must be updated through the Infisical UI.
|
||||
Check out the configuration docs for [Azure Key Vault Connections](/integrations/app-connections/azure-key-vault) for a step-by-step
|
||||
guide.
|
||||
</Note>
|
||||
@@ -80,7 +80,7 @@ Infisical currently only supports one method for connecting to Azure, which is O
|
||||
|
||||
</Step>
|
||||
<Step title="Grant Access">
|
||||
You will then be redirected to Azure to grant Infisical access to your Azure account (organization and repo privileges). Once granted,
|
||||
You will then be redirected to Azure to grant Infisical access to your Azure account. Once granted,
|
||||
you will redirect you back to Infisical's App Connections page. 
|
||||
</Step>
|
||||
|
||||
@@ -32,7 +32,7 @@ Infisical currently only supports one method for connecting to Azure, which is O
|
||||
</Step>
|
||||
<Step title="Assign API permissions to the application">
|
||||
|
||||
For the Azure Connection to work with both Key Vault, you need to assign multiple permissions to the application.
|
||||
For the Azure Connection to work with Key Vault, you need to assign multiple permissions to the application.
|
||||
|
||||
#### Azure Key Vault permissions
|
||||
|
||||
@@ -79,7 +79,7 @@ Infisical currently only supports one method for connecting to Azure, which is O
|
||||
|
||||
</Step>
|
||||
<Step title="Grant Access">
|
||||
You will then be redirected to Azure to grant Infisical access to your Azure account (organization and repo privileges). Once granted,
|
||||
You will then be redirected to Azure to grant Infisical access to your Azure account. Once granted,
|
||||
you will redirect you back to Infisical's App Connections page. 
|
||||
</Step>
|
||||
|
||||
@@ -12,8 +12,7 @@ description: "Learn how to configure an Azure App Configuration Sync for Infisic
|
||||
The Azure App Configuration Secret Sync requires the following permissions to be set on the user / service principal
|
||||
for Infisical to sync secrets to Azure App Configuration: `Read Key-Value`, `Write Key-Value`, `Delete Key-Value`.
|
||||
|
||||
Any role with these permissions would work such as the **App Configuration Data Owner** role. Alternatively, you can use the
|
||||
**App Configuration Data Reader** role for read-only access or **App Configuration Data Contributor** role for read/write access.
|
||||
Any role with these permissions would work such as the **App Configuration Data Owner** role. Alternatively, you can use the **App Configuration Data Contributor** role for read/write access.
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
@@ -44,11 +43,12 @@ description: "Learn how to configure an Azure App Configuration Sync for Infisic
|
||||
5. Configure the **Sync Options** to specify how secrets should be synced, then click **Next**.
|
||||

|
||||
|
||||
|
||||
- **Initial Sync Behavior**: Determines how Infisical should resolve the initial sync.
|
||||
- **Overwrite Destination Secrets**: Removes any secrets at the destination endpoint not present in Infisical.
|
||||
<Note>
|
||||
Azure App Configuration does not support importing secrets.
|
||||
</Note>
|
||||
- **Import Secrets (Prioritize Infisical)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Infisical over Secrets Manager when keys conflict.
|
||||
- **Import Secrets (Prioritize Azure App Configuration)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Secrets Manager over Infisical when keys conflict.
|
||||
|
||||
- **Auto-Sync Enabled**: If enabled, secrets will automatically be synced from the source location when changes occur. Disable to enforce manual syncing only.
|
||||
|
||||
6. Configure the **Details** of your Azure App Configuration Sync, then click **Next**.
|
||||
|
||||
@@ -49,9 +49,8 @@ description: "Learn how to configure a Azure Key Vault Sync for Infisical."
|
||||
|
||||
- **Initial Sync Behavior**: Determines how Infisical should resolve the initial sync.
|
||||
- **Overwrite Destination Secrets**: Removes any secrets at the destination endpoint not present in Infisical.
|
||||
<Note>
|
||||
Azure Key Vault does not support importing secrets.
|
||||
</Note>
|
||||
- **Import Secrets (Prioritize Infisical)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Infisical over Secrets Manager when keys conflict.
|
||||
- **Import Secrets (Prioritize Azure Key Vault)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Secrets Manager over Infisical when keys conflict.
|
||||
- **Auto-Sync Enabled**: If enabled, secrets will automatically be synced from the source location when changes occur. Disable to enforce manual syncing only.
|
||||
|
||||
6. Configure the **Details** of your Azure Key Vault Sync, then click **Next**.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Infisical",
|
||||
"openapi": "https://2eb781d275f5.ngrok.app/api/docs/json",
|
||||
"openapi": "https://app.infisical.com/api/docs/json",
|
||||
"logo": {
|
||||
"dark": "/logo/dark.svg",
|
||||
"light": "/logo/light.svg",
|
||||
@@ -847,6 +847,30 @@
|
||||
"api-reference/endpoints/app-connections/gcp/update",
|
||||
"api-reference/endpoints/app-connections/gcp/delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Azure Key Vault",
|
||||
"pages": [
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/list",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/available",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/get-by-id",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/get-by-name",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/create",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/update",
|
||||
"api-reference/endpoints/app-connections/azure-key-vault/delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Azure App Configuration",
|
||||
"pages": [
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/list",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/available",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/get-by-id",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/get-by-name",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/create",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/update",
|
||||
"api-reference/endpoints/app-connections/azure-app-configuration/delete"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
AzureAppConfigurationConnectionMethod,
|
||||
AzureKeyVaultConnectionMethod,
|
||||
GitHubConnectionMethod,
|
||||
TAzureAppConfigurationConnection,
|
||||
TAzureKeyVaultConnection,
|
||||
TGitHubConnection,
|
||||
useCreateAppConnection,
|
||||
@@ -15,20 +16,25 @@ import {
|
||||
} from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
type GithubFormData = Pick<TGitHubConnection, "name" | "method" | "description"> & {
|
||||
type BaseFormData = {
|
||||
returnUrl?: string;
|
||||
connectionId?: string;
|
||||
};
|
||||
|
||||
type AzureFormData = Pick<TGitHubConnection, "name" | "method" | "description"> & {
|
||||
returnUrl?: string;
|
||||
connectionId?: string;
|
||||
} & Pick<TAzureKeyVaultConnection["credentials"], "tenantId">;
|
||||
type GithubFormData = BaseFormData & Pick<TGitHubConnection, "name" | "method" | "description">;
|
||||
|
||||
type AzureKeyVaultFormData = BaseFormData &
|
||||
Pick<TAzureKeyVaultConnection, "name" | "method" | "description"> &
|
||||
Pick<TAzureKeyVaultConnection["credentials"], "tenantId">;
|
||||
|
||||
type AzureAppConfigurationFormData = BaseFormData &
|
||||
Pick<TAzureAppConfigurationConnection, "name" | "method" | "description"> &
|
||||
Pick<TAzureAppConfigurationConnection["credentials"], "tenantId">;
|
||||
|
||||
type FormDataMap = {
|
||||
[AppConnection.GitHub]: GithubFormData & { app: AppConnection.GitHub };
|
||||
[AppConnection.AzureKeyVault]: AzureFormData & { app: AppConnection.AzureKeyVault };
|
||||
[AppConnection.AzureAppConfiguration]: AzureFormData & {
|
||||
[AppConnection.AzureKeyVault]: AzureKeyVaultFormData & { app: AppConnection.AzureKeyVault };
|
||||
[AppConnection.AzureAppConfiguration]: AzureAppConfigurationFormData & {
|
||||
app: AppConnection.AzureAppConfiguration;
|
||||
};
|
||||
};
|
||||
@@ -105,7 +111,8 @@ export const OAuthCallbackPage = () => {
|
||||
app: AppConnection.AzureKeyVault,
|
||||
connectionId,
|
||||
credentials: {
|
||||
code: code as string
|
||||
code: code as string,
|
||||
tenantId: formData.tenantId
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -122,7 +129,7 @@ export const OAuthCallbackPage = () => {
|
||||
}
|
||||
} catch (err: any) {
|
||||
createNotification({
|
||||
title: `Failed to ${connectionId ? "update" : "add"} Azure Connection`,
|
||||
title: `Failed to ${connectionId ? "update" : "add"} Azure Key Vault Connection`,
|
||||
text: err?.message,
|
||||
type: "error"
|
||||
});
|
||||
@@ -152,7 +159,8 @@ export const OAuthCallbackPage = () => {
|
||||
app: AppConnection.AzureAppConfiguration,
|
||||
connectionId,
|
||||
credentials: {
|
||||
code: code as string
|
||||
code: code as string,
|
||||
tenantId: formData.tenantId
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -162,13 +170,14 @@ export const OAuthCallbackPage = () => {
|
||||
description,
|
||||
method: AzureAppConfigurationConnectionMethod.OAuth,
|
||||
credentials: {
|
||||
code: code as string
|
||||
code: code as string,
|
||||
tenantId: formData.tenantId
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err: any) {
|
||||
createNotification({
|
||||
title: `Failed to ${connectionId ? "update" : "add"} Azure Connection`,
|
||||
title: `Failed to ${connectionId ? "update" : "add"} Azure App Configuration Connection`,
|
||||
text: err?.message,
|
||||
type: "error"
|
||||
});
|
||||
|
||||
@@ -45,7 +45,8 @@ export const AzureAppConfigurationConnectionForm = ({ appConnection }: Props) =>
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: appConnection
|
||||
? {
|
||||
...appConnection
|
||||
...appConnection,
|
||||
tenantId: appConnection.credentials.tenantId
|
||||
}
|
||||
: {
|
||||
app: AppConnection.AzureAppConfiguration,
|
||||
|
||||
@@ -45,7 +45,8 @@ export const AzureKeyVaultConnectionForm = ({ appConnection }: Props) => {
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: appConnection
|
||||
? {
|
||||
...appConnection
|
||||
...appConnection,
|
||||
tenantId: appConnection.credentials.tenantId
|
||||
}
|
||||
: {
|
||||
app: AppConnection.AzureKeyVault,
|
||||
|
||||
Reference in New Issue
Block a user