Hello Chandan,

Thank you for sharing your thoughts.

Here's how rotation is handled today, and the key assumptions behind it:

- Each vault provider plugin caches secrets for a configurable TTL (default
1 hour); once it expires, the next lookup re-fetches from the vault
automatically.

- For SystemProperty-backed secrets, an opt-in hourly job
(secret.rotation.autosync.enabled, off by default) checks the vault and
writes back any changed value automatically — no admin action needed.

- An admin can also force an immediate sync anytime via "Flush Secret
Cache" or "Sync Now" in the EncryptValue screen.

Key assumptions:

- The vault is the source of truth, one-way. We never write back to the
vault, so a local edit to a vault-backed value will be overwritten on the
next sync.

- Scope is SystemProperty only. passwords.properties (including DB
passwords) stays manual-only — DB password rotation also needs a
coordinated change on the database side, which is out of scope here.

- One failing key during a sync doesn't block the rest — failures are
logged and the batch continues.

This covers the common case (rotated credentials picked up automatically,
bounded by the TTL) without claiming full bidirectional secret lifecycle
management.

For more details, please see my recent commit:
https://github.com/apache/ofbiz-framework/commit/6da29791891a408d533e541e392df415361b7b51

Looking forward to your further feedback.

--
Kind Regards,
Ashish Vijaywargiya
Vice President of Operations
*HotWax Systems*
*Enterprise open source experts*
http://www.hotwaxsystems.com



On Thu, Jun 18, 2026 at 4:07 PM Chandan Khandelwal <
[email protected]> wrote:

> 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
> > >>
> > >>
> >
>

Reply via email to