diff --git a/.github/workflows/keyfactor-starter-workflow.yml b/.github/workflows/keyfactor-starter-workflow.yml index ca27bb4..3c92a1d 100644 --- a/.github/workflows/keyfactor-starter-workflow.yml +++ b/.github/workflows/keyfactor-starter-workflow.yml @@ -45,9 +45,3 @@ jobs: secrets: token: ${{ secrets.SDK_SYNC_PAT }} - call-update-store-types-workflow: - needs: get-manifest-properties - if: needs.get-manifest-properties.outputs.integration_type == 'orchestrator' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') - uses: Keyfactor/actions/.github/workflows/update-store-types.yml@main - secrets: - token: ${{ secrets.UPDATE_STORE_TYPES }} diff --git a/.gitignore b/.gitignore index 600e2bf..fd963ea 100644 --- a/.gitignore +++ b/.gitignore @@ -345,4 +345,6 @@ healthchecksdb /privkey.pem /key.pem /cert.pem -/cert.csr \ No newline at end of file +/cert.csr + +*/C: \ No newline at end of file diff --git a/AzureEnterpriseApplicationOrchestrator/Client/AzureGraphJob.cs b/AzureEnterpriseApplicationOrchestrator/Client/AzureGraphJob.cs index 1808215..e7779b3 100644 --- a/AzureEnterpriseApplicationOrchestrator/Client/AzureGraphJob.cs +++ b/AzureEnterpriseApplicationOrchestrator/Client/AzureGraphJob.cs @@ -84,11 +84,11 @@ private void Initialize(CertificateStore details) } else { - throw new System.Exception("Invalid type: " + typeof(T) + ". Must be ServicePrincipal or Application."); + throw new Exception("Invalid type: " + typeof(T) + ". Must be ServicePrincipal or Application."); } } - protected void Initialize(DiscoveryJobConfiguration config) + private void Initialize(DiscoveryJobConfiguration config) { ILogger logger = LogHandler.GetReflectedClassLogger(this); logger.LogDebug($"Discovery Job Configuration: {JsonConvert.SerializeObject(config)}"); @@ -100,13 +100,19 @@ protected void Initialize(DiscoveryJobConfiguration config) ClientSecret = config.ServerPassword }; - if (config.ServerUsername == "OAuth/SAML (ServicePrincipal)") + if (typeof(T) == typeof(ServicePrincipal)) { + _logger.LogDebug("Initializing AzureServicePrincipalClient"); Client = new AzureServicePrincipalClient(azureProperties); - } else // Else case is "Authentication (Application)" + } else if (typeof(T) == typeof(Application)) { + _logger.LogDebug("Initializing AzureApplicationClient"); Client = new AzureApplicationClient(azureProperties); } + else + { + throw new Exception("Invalid type: " + typeof(T) + ". Must be ServicePrincipal or Application."); + } } protected JobResult ProcessInventoryJob(InventoryJobConfiguration config, SubmitInventoryUpdate cb) @@ -161,7 +167,7 @@ protected JobResult ProcessManagementJob(ManagementJobConfiguration config) _logger.LogDebug("Adding certificate to {Type}", Client.TypeString); // Ensure that the password is provided. - if (string.IsNullOrWhiteSpace(config.JobCertificate.PrivateKeyPassword)) + if (typeof(T) == typeof(ServicePrincipal) && string.IsNullOrWhiteSpace(config.JobCertificate.PrivateKeyPassword)) { throw new Exception("Private key password must be provided."); } @@ -182,6 +188,11 @@ protected JobResult ProcessManagementJob(ManagementJobConfiguration config) _logger.LogDebug("Overwrite is enabled, replacing certificate in {Type} called \"{Alias}\"", Client.TypeString, config.JobCertificate.Alias); Client.ReplaceCertificate(config.JobCertificate.Alias, config.JobCertificate.Contents, config.JobCertificate.PrivateKeyPassword); } + else if (typeof(T) == typeof(ServicePrincipal) && !config.Overwrite) + { + throw new Exception( + "Cannot perform Management Add for ServicePrincipal without overwrite enabled."); + } else { _logger.LogDebug("Adding certificate to {Type}", Client.TypeString); diff --git a/README.md b/README.md index eaa6cdd..2fe1b62 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ The Azure Application and Enterprise Application Orchestrator extension acts as #### Integration status: Prototype - Demonstration quality. Not for use in customer environments. + ## About the Keyfactor Universal Orchestrator Extension This repository contains a Universal Orchestrator Extension which is a plugin to the Keyfactor Universal Orchestrator. Within the Keyfactor Platform, Orchestrators are used to manage “certificate stores” — collections of certificates and roots of trust that are found within and used by various applications. @@ -13,7 +14,6 @@ The Universal Orchestrator is part of the Keyfactor software distribution and is The Universal Orchestrator is the successor to the Windows Orchestrator. This Orchestrator Extension plugin only works with the Universal Orchestrator and does not work with the Windows Orchestrator. - ## Support for Azure Application and Enterprise Application Orchestrator Azure Application and Enterprise Application Orchestrator is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket with your Keyfactor representative. @@ -21,7 +21,6 @@ Azure Application and Enterprise Application Orchestrator is supported by Keyfac ###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. - --- @@ -224,13 +223,13 @@ To schedule a discovery job, select the _Locations_ drop down, select _Certifica Azure App Registrations (Applications) and Azure Enterprise Applications (Service Principals) are linked by the same Application ID, the configuration for both `AzureApp` and `AzureSP` is the same. The following table describes the configuration options for the Azure App Registration (Application) and Azure Enterprise Application (Service Principal) store types: -| Parameter | Value | Description | -|-----------------|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| -| Category | 'Azure Application (Auth)' or `Azure Service Principal (SSO/SAML)` | Name of the store type | -| Client Machine | Azure Tenant ID | The Azure Tenant ID | -| Store Path | Application Gateway resource ID | Azure Application ID of the App Registration (Application) or Enterprise Application (Enterprise Application) | -| Server Username | Application ID | Application ID of the service principal created to authenticate to the Graph API | -| Server Password | Client Secret | Secret value of the service principal created to authenticate to the Graph API | +| Parameter | Value | Description | +|-----------------|--------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| +| Category | `Azure Application (Auth)` or `Azure Service Principal (SSO/SAML)` | Name of the store type | +| Client Machine | Azure Tenant ID | The Azure Tenant ID | +| Store Path | Application Gateway resource ID | Azure Application ID of the App Registration (Application) or Enterprise Application (Enterprise Application) | +| Server Username | Application ID | Application ID of the service principal created to authenticate to the Graph API | +| Server Password | Client Secret | Secret value of the service principal created to authenticate to the Graph API | For the discovery job, populate the _Directories to search_ with any value. The extension will discover all Application Gateways accessible by the Azure Service Principal. diff --git a/integration-manifest.json b/integration-manifest.json index f7837e4..ae8e88b 100644 --- a/integration-manifest.json +++ b/integration-manifest.json @@ -27,7 +27,118 @@ "supportsReenrollment": false, "supportsInventory": true, "platformSupport": "Unused" - } + }, + "store_types": [ + { + "Name": "Azure Application (Auth)", + "ShortName": "AzureApp", + "Capability": "AzureApp", + "LocalStore": false, + "SupportedOperations": { + "Add": true, + "Create": false, + "Discovery": true, + "Enrollment": false, + "Remove": true + }, + "Properties": [ + { + "StoreTypeId": 279, + "Name": "ServerUsername", + "DisplayName": "Server Username", + "Type": "Secret", + "DependsOn": "", + "DefaultValue": "", + "Required": false + }, + { + "StoreTypeId": 279, + "Name": "ServerPassword", + "DisplayName": "Server Password", + "Type": "Secret", + "DependsOn": "", + "DefaultValue": "", + "Required": false + }, + { + "StoreTypeId": 279, + "Name": "ServerUseSsl", + "DisplayName": "Use SSL", + "Type": "Bool", + "DependsOn": "", + "DefaultValue": "true", + "Required": true + } + ], + "EntryParameters": [], + "PasswordOptions": { + "EntrySupported": false, + "StoreRequired": false, + "Style": "Default" + }, + "PrivateKeyAllowed": "Forbidden", + "JobProperties": [], + "ServerRequired": true, + "PowerShell": false, + "BlueprintAllowed": false, + "CustomAliasAllowed": "Required" + }, + { + "Name": "Azure Service Principal (SSO/SAML)", + "ShortName": "AzureSP", + "Capability": "AzureSP", + "LocalStore": false, + "SupportedOperations": { + "Add": true, + "Create": false, + "Discovery": true, + "Enrollment": false, + "Remove": true + }, + "Properties": [ + { + "StoreTypeId": 280, + "Name": "ServerUsername", + "DisplayName": "Server Username", + "Type": "Secret", + "DependsOn": "", + "DefaultValue": "", + "Required": false + }, + { + "StoreTypeId": 280, + "Name": "ServerPassword", + "DisplayName": "Server Password", + "Type": "Secret", + "DependsOn": "", + "DefaultValue": "", + "Required": false + }, + { + "StoreTypeId": 280, + "Name": "ServerUseSsl", + "DisplayName": "Use SSL", + "Type": "Bool", + "DependsOn": "", + "DefaultValue": "true", + "Required": true + } + ], + "EntryParameters": [], + "PasswordOptions": { + "EntrySupported": false, + "StoreRequired": false, + "Style": "Default" + }, + "PrivateKeyAllowed": "Required", + "JobProperties": [], + "ServerRequired": true, + "PowerShell": false, + "BlueprintAllowed": false, + "CustomAliasAllowed": "Required" + } + ] } - } + }, + "release_dir": "" } diff --git a/readme_source.md b/readme_source.md index f8ce3bc..46b895a 100644 --- a/readme_source.md +++ b/readme_source.md @@ -176,12 +176,12 @@ To schedule a discovery job, select the _Locations_ drop down, select _Certifica Azure App Registrations (Applications) and Azure Enterprise Applications (Service Principals) are linked by the same Application ID, the configuration for both `AzureApp` and `AzureSP` is the same. The following table describes the configuration options for the Azure App Registration (Application) and Azure Enterprise Application (Service Principal) store types: -| Parameter | Value | Description | -|-----------------|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| -| Category | 'Azure Application (Auth)' or `Azure Service Principal (SSO/SAML)` | Name of the store type | -| Client Machine | Azure Tenant ID | The Azure Tenant ID | -| Store Path | Application Gateway resource ID | Azure Application ID of the App Registration (Application) or Enterprise Application (Enterprise Application) | -| Server Username | Application ID | Application ID of the service principal created to authenticate to the Graph API | -| Server Password | Client Secret | Secret value of the service principal created to authenticate to the Graph API | +| Parameter | Value | Description | +|-----------------|--------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| +| Category | `Azure Application (Auth)` or `Azure Service Principal (SSO/SAML)` | Name of the store type | +| Client Machine | Azure Tenant ID | The Azure Tenant ID | +| Store Path | Application Gateway resource ID | Azure Application ID of the App Registration (Application) or Enterprise Application (Enterprise Application) | +| Server Username | Application ID | Application ID of the service principal created to authenticate to the Graph API | +| Server Password | Client Secret | Secret value of the service principal created to authenticate to the Graph API | For the discovery job, populate the _Directories to search_ with any value. The extension will discover all Application Gateways accessible by the Azure Service Principal. \ No newline at end of file