Inspecting Kerberos Tickets and Using Them with Python Requests

· security / authentication · #kerberos #kinit #klist #dsregcmd #python #requests

Kerberos provides ticket-based authentication for services in an Active Directory or other Kerberos realm. Instead of sending a password to every service, a client first obtains a ticket-granting ticket (TGT). It can then request service tickets and present them to the relevant services.

This post covers three practical tasks:

  • Obtaining and inspecting Kerberos tickets with kinit and klist
  • Checking Windows device and Azure AD registration with dsregcmd /status
  • Sending HTTP requests with Kerberos authentication from Python

Obtain a Ticket with kinit

On Linux, macOS, and other systems with MIT Kerberos tools installed, use kinit to authenticate and create a TGT in the local credential cache:

kinit user@EXAMPLE.COM

Enter the password when prompted. If the command succeeds, it normally produces no output. The ticket is stored in the credential cache, commonly /tmp/krb5cc_<uid> on Linux.

For a keytab-based, non-interactive login, use:

kinit -kt /path/to/service.keytab HTTP/service.example.com@EXAMPLE.COM

Keytabs are sensitive credentials. Restrict their file permissions and do not commit them to source control.

Inspect Tickets with klist

Run klist to display the credentials currently in the cache:

klist

Typical output contains the default principal, the credential cache location, and ticket validity times:

Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: user@EXAMPLE.COM

Valid starting       Expires              Service principal
07/17/2026 09:00:00  07/17/2026 19:00:00  krbtgt/EXAMPLE.COM@EXAMPLE.COM

The krbtgt/EXAMPLE.COM@EXAMPLE.COM entry is the TGT. Once an application connects to a Kerberos-protected service, klist may also show a service ticket such as HTTP/api.example.com@EXAMPLE.COM.

If a ticket has expired, obtain a new one with kinit. To remove cached credentials explicitly, run:

kdestroy

On Windows, the built-in klist command can inspect the tickets held by the current logon session:

klist

Check Windows Device Registration

Kerberos authentication in enterprise environments can depend on the device’s identity and its relationship to Active Directory or Microsoft Entra ID. On Windows, use the following command from a Command Prompt or PowerShell session:

dsregcmd /status

Review the Device State and User State sections. Common fields include:

Field Meaning
AzureAdJoined The device is joined to Microsoft Entra ID.
DomainJoined The device is joined to an on-premises Active Directory domain.
WorkplaceJoined A work or school account is registered on the device.
AzureAdPrt A Primary Refresh Token is available for the signed-in user.

For example, a hybrid-joined device often reports both AzureAdJoined : YES and DomainJoined : YES. A device that should use integrated authentication but reports an unexpected join state may need device-registration or policy investigation before debugging the application itself.

dsregcmd /status reports device and user registration state; it does not replace klist when you need to inspect Kerberos tickets directly.

Use Kerberos Authentication with requests

Python’s requests library does not implement Kerberos authentication by itself. The requests-kerberos package supplies an authentication handler that uses the current user’s Kerberos credential cache.

Install the packages:

python -m pip install requests requests-kerberos

After running kinit or signing in to the domain, attach HTTPKerberosAuth to a request:

import requests
from requests_kerberos import HTTPKerberosAuth, OPTIONAL

response = requests.get(
	"https://api.example.com/protected-resource",
	auth=HTTPKerberosAuth(mutual_authentication=OPTIONAL),
	timeout=30,
)
response.raise_for_status()

print(response.json())

The HTTP server must be configured for Negotiate authentication and must have an HTTP service principal name (SPN) that matches the hostname in the URL. For example, a request to https://api.example.com/ typically needs an SPN similar to:

HTTP/api.example.com@EXAMPLE.COM

Prefer the service’s canonical DNS name in the URL. Accessing the same service by IP address, an alias without a registered SPN, or an untrusted hostname can prevent the client from obtaining the correct service ticket.

Troubleshooting Checklist

When an authenticated request fails, check the authentication path in order:

  1. Run klist and verify that the TGT exists and has not expired.
  2. Run kinit user@EXAMPLE.COM to refresh the credential cache when needed.
  3. Retry the request, then use klist again to see whether an HTTP/<hostname> service ticket was issued.
  4. On Windows, run dsregcmd /status to verify the expected device and user registration state.
  5. Confirm that the URL hostname matches the HTTP SPN configured on the server.
  6. Check server logs for Negotiate, SPN, or delegation errors.

Takeaway

kinit obtains Kerberos credentials, and klist shows the tickets available to the current user. On Windows, dsregcmd /status provides complementary device-registration information. In Python, requests-kerberos connects requests to the existing Kerberos credential cache, allowing HTTP clients to use Negotiate authentication without handling passwords in application code.