eigenstate-ipa

User Lease Module

Related docs:

  USER LEASE CAPABILITIES     USER LEASE USE CASES     EPHEMERAL ACCESS CAPABILITIES     AAP INTEGRATION     DOCS MAP  

Purpose

eigenstate.ipa.user_lease manages IdM user expiry attributes as an access boundary, not as generic user CRUD.

Use it when an existing user should become unusable at a defined time by setting krbPrincipalExpiration, optionally with krbPasswordExpiration. This reference covers the exact module surface: authentication, states, time formats, group-gated assertions, return data, and failure boundaries.

Contents

Write Model

flowchart LR
    module["eigenstate.ipa.user_lease"] --> auth["Kerberos ticket<br/>existing, password-derived, or keytab-derived"]
    auth --> api["ipalib user_show / user_mod"]
    api --> attrs["krbPrincipalExpiration<br/>and optionally<br/>krbPasswordExpiration"]
    attrs --> result["Return: changed + before/after expiry state"]

The module reads the current user state from IdM, computes whether the target expiry attributes need to change, and only then calls user_mod.

This is intentionally narrow:

Authentication Model

The module uses the same ipalib and Kerberos stack as vault_write.

It can authenticate in three ways:

[!IMPORTANT] For delegated non-admin operation, the authenticating principal must have write access to krbPrincipalExpiration on the target user. Managing krbPasswordExpiration additionally requires write access to that attribute.

States

state: present

Ensures one or both expiry attributes are set to the requested time.

state: expired

Sets krbPrincipalExpiration to the current UTC time. When password_expiration_matches_principal: true is also set, the password expiry is set to the same current time.

state: cleared

Removes krbPrincipalExpiration. When clear_password_expiration: true is also set, removes krbPasswordExpiration too.

Time Input Formats

For state: present, the module accepts these forms:

Examples:

[!NOTE] Relative durations are evaluated at runtime and are therefore not stable across repeated runs. Use absolute times when strict idempotent convergence matters.

Governed Group Assertions

require_groups is not an RBAC system. It is a safety check.

The module reads the user’s direct IdM group memberships and fails if any required group is missing. This is useful when the delegated permission itself is already scoped to members of a governed group and the playbook should refuse mutations outside that boundary.

Idempotency

State Change condition
present requested expiry differs from current expiry
expired current expiry is not already equal to the current runtime timestamp
cleared the selected expiry attribute currently exists

Two practical points matter:

Return Shape

changed: true | false
username: string
uid: string
principal_expiration_before: string | null
principal_expiration_after: string | null
password_expiration_before: string | null
password_expiration_after: string | null
lease_end: string | null
memberof_group: list[str]
groups_checked: list[str]

All expiry values are returned in generalized UTC format.

Options Reference

Option Required Default Description
username yes existing IdM user to modify
state no present present, expired, or cleared
principal_expiration no target krbPrincipalExpiration for state: present
password_expiration no target krbPasswordExpiration for state: present
password_expiration_matches_principal no false reuse the principal expiry time for password expiry
clear_password_expiration no false with state: cleared, also remove password expiry
require_groups no [] require the user to belong to all listed groups
server yes $IPA_SERVER FQDN of the IPA server
ipaadmin_principal no admin Kerberos principal to authenticate as
ipaadmin_password no $IPA_ADMIN_PASSWORD password for the principal
kerberos_keytab no $IPA_KEYTAB keytab path; takes precedence over password
verify no $IPA_CERT/etc/ipa/ca.crt IPA CA path for TLS verification

Examples

Set a two-hour lease window:

- name: Grant a two-hour lease
  eigenstate.ipa.user_lease:
    username: temp-deploy
    principal_expiration: "02:00"
    server: idm-01.example.com
    kerberos_keytab: /etc/ipa/lease-operator.keytab
    ipaadmin_principal: lease-operator

Expire both authentication paths now:

- name: End temporary access now
  eigenstate.ipa.user_lease:
    username: temp-maintenance
    state: expired
    password_expiration_matches_principal: true
    require_groups:
      - lease-targets
    server: idm-01.example.com
    kerberos_keytab: /etc/ipa/lease-operator.keytab
    ipaadmin_principal: lease-operator

Clear lease state:

- name: Remove principal expiry and leave password expiry untouched
  eigenstate.ipa.user_lease:
    username: temp-build
    state: cleared
    server: idm-01.example.com
    ipaadmin_password: "{{ ipa_password }}"

Failure Boundaries

The module fails when:

The module does not revoke already-issued Kerberos tickets. It only changes the future authentication boundary on the user object.