From 254665162bbab6a78f2675ee8f0c6eaf40439f45 Mon Sep 17 00:00:00 2001 From: Adam Guzzo Date: Tue, 9 Jun 2026 15:11:26 -0400 Subject: [PATCH 1/8] Code formatting fixes --- README.md | 4 +- integration-manifest.json | 6 +-- .../PasswordManagerAPI.cs | 40 +++++++++---------- password-manager-pro-pam/PasswordProPam.cs | 17 +++++--- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 9448e8d..94869d6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

-Integration Status: prototype +Integration Status: production Release Issues GitHub Downloads (all assets, all releases) @@ -69,7 +69,7 @@ Select the exported .cer file and complete the wizard If PMP is running on the same machine as the extension and you are connecting via localhost, the certificate's hostname will not match. This is expected and is handled automatically by the extension; no additional configuration is required. ## Support -The Password Manager Pro Pam Provider is open source and there is **no SLA**. Keyfactor will address issues as resources become available. Keyfactor customers may request escalation by opening up a support ticket through their Keyfactor representative. +The Password Manager Pro Pam Provider is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com. > 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. diff --git a/integration-manifest.json b/integration-manifest.json index ef27d3b..fad658c 100644 --- a/integration-manifest.json +++ b/integration-manifest.json @@ -1,10 +1,10 @@ { - "$schema": "https://keyfactor.github.io/integration-manifest-schema.json", + "$schema": "https://keyfactor.github.io/v2/integration-manifest-schema.json", "integration_type": "pam", "name": "Password Manager Pro Pam Provider", - "status": "prototype", + "status": "production", "description": "The Password Manager Pro PAM extension allows for the retrieval of account usernames and passwords", - "support_level": "kf-community", + "support_level": "kf-supported", "link_github": true, "update_catalog": true, "release_dir": "password-manager-pro-pam/bin/Release", diff --git a/password-manager-pro-pam/PasswordManagerAPI.cs b/password-manager-pro-pam/PasswordManagerAPI.cs index d3450ad..48a6f50 100644 --- a/password-manager-pro-pam/PasswordManagerAPI.cs +++ b/password-manager-pro-pam/PasswordManagerAPI.cs @@ -28,16 +28,14 @@ namespace Keyfactor.Extensions.Pam.PasswordManagerPro { internal class PasswordManagerAPI { - internal static string GetResourceAccountID(string name, Dictionary instanceParameters, Uri host, string Authtoken) + internal static AccountResourceLookup GetResourceAccountID(string name, Dictionary instanceParameters, Uri host, string Authtoken) { ILogger logger = LogHandler.GetClassLogger(); - logger.LogDebug($"PAM Provider {name} - Bazinga."); + logger.LogDebug($"PAM Provider {name} - Getting resource and account ids."); HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/getResourceIdAccountId?RESOURCENAME={instanceParameters["resourceName"]}&ACCOUNTNAME={instanceParameters["accountName"]}"); req.Method = "GET"; req.Headers.Add("AUTHTOKEN", Authtoken); - //req.Headers.Add("RESOURCENAME", instanceParameters["resourceName"]); - //req.Headers.Add("ACCOUNTNAME", instanceParameters["accountName"]); logger.LogDebug($"PAM Provider {name} - requesting secret located at {req.RequestUri}"); req.ServerCertificateValidationCallback = (sender, cert, chain, errors) => @@ -46,14 +44,6 @@ internal static string GetResourceAccountID(string name, Dictionary(strResponse); if (response.Operation.Result.Status != "Success") - throw new Exception($"PAM Provider {name} - PMP API error: {response.Operation.Result.Message}"); + throw new PasswordManagerProException($"PAM Provider {name} - PMP API error: {response.Operation.Result.Message}"); - string resourceId = response.Operation.Details["RESOURCEID"]; - string accountId = response.Operation.Details["ACCOUNTID"]; + AccountResourceLookup accountResources = new AccountResourceLookup(); - logger.LogDebug($"PAM Provider {name} - resolved RESOURCEID and ACCOUNTID"); - return $"{resourceId},{accountId}"; + accountResources.ResourceId = response.Operation.Details["RESOURCEID"]; + accountResources.AccountId = response.Operation.Details["ACCOUNTID"]; + + logger.LogDebug($"PAM Provider {name} - resolved RESOURCEID: {accountResources.ResourceId} and ACCOUNTID: {accountResources.AccountId}"); + return accountResources; } internal static string GetPasswordManagerValue(string name, Dictionary instanceParameters, Uri host, string Authtoken) @@ -95,10 +87,9 @@ internal static string GetPasswordManagerValue(string name, Dictionary(); logger.LogDebug($"PAM Provider {name} - Beginning secret fetch."); - string idString = GetResourceAccountID(name, instanceParameters, host, Authtoken); - string[] ids = idString.Split(','); + AccountResourceLookup accountIds = GetResourceAccountID(name, instanceParameters, host, Authtoken); - HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/{ids[0]}/accounts/{ids[1]}/password"); + HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/{accountIds.ResourceId}/accounts/{accountIds.AccountId}/password"); req.Method = "GET"; req.Headers.Add("AUTHTOKEN", Authtoken); logger.LogDebug($"PAM Provider {name} - requesting secret located at {req.RequestUri}"); @@ -120,7 +111,7 @@ internal static string GetPasswordManagerValue(string name, Dictionary "Password-Manager-Pro"; @@ -31,21 +35,22 @@ public class PasswordManagerPAM : IPAMProvider public string GetPassword(Dictionary instanceParameters, Dictionary initializationInfo) { ILogger logger = LogHandler.GetClassLogger(); - logger.LogDebug("Password Manager Pro Starting"); logger.MethodEntry(LogLevel.Trace); - if (instanceParameters["LookupType"].Equals("Username")) + logger.LogDebug("Password Manager Pro Starting"); + string lookupType = instanceParameters["LookupType"].Trim(); + if (lookupType.Equals("username", StringComparison.OrdinalIgnoreCase)) { - logger.LogDebug($"Returning: {instanceParameters["accountName"]}"); + logger.LogDebug("Returning Username"); return instanceParameters["accountName"]; } - else if (instanceParameters["LookupType"].Equals("Password")) + else if (lookupType.Equals("password", StringComparison.OrdinalIgnoreCase)) { return PasswordManagerAPI.GetPasswordManagerValue(Name, instanceParameters, new Uri(initializationInfo["Host"]), initializationInfo["Authtoken"]); } else { - logger.LogError("PAM extension Lookup type parameter must be defined. Options: Username, Password"); - return "NULL"; + logger.LogError($"PAM extension Lookup type {instanceParameters["LookupType"]} is invalid. Options: Username, Password"); + throw new PasswordManagerProException($"PAM extension Lookup type {instanceParameters["LookupType"]} is invalid. Options: Username, Password"); } } } From 224dc5ac642e080a649071c806def04a72466412 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 19:13:04 +0000 Subject: [PATCH 2/8] docs: auto-generate README and documentation [skip ci] --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 94869d6..a3589c9 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@

