Hello Ashish, Thanks for working on this feature. The overall approach looks good and the backward compatibility is appreciated.
I noticed that under "Further work" item #2, secret key/password rotation handling is listed on the roadmap. Since credential rotation is a common requirement in enterprise environments, it would be helpful to understand the expected behavior when a secret is updated in the external provider and how OFBiz instances will pick up those changes until full rotation support is available. Overall, this seems like a valuable addition to OFBiz and should help make the project more attractive for organizations adopting modern cloud and security practices. I will review the PR in more detail and share any additional feedback as needed. Kind Regards, Chandan Khandelwal On Wed, Jun 17, 2026 at 11:43 PM Ashish Vijaywargiya < [email protected]> wrote: > Hello Dev Members, > > I'd like to propose merging the changes from the following branches: > > "various-secret-manager" branch - > > https://github.com/ashishvijaywargiya/ofbiz-framework/tree/various-secret-manager > > "plugins-various-secret-manager" branch - > > https://github.com/ashishvijaywargiya/ofbiz-plugins/tree/plugins-various-secret-manager > > into trunk. > > I shared a detailed summary of the changes in my earlier email. In short, > it adds support for pluggable secret managers, a webtools "Encrypt Value" > screen with CSV bulk upload, and a configurable secret-value marker. It > will be an important feature for the Apache OFBiz project for > compliance-sensitive deployments(PCI-DSS, SOC2, etc.). > > The Secret Manager functionality is disabled by default, with the existing > passwords.properties/ENC(...) behavior used as the fallback when no > provider is configured. This means existing OFBiz installations will > continue to work exactly as before, with no changes required and no > breaking changes to current functionality. > > Unless there are concerns, I'm planning to merge these changes into trunk > over the coming weekend. Please take a look at the branch before then and > share any feedback or concerns. > > Here are the PRs for your kind reference: > > https://github.com/apache/ofbiz-framework/pull/1367 > > https://github.com/apache/ofbiz-plugins/pull/291 > > Thank you in advance for your help and review. > > I will also share the User Manual/ DIY(Do It Yourself) document for Secret > Managers setup on the OFBiz Wiki sometime in the next week. > > -- > Kind Regards, > Ashish Vijaywargiya > Vice President of Operations > *HotWax Systems* > *Enterprise open source experts* > http://www.hotwaxsystems.com > > > On Tue, Jun 16, 2026 at 8:58 PM Ashish Vijaywargiya < > [email protected]> wrote: > > > Hello Dev Members, > > > > I have updated the Secret Manager/Vault support in Apache OFBiz, and the > > following changes have been made in my forked version. > > > > Webtools Secret Manager Screen (EncryptValue) > > ---------------------------------------------- > > > > 1. Single-entry form with dual storage targets. > > > > The EncryptValue screen supports two storage targets via a radio button: > > SystemProperty entity and passwords.properties. For the SystemProperty > > target, Resource ID and Property ID are required; Lookup Key is optional > > and, when provided, wires the record to a remote secret provider. For the > > passwords.properties target, two sub-cases are supported: > > > > Case A (Lookup Key only): writes jdbc-password.<key>=ENC(...) to > > passwords.properties, covering the entityengine.xml jdbc-password-lookup > > use case. > > > > Case B (all four fields): writes <key>=ENC(...) to passwords.properties, > > sets <propertyId>=LOOKUP(<key>) in the source .properties file on disk, > and > > flushes the OFBiz property cache — no server restart needed. > > > > 2. Dynamic labels based on target selection. > > > > Field labels update dynamically when the target radio button is switched. > > Selecting SystemProperty shows "System Resource ID (SystemProperty)" and > > "System Property ID (SystemProperty)"; selecting passwords.properties > shows > > "Resource ID (Property File)" and "Property ID (Property File)". This > > avoids confusion about which entity or file a field refers to. > > > > 3. Form field persistence on validation errors. > > > > When a submission fails validation, the radio button selection, > > systemResourceId, systemPropertyId, and lookupKey fields are > pre-populated > > with the values the user entered. The secretValue field is intentionally > > cleared on error so the plain-text password is never re-rendered in the > > page. > > > > 4. Stale lookup key cleanup. > > > > When Case B is used and the user changes the lookupKey for a property > that > > already had a LOOKUP(...) reference in the source .properties file, the > old > > key's entry is automatically removed from passwords.properties before the > > new one is written, preventing orphaned encrypted entries. > > > > 5. CSV bulk upload with security pre-scan. > > > > A CSV upload path allows multiple secrets to be created in one operation > > (target, systemResourceId, systemPropertyId, lookupKey, secretValue > > columns). The entire file is validated before any writes occur — the file > > is rejected as a whole if any row contains unknown targets, invalid > > identifier characters (only letters, digits, dots, hyphens, and > underscores > > are allowed in identifier fields), path traversal sequences (..), or if > the > > file exceeds 512 KB or 500 rows. The whole-file content scan uses OFBiz's > > existing SecuredUpload.isValidTextContent() sandboxing mechanism to block > > null bytes and control characters at the Unicode code-point level. > > > > 6. Input validation on form and CSV upload. > > > > Server-side guards reject a LOOKUP(...) marker typed into the lookupKey > > field and an ENC(...) prefix typed into the secretValue field, on both > the > > single-entry form and the CSV bulk-upload path. A matching client-side > > JavaScript validator highlights the offending field and shows an inline > > error before the form is even submitted, preventing accidental misuse. > > > > Marker and Resolver Changes > > ---------------------------- > > > > 7. Configurable secret marker (default: LOOKUP). > > > > The marker used to identify secret references in property values > > (previously hardcoded as SECRET) is now configurable via > > secret.value.marker in security.properties. The default has been changed > to > > LOOKUP, which aligns naturally with the existing systemPropertyLookup > field > > name in the SystemProperty entity and the jdbc-password-lookup attribute > in > > entityengine.xml. Admins can change it to any uppercase word if it > collides > > with an existing property value. > > > > 8. Plain key in SystemProperty.systemPropertyLookup. > > > > Previously, the field stored a wrapped value like LOOKUP(smtp-key). It > now > > stores the plain key (smtp-key) directly, since the field name already > > implies lookup semantics. EntityUtilProperties now calls the new > > SecretValueResolver.resolveKey(String) method to resolve the raw key > > without needing a marker wrapper. Marker-based resolution (LOOKUP(key)) > in > > .properties files remains unchanged. > > > > 9. Marker config moved to security.properties. > > > > secret.value.marker and secret.cache.ttl.seconds are now documented in > > security.properties rather than general.properties, which is the more > > appropriate home for secret-management configuration. > > > > 10. Fixed marker coupling in SecretManagerServices. > > > > All hardcoded "SECRET(" string literals in the writer and parser have > been > > replaced with SecretValueResolver.MARKER_NAME (now public), ensuring the > > writer and resolver always stay in sync when an admin changes the > > configured marker. > > > > 11. SecretValueResolver refactored. > > > > Cache and provider logic extracted into a new public resolveKey(String > > key) method; resolve(String) now delegates to it after parsing the > marker. > > This eliminates duplicated cache logic and gives callers a clean API for > > direct raw-key resolution without constructing a synthetic LOOKUP(...) > > wrapper. > > > > If you wish to review the code changes, please review the URL below: > > > > > https://github.com/ashishvijaywargiya/ofbiz-framework/tree/various-secret-manager > > > > Thank you. > > > > PS: I noticed that my previous email had formatting issues. Sharing it > > again. > > > > -- > > Kind Regards, > > Ashish Vijaywargiya > > Vice President of Operations > > *HotWax Systems* > > *Enterprise open source experts* > > http://www.hotwaxsystems.com > > > > > > > > On Mon, Jun 15, 2026 at 5:35 PM Ashish Vijaywargiya < > > [email protected]> wrote: > > > >> Dear Dev Community, > >> > >> Over the past few days, I've been working on adding optional Secret > >> Manager/Vault integration to Apache OFBiz, and I'd like to share it with > >> the Dev list for feedback before taking it further. > >> > >> The goal is simple: today, DB passwords, JWT/login keys, and various > >> gateway credentials mostly live as plain text in .properties files or in > >> the SystemProperty entity, which is a real concern for production and > >> compliance-sensitive deployments (PCI-DSS, SOC2, etc.). This work gives > >> adopters a way to back those values with an external secret manager of > >> their choice, while leaving everything else untouched. > >> > >> To make this happen, I've added six provider plugins, each implementing > a > >> small SecretProvider SPI: AWS Secrets Manager, GCP(Google Cloud > Platform) > >> Secret Manager, Azure Key Vault, HashiCorp Vault by IBM, 1Password, and > >> Bitwarden Secrets Manager. > >> > >> On the framework side, the key additions are a > >> SecretProvider/SecretProviderFactory/FallbackSecretProvider setup in > >> framework/base, a ConfigCryptoUtil class for local AES-256-GCM > encryption > >> of values as ENC(...) keyed by OFBIZ_MASTER_KEY, and a > SecretValueResolver > >> that resolves any SECRET(key) reference in a property file or > >> SystemProperty row through the configured provider, with a configurable > >> cache TTL. > >> > >> entityengine.xml now supports jdbc-password-lookup on inline-jdbc > >> elements, which is resolved via SecretProviderFactory at startup, so > the DB > >> password never needs to appear in entityengine.xml at all. Previously, > >> passwords.properties only supported plain-text values; now those same > >> entries can be encrypted at rest using a new generateDBPassword gradle > >> task, which prompts for the value via masked stdin and writes out the > >> ENC(...) form, so no secret ever needs to be typed on the command line > or > >> land in shell history. > >> > >> SystemProperty also has a new systemPropertyLookup field so individual > >> properties can opt into secret-manager resolution. > >> > >> I've also added unit tests (e.g. SecretValueResolverTest) covering plain > >> values, ENC(...) values, cached lookups, and provider failure/fallback > >> behavior, plus a generateDBPassword gradle task with the same > masked-prompt > >> approach for setting up the local DB password. > >> > >> On the impact to existing implementations/configurations, this is fully > >> backward-compatible and opt-in only: > >> > >> 1) passwords.properties / entityengine.xml – Existing plain-text > >> jdbc-password values continue to work exactly as before. Sites can > >> optionally migrate to ENC(...) (AES-256-GCM, keyed by OFBIZ_MASTER_KEY, > >> generated via generateEncryptedSecret) or to a jdbc-password-lookup key > >> resolved via a secret manager, but if they do nothing, behavior is > >> unchanged. > >> > >> 2) SystemProperty – The new systemPropertyLookup field is additive. > >> Existing rows with only systemPropertyValue (plain or ENC(...)) behave > as > >> they do today. A site only sees secret-manager resolution if it > explicitly > >> sets systemPropertyLookup on a row. > >> > >> 3) Secret managers – All six provider plugins (AWS, Azure, HashiCorp, > >> GCP, 1Password, Bitwarden) are optional. None are enabled by default, > with > >> no new mandatory dependencies in core. You can enable one > plugin/provider > >> at a time by changing values in the respective plugin's > ofbiz-component.xml > >> file. > >> > >> 4) Fallback chain – Lookup → remote secret manager (if configured) → > >> local ENC(...)/plain value. If the remote provider is unreachable or > >> unconfigured, OFBiz falls back to the existing file/entity-based value, > >> resulting in no new failure mode for sites that do not adopt this > >> functionality. > >> > >> 5) Testing – The new resolver, crypto utility, and provider fallback > >> logic are all covered by unit tests, so existing config-loading paths > >> remain verified alongside the new optional ones. > >> > >> Here is the source code for your kind review: > >> > >> Framework related changes: > >> > >> > https://github.com/ashishvijaywargiya/ofbiz-framework/tree/various-secret-manager > >> > >> Plugins related changes: > >> > >> > https://github.com/ashishvijaywargiya/ofbiz-plugins/tree/plugins-various-secret-manager > >> > >> Further work: > >> > >> 1) I am working on adding an Admin Screen in webtools where a user can > >> create secrets either in the SystemProperty entity or the > password.properties > >> file. I will provide an option where a user can create multiple secrets > >> in a CSV file and upload them in bulk. The AES algorithm will encrypt > >> the password and put it either in SystemProperty or password.properties > >> file. > >> > >> 2) Another item on the roadmap is secret key/password rotation handling > >> from the remote service, with the corresponding values updated in > >> passwords.properties or the relevant SystemProperty records. Many > >> third-party services expect support for secret key rotation at regular > >> intervals for security reasons. For now, we won't provide support for > >> database password rotation in the Secret Manager, since that would also > >> require handling of the user password rotation on the database side > itself > >> (MySQL, PostgreSQL, etc.). > >> > >> 3) Merge the generateDBPassword and generateEncryptedSecret Gradle tasks > >> and make them one, i.e generateEncryptedSecret. > >> > >> Please let me know your thoughts/feedback on this work. I will quickly > accommodate > >> your thoughts/ideas in the current implementation. > >> > >> I'm planning to commit the current work to the Apache OFBiz > >> project(trunk) in the next few days. > >> > >> Thank you. > >> > >> -- > >> Kind Regards, > >> Ashish Vijaywargiya > >> Vice President of Operations > >> *HotWax Systems* > >> *Enterprise open source experts* > >> http://www.hotwaxsystems.com > >> > >> >
