Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - aws/credentials-fetcher: Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory. · GitHub
Skip to content

Credentials Fetcher

credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

This daemon works in a similar way as ccg.exe and the gMSA plugin in Windows as described in - https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements

Table of Contents

Prerequisites

Supported Platforms: Amazon Linux 2023 (recommended), Fedora 41+

Required Dependencies:

dnf install openldap-clients krb5-workstation sssd 

For Domain-Joined Mode (additional):

dnf install realmd oddjob oddjob-mkhomedir adcli

Build Dependencies (AL2023):

# Install Go
sudo dnf install -y golang make krb5-devel
# Install golangci-lint (Optional)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
# Install gosec (Optional)
go install github.com/securego/gosec/v2/cmd/gosec@latest
# Add to PATHexport PATH=$PATH:$(go env GOPATH)/bin

Building from Source

Quick Build

make build

The binary will be created at bin/credentials-fetcherd.

Build Options

CommandDescription
make buildBuild the binary
make lint-checkRun golangci-lint
make security-checkRun gosec security scanner
make release-strictFull build with security checks, linting, and race detection
make cf-installBuild and install to system (requires sudo)
make cf-create-serviceGenerate systemd service file

Build Flags

Enable debugging symbols:

ENABLE_DEBUGGING=1 make build

Enable code coverage:

CODE_COVERAGE=1 make build

Manual Installation

After building:

sudo make cf-install

This installs:

  • Binary to /usr/sbin/credentials-fetcher
  • Service file to /usr/lib/systemd/system/credentials-fetcher.service
  • Config to /etc/credentials-fetcher.conf

Please note the name of the binary is updated to credentials-fetcher

Installation

Installing the latest version of credentials-fetcher

dnf install credentials-fetcher

Verify Installation

systemctl status credentials-fetcher
credentials-fetcher --version

Configuration

The daemon is configured via /etc/credentials-fetcher.conf.

For ECS/Fargate (managed modes): No configuration needed. Default settings work out of the box.

For standalone mode: All options remain optional for basic lease operations. Configuration is only needed if you require automatic credential renewal in non-domain joined standalone deployments.

Configuration Options

OptionTypeDefaultDescription
RunRenewalNonDomainJoinedboolfalseEnable automatic credential renewal for non-domain joined standalone mode
CFGmsaSecretNamestring""AWS Secrets Manager secret name containing AD credentials
LDAPSearchTimeoutint5LDAP search timeout in seconds

Default Configuration (ECS/Fargate/Standalone)

Works for all deployment modes without modification:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined =
CFGmsaSecretName = ""LDAPSearchTimeout = 5

Standalone Non-Domain-Joined with Auto-Renewal

Only needed for standalone deployments requiring automatic credential renewal:

# /etc/credentials-fetcher.confRunRenewalNonDomainJoined = true
CFGmsaSecretName = "prod/ad-credentials"LDAPSearchTimeout = 10

AWS Secrets Manager secret format:

{"username": "StandardUser01", "password": "p@ssw0rd", "domainName": "contoso.com"}

Setting up testing environment

Setting up gMSA accounts

Setup gMSA accounts using instructions here. Both domain-joined and non-domain joined use cases are supported. In Fargate, only non-domain joined is supported.

Setting up domain credentials to retrieve gMSA password

In non domain joined modes, the AD User credentials need to be stored in a secret store that will be retrieved by the daemon. We use AWS Secret Manager for this.

Save the AD User credentials to AWS secrets manager

{
"username":"StandardUser01",
"password":"p@ssw0rd",
"domainName":"contoso.com"
}

Next, on the EC2 instance where credentials-fetcher is installed, navigate to /etc/credentials-fetcher.conf and provide the secrets manager name

For domain joined modes, the host principle needs to be part of the group that is allowed to retrieve the managed password in AD setup.

Testing

Once gMSA accounts are created, use the test scripts in tests/test_scripts/ to validate kerberos ticket functionality.