Integration Status: production -Release -Issues -GitHub Downloads (all assets, all releases) +Release +Issues +GitHub Downloads (all assets, all releases)

@@ -105,7 +105,7 @@ Create the required PAM Types in the connected Command platform. ```shell # Password-Manager-Pro -kfutil pam-types create -r password-manager-pro -n Password-Manager-Pro +kfutil pam-types create -r password-manager-pro-pam -n Password-Manager-Pro ``` ##### Using the API From 7e119781a5a39b22b5e7191b85ed49b7d719a6c2 Mon Sep 17 00:00:00 2001 From: Adam Guzzo Date: Tue, 9 Jun 2026 15:27:10 -0400 Subject: [PATCH 3/8] Workflow fix --- docsource/overview.md | 3 ++- password-manager-pro-pam.sln | 25 +++++++++++++++++++ password-manager-pro-pam.slnx | 3 +++ .../PasswordManagerAPI.cs | 2 +- password-manager-pro-pam/PasswordProPam.cs | 2 +- .../password-manager-pro-pam.slnx | 3 --- 6 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 password-manager-pro-pam.sln create mode 100644 password-manager-pro-pam.slnx delete mode 100644 password-manager-pro-pam/password-manager-pro-pam.slnx diff --git a/docsource/overview.md b/docsource/overview.md index b82d496..d11f9a1 100644 --- a/docsource/overview.md +++ b/docsource/overview.md @@ -4,7 +4,8 @@ The Password Manager Pro PAM Provider allows for the retrieval of stored account ## Installation and Configuration #### In ManageEngine Password Manager Pro -When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the ip of your KeyFactor Command instance. +When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the IP of your Keyfactor Command instance. + After ensuring the API User exists and has access to the resource and account you wish to retrieve from PMP, you can use the resource's name (the "Resource Name") and the account name (the "Account Name") to retrieve credentials via the PMP PAM Provider extension. #### On the Universal Orchestrator diff --git a/password-manager-pro-pam.sln b/password-manager-pro-pam.sln new file mode 100644 index 0000000..31132ec --- /dev/null +++ b/password-manager-pro-pam.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31515.178 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "password-manager-pro-pam", "password-manager-pro-pam\password-manager-pro-pam.csproj", "{00AF414E-AB66-42F6-9D02-597AB6A0DF63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {924718C4-B817-479F-B799-87E6F1A6863C} + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/password-manager-pro-pam.slnx b/password-manager-pro-pam.slnx new file mode 100644 index 0000000..976c90e --- /dev/null +++ b/password-manager-pro-pam.slnx @@ -0,0 +1,3 @@ + + + diff --git a/password-manager-pro-pam/PasswordManagerAPI.cs b/password-manager-pro-pam/PasswordManagerAPI.cs index 48a6f50..dfeca46 100644 --- a/password-manager-pro-pam/PasswordManagerAPI.cs +++ b/password-manager-pro-pam/PasswordManagerAPI.cs @@ -1,4 +1,4 @@ -// Copyright 2023 Keyfactor +// Copyright 2026 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/password-manager-pro-pam/PasswordProPam.cs b/password-manager-pro-pam/PasswordProPam.cs index 36c1c47..77b6443 100644 --- a/password-manager-pro-pam/PasswordProPam.cs +++ b/password-manager-pro-pam/PasswordProPam.cs @@ -1,4 +1,4 @@ -// Copyright 2023 Keyfactor +// Copyright 2026 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/password-manager-pro-pam/password-manager-pro-pam.slnx b/password-manager-pro-pam/password-manager-pro-pam.slnx deleted file mode 100644 index 0ab8719..0000000 --- a/password-manager-pro-pam/password-manager-pro-pam.slnx +++ /dev/null @@ -1,3 +0,0 @@ - - - From b22d3c14a96d1d5ee7afcb3f645cfee7abd76299 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jun 2026 19:28:09 +0000 Subject: [PATCH 4/8] docs: auto-generate README and documentation [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3589c9..54fb435 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ The Password Manager Pro PAM Provider allows for the retrieval of stored account ## Installation and Configuration #### In ManageEngine Password Manager Pro -When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the ip of your KeyFactor Command instance. +When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the IP of your Keyfactor Command instance. + After ensuring the API User exists and has access to the resource and account you wish to retrieve from PMP, you can use the resource's name (the "Resource Name") and the account name (the "Account Name") to retrieve credentials via the PMP PAM Provider extension. #### On the Universal Orchestrator From 6b0bc44c43cc7f2df5b84cb6a7a5cddf366d5937 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Aug 2026 11:49:46 +0000 Subject: [PATCH 5/8] docs: auto-generate README and documentation [skip ci] --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9448e8d..0242a4a 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@

