Related docs:
KEYTAB CAPABILITIES KEYTAB USE CASES IDM VAULT PLUGIN AAP INTEGRATION DOCS MAP
eigenstate.ipa.keytab retrieves Kerberos keytab files for service and host
principals registered in FreeIPA/IdM.
This reference covers:
ipa-getkeytabretrieve and generate modesThe authenticating principal must have permission to retrieve keytabs for the target principals. In most environments this requires admin rights or explicit IPA RBAC delegation.
flowchart LR
ans["Ansible task or template"]
lookup["eigenstate.ipa.keytab"]
krb["Kerberos ticket\nexisting, password-derived,\nor keytab-derived"]
cmd["ipa-getkeytab subprocess"]
idm["IdM / FreeIPA\n(Kerberos-authenticated LDAP)"]
out["Lookup return value\nbase64-encoded keytab"]
ans --> lookup
lookup --> krb
krb --> cmd
cmd --> idm
idm --> out
The lookup shells out to ipa-getkeytab from the local IdM client packages.
It does not use ipalib for the retrieval step. The ipa-getkeytab binary
handles the Kerberos-authenticated LDAP protocol internally. The only Ansible-
side Python dependency is a working Kerberos credential cache before the
subprocess runs. On the validated RHEL 10 path, ipa-getkeytab is provided by
ipa-client.
The lookup always operates with a Kerberos credential cache.
It can get there in three ways:
ipaadmin_password:
kinit to obtain a ticket before calling ipa-getkeytabkinitkerberos_keytab:
kinit -kt to obtain a ticket non-interactively[!NOTE] Password auth is viable for local automation only when the IPA account’s password is not forced into a change-on-first-login flow. A newly created IPA user with an expired password will fail non-interactive
kinit.
[!IMPORTANT] For AAP use,
kerberos_keytabis the correct non-interactive path. A Controller credential type that mounts a keytab file into the EE is the standard deployment pattern. See the AAP integration guide for the full wiring.
When kerberos_keytab or ipaadmin_password point to local files, the plugin
warns if those files have permissions broader than 0600.
TLS verification behavior:
verify: /path/to/ca.crt adds --cacert /path/to/ca.crt to ipa-getkeytabverify: false skips the explicit --cacert override and relies on the
local system trust configurationverify first tries /etc/ipa/ca.crtA keytab is not just a file-delivery problem. In Kerberos-based automation it is often the bootstrap material used to obtain the real runtime credential: a Kerberos ticket. That makes the keytab surface more operationally powerful than an ordinary static password.
When the principal is dedicated to one controller workflow or one tightly scoped
service boundary, retrieve_mode='generate' can also be used as an immediate
retirement mechanism: rotating the principal keys invalidates the previous
keytab material at once. In practice that means a job can:
That is not a Vault-style lease model. There is no TTL or issuer-owned renewal contract. But it is still a materially stronger short-lived machine-identity pattern than leaving a shared password in place indefinitely.
The retrieve_mode option controls the behavior of the ipa-getkeytab call.
retrieve (default)Passes -r to ipa-getkeytab. Only retrieves existing keys for the principal.
The call fails if no keys exist yet.
This is the safe default. Existing keytabs held by services are not invalidated.
generateOmits -r. May generate new random keys for the principal.
[!WARNING]
generaterotates the principal’s keys. Any service or host that holds an existing keytab for that principal will be unable to authenticate immediately after the call. Usegenerateonly when explicit rotation is the intent and when the new keytab will be deployed to all consuming services in the same playbook run.
The lookup emits a visible display.warning when retrieve_mode='generate'
is selected.
By default, ipa-getkeytab selects encryption types according to the IPA
server’s policy. Use enctypes to override:
enctypes:
- aes256-cts
- aes128-cts
Each entry becomes a separate -e flag in the ipa-getkeytab call. Setting
enctypes to an empty list (the default) passes no -e flags.
Typical use cases for explicit enctypes:
The plugin always returns base64-encoded keytab content. Keytabs are binary files and cannot be embedded directly in Ansible variables.
Three result shapes are available via result_format:
value (default)Returns a bare base64 string per principal.
result: ["AQIB..."]
Use this when the playbook only needs the keytab bytes and has a simple single-principal lookup.
recordReturns a dict per principal with:
principal — the Kerberos principal namevalue — base64-encoded keytabencoding — always base64result:
- principal: "HTTP/webserver.example.com"
value: "AQIB..."
encoding: "base64"
Use this when the playbook should not depend on positional list ordering or
when it needs to log or route based on the principal name. In Ansible, use
query(...) | first for this structured return shape.
mapReturns a single dict keyed by principal name. This is returned as a one-element list containing the dict.
result:
- "HTTP/web-01.example.com": "AQIB..."
"HTTP/web-02.example.com": "AQIC..."
Use this when a single lookup retrieves keytabs for multiple principals and
the playbook needs to address them by name rather than by position. In
Ansible, use query(...) | first for this structured return shape.
Retrieve an existing HTTP service keytab:
- ansible.builtin.set_fact:
http_keytab_b64: "{{ lookup('eigenstate.ipa.keytab',
'HTTP/webserver.idm.corp.lan',
server='idm-01.idm.corp.lan',
ipaadmin_password=lookup('env', 'IPA_PASSWORD'),
verify='/etc/ipa/ca.crt') }}"
Retrieve using a keytab for non-interactive authentication:
- ansible.builtin.set_fact:
nfs_keytab_b64: "{{ lookup('eigenstate.ipa.keytab',
'nfs/storage.idm.corp.lan',
server='idm-01.idm.corp.lan',
kerberos_keytab='/runner/env/ipa/admin.keytab',
verify='/etc/ipa/ca.crt') }}"
Write keytab to disk on the target host:
- ansible.builtin.copy:
content: "{{ lookup('eigenstate.ipa.keytab',
'HTTP/webserver.idm.corp.lan',
server='idm-01.idm.corp.lan',
kerberos_keytab='/runner/env/ipa/admin.keytab',
verify='/etc/ipa/ca.crt') | b64decode }}"
dest: /etc/httpd/conf/httpd.keytab
mode: "0600"
owner: apache
group: apache
Multiple principals in one lookup with map format:
- ansible.builtin.set_fact:
web_keytabs: "{{ query('eigenstate.ipa.keytab',
'HTTP/web-01.idm.corp.lan',
'HTTP/web-02.idm.corp.lan',
server='idm-01.idm.corp.lan',
kerberos_keytab='/runner/env/ipa/admin.keytab',
result_format='map',
verify='/etc/ipa/ca.crt') | first }}"
# web_keytabs['HTTP/web-01.idm.corp.lan'] | b64decode
# web_keytabs['HTTP/web-02.idm.corp.lan'] | b64decode
Restrict to AES-256 only:
- ansible.builtin.set_fact:
keytab_b64: "{{ lookup('eigenstate.ipa.keytab',
'HTTP/webserver.idm.corp.lan',
server='idm-01.idm.corp.lan',
kerberos_keytab='/runner/env/ipa/admin.keytab',
enctypes=['aes256-cts'],
verify='/etc/ipa/ca.crt') }}"
Rotate keys (invalidates all existing keytabs for this principal):
- ansible.builtin.set_fact:
new_keytab_b64: "{{ lookup('eigenstate.ipa.keytab',
'HTTP/webserver.idm.corp.lan',
server='idm-01.idm.corp.lan',
kerberos_keytab='/runner/env/ipa/admin.keytab',
retrieve_mode='generate',
verify='/etc/ipa/ca.crt') }}"
Common failure classes are:
ipa-getkeytab not installed on the control node or EEretrieve mode fails because no keys exist yet for the principal (this is
expected for brand-new service principals; use generate on first deploy
and retrieve on subsequent runs)[!NOTE] If
retrievemode fails for a principal that was just created, the principal may not have keys yet. Usegeneratefor the initial keytab issuance, then switch toretrievefor subsequent retrieval. You can also useipa service-add-principaland confirm withipa service-showbefore running the lookup.
Use KEYTAB CAPABILITIES when you need operator patterns rather than option-by-option reference: