Enable self credentials rotation for static roles#212
Open
jadeidev wants to merge 47 commits intohashicorp:mainfrom
Open
Enable self credentials rotation for static roles#212jadeidev wants to merge 47 commits intohashicorp:mainfrom
jadeidev wants to merge 47 commits intohashicorp:mainfrom
Conversation
- Mark password field as sensitive in schema. - Add validation for distinguished name (DN) when setting self-managed accounts. - Improve error handling for password rotation with self-managed accounts.
…ent and test files
…prevent modification after creation
…nts during creation
…efault max invalid attempts
… max invalid attempts for auto-rotation
…eue and update test assertions for password validation
…al rotation method
…tation is suspended due to invalid password attempts. - Updated logic in password setting to mark rotation as suspended when max attempts are reached. - Cleared the suspended flag upon successful password rotation. - Enhanced tests to validate the behavior of the rotation_suspended flag.
Author
Possible Enhancements to this PR for RACFFor RACF self rotation is currently set to be done in the same way regular rotation is done (requiring the account to be privileged). As an alternative to that
Unfortunately I don't have an RACF system to test either options. Please provide guidance if there is interest. sample code for changing a user password or password phrase in RACF using SDBMfunc racfSelfRotation(cfg *Config, currentPassword, newPassword string) error {
conn, err := c.ldap.DialLDAP(cfg.ConfigEntry)
if err != nil {
return err
}
defer conn.Close()
// RACF (SDBM backend) supports self password/phrase change via simple bind using
// "current/new". Slashes and backslashes inside a password phrase must be escaped.
if currentPassword == "" || newPassword == "" {
return fmt.Errorf("must provide both current and new passwords")
}
combined := racfCombineForBind(currentPassword, newPassword)
// Determine the user to bind with
var bindUser string
switch {
case cfg.UPNDomain != "":
bindUser = fmt.Sprintf("%s@%s", ldaputil.EscapeLDAPValue(cfg.BindDN), cfg.UPNDomain)
case cfg.BindDN != "":
bindUser = cfg.BindDN
default:
return errors.New("must provide binddn or upndomain")
}
if err := conn.Bind(bindUser, combined); err != nil {
return fmt.Errorf("racf self-managed password change bind failed: %w", err)
}
}
// racfCombineForBind escapes RACF password phrases then joins current/new for simple bind change.
func racfCombineForBind(current, new string) string {
return racfEscapePhrase(current) + "/" + racfEscapePhrase(new)
}
// racfEscapePhrase:
// - Escape backslash as \\
// - Escape forward slash as \/ so it is not interpreted as the delimiter
func racfEscapePhrase(s string) string {
s = strings.ReplaceAll(s, `\`, `\\`)
s = strings.ReplaceAll(s, `/`, `\/`)
return s
} |
…ion for LDAP operations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
A high level description of the contribution
Who the change affects or is for (stakeholders)?
This change is for Vault users and administrators who manage static LDAP accounts and require Vault to rotate credentials using the account’s own password, rather than a privileged bind DN. Stakeholders include security teams and operators who need tighter control over credential rotation for sensitive accounts.
What is the change?
This contribution enables support for "self-managed" static accounts in the Vault OpenLDAP secrets engine. When enabled, Vault rotates credentials by authenticating as the managed account itself, using its current password, rather than relying on a privileged bind DN.
This feature introduces new attributes to the static role schema:
self_managed(default:false) parameter is optional and indicates whether the role manages its own password rotation. If true, Vault will perform rotations by authenticating as this account using its current password (no privileged bind DN).This requires the "password" parameter to be set on creation, and the "dn" parameter to be set as well.
This field is immutable after creation. If false (the default), Vault will use the configured bind DN to perform rotations.
passwordparameter is required only if "self_managed" is true, and configures the current password for the entry.This allows Vault to assume management of an existing account. The password will be rotated on creation unless
the
skip_import_rotationparameter is set to true. The password is not returned in read operations.self_managed_max_invalid_attemptsparameter is optional and configures the maximum number of invalid current-password attempts for self-managed accounts. A value equal to 0 means use the default (5), and a negative value means unlimited attempts. When the maximum number of attempts is reached, automatic rotation is suspended until the role is updated via thepasswordparameter. This field is immutable after creation.rotation_suspendedfield is only returned in read operations and indicates whether automatic rotation is currently suspended for this static account due to too many invalid current-password attempts on self-managed accounts.Why is the change needed?
Some environments restrict privileged access or require that password changes be performed by the account owner. Supporting self-managed rotation allows Vault to manage credentials for accounts where privileged bind is not possible or not desired, improving flexibility and security.
How does this change affect the user experience (if at all)?
Users can now create static roles with the
self_managedoption, providing the current password and DN. Vault will rotate credentials using the account’s own authentication, and will suspend automatic rotation after a configurable number of failed attempts, requiring manual intervention. This enhances Vault’s ability to manage a wider range of LDAP accounts and improves compliance with organizational policies.Related Issues/Pull Requests
Contributor Checklist
PCI review checklist
I have documented a clear reason for, and description of, the change I am making.
If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
If applicable, I've documented the impact of any changes to security controls.
Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.