Integration Status: prototype -Release -Issues -GitHub Downloads (all assets, all releases) +Release +Issues +GitHub Downloads (all assets, all releases)

@@ -105,7 +105,7 @@ Create the required PAM Types in the connected Command platform. ```shell # Password-Manager-Pro -kfutil pam-types create -r password-manager-pro -n Password-Manager-Pro +kfutil pam-types create -r password-manager-pro-pam -n Password-Manager-Pro ``` ##### Using the API From ad877766314193d8e3bab83ee7544626fe79c244 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Aug 2026 11:51:50 +0000 Subject: [PATCH 6/8] docs: auto-generate README and documentation [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 998849d..54fb435 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

-Integration Status: production +Integration Status: production Release Issues GitHub Downloads (all assets, all releases) From 3845c1e13ffb35cd1a58ebb791c7a224c4fc1044 Mon Sep 17 00:00:00 2001 From: Adam Guzzo Date: Mon, 10 Aug 2026 08:09:02 -0400 Subject: [PATCH 7/8] Create CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e577aae --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +v1.0.0 +- Initial Version From 8bdbab3737d1432c8adae8238ad947138bf4372b Mon Sep 17 00:00:00 2001 From: Morgan Gangwere <470584+indrora@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:15:57 -0700 Subject: [PATCH 8/8] Update integration-manifest.json --- integration-manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-manifest.json b/integration-manifest.json index fad658c..4afb03f 100644 --- a/integration-manifest.json +++ b/integration-manifest.json @@ -1,7 +1,7 @@ { "$schema": "https://keyfactor.github.io/v2/integration-manifest-schema.json", - "integration_type": "pam", "name": "Password Manager Pro Pam Provider", + "integration_type": "pam", "status": "production", "description": "The Password Manager Pro PAM extension allows for the retrieval of account usernames and passwords", "support_level": "kf-supported", @@ -61,4 +61,4 @@ } } } -} \ No newline at end of file +}