Quick Test Setup

  1. Install Python dependencies:

    dnf install -y pip
    cd /path/to/repo
    python3 -m venv .venv
    source .venv/bin/activate pip install grpcio grpcio-tools
  2. Generate gRPC Python files:

    cd tests/test_scripts
    python -m grpc_tools.protoc --proto_path=../../internal/grpc/proto --python_out=. --grpc_python_out=. credentialsfetcher.proto
  3. Start credentials-fetcher daemon:

    sudo systemctl start credentials-fetcher

Running Tests

Domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} with your credspec JSON
python add_kerberos_lease_test.py
# Delete lease (replace {LEASE_ID_PLACEHOLDER} with returned lease_id)
python delete_kerberos_lease_test.py

Non-domain-joined mode:

# Replace {CREDSPEC_PLACEHOLDER} and {PASSWORD_PLACEHOLDER} with actual values
python add_non_domain_joined_kerberos_lease_test.py
# Test renewal
python renew_non_domain_joined_kerberos_lease.py

Expected output: Scripts print GRPC_TEST_RESULT: followed by JSON with success status and lease details.

Sample Credspec

Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-123456789-123456789-123456789",
"MachineAccountName": "WebApp01",
"Guid": "af602f85-d754-4eea-9fa8-fd76810485f1",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp01",
"Scope": "contoso.com"
}
]
}
}

Non-Domain-Joined Mode:

{
"CmsPlugins": ["ActiveDirectory"],
"DomainJoinConfig": {
"Sid": "S-1-5-21-987654321-987654321-987654321",
"MachineAccountName": "WebApp02",
"Guid": "bf702f85-e864-5ffa-8gb9-ge87920596g2",
"DnsTreeName": "contoso.com",
"DnsName": "contoso.com",
"NetBiosName": "CONTOSO"
},
"ActiveDirectoryConfig": {
"GroupManagedServiceAccounts": [
{
"Name": "WebApp02",
"Scope": "contoso.com"
}
],
"HostAccountConfig": {
"PortableCcgVersion": "1",
"PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
"PluginInput": {
"CredentialArn": "$gmsaSecretArn$"// AWS secret manager arn
}
}
}
}

Service Management

# Start the service
sudo systemctl start credentials-fetcher
# Stop the service
sudo systemctl stop credentials-fetcher
# Check status
sudo systemctl status credentials-fetcher
# Enable auto-start
sudo systemctl enable credentials-fetcher
# View logs
sudo journalctl -u credentials-fetcher -f

Troubleshooting

Common Issues

Service won't start:

  • Check logs: sudo journalctl -u credentials-fetcher
  • Verify config file: /etc/credentials-fetcher.conf
  • Ensure socket directory exists: /var/credentials-fetcher/socket

LDAP connection failures:

  • Verify AD connectivity: ldapsearch -H ldap://your-dc.contoso.com
  • Check DNS resolution: nslookup your-dc.contoso.com
  • Validate credentials in AWS Secrets Manager
  • Review logs: journalctl -u credentials-fetcher | grep -i ldap (automatic retry with debug on failure)

Kerberos ticket issues:

  • Check ticket cache: klist -c /var/credentials-fetcher/krbdir/*/krb5cc_*
  • Verify time sync: timedatectl status
  • Test kinit manually: kinit username@DOMAIN.COM

Test script failures:

  • Ensure daemon is running: systemctl status credentials-fetcher
  • Check socket permissions: ls -la /var/credentials-fetcher/socket/
  • Verify gRPC files generated: ls -la tests/test_scripts/*_pb2.py

Log Locations

  • Service logs: journalctl -u credentials-fetcher
  • Application logs: /var/credentials-fetcher/logging
  • Kerberos cache: /var/credentials-fetcher/krbdir

About

Credentials-fetcher is a Linux daemon that retrieves gMSA credentials from Active Directory over LDAP. It creates and refreshes kerberos tickets from gMSA credentials. Kerberos tickets can be used by containers to run apps/services that authenticate using Active Directory.

Resources

Code of conduct

Contributing

Security policy

Stars

133 stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages