Active Directory Service Accounts for Windows Containers

Users and other services may need to make authenticated connections to your applications and services so you can keep data secure and prevent unauthorized usage. Windows Active Directory (AD) domains natively support both password and certificate authentication. When you build your application or service on a Windows domain-joined host, it uses the identity of the host by default if run as Local System or Network Service. Otherwise, you may configure another AD account for authentication instead.

Although Windows Containers cannot be domain-joined, they can also take advantage of Active Directory domain identities similar to when a device is realm-joined. With Windows Server 2012 domain controllers, we introduced a new account called a Group Managed Service Account (gMSA) which was designed to be shared by services. By using Group Managed Service Accounts (gMSA), Windows Containers themselves and the services they host can be configured to use a specific gMSA as their domain identity. Any service running as Local System or Network Service will use the Windows Container's identity just like they use the domain-joined host's identity today. There is no password or certificate private key stored in the container image that could be inadvertently exposed, and the container can be redeployed to development, test, and production environments without being rebuilt to change stored passwords or certificates.

Glossary & References

  • Active Directory is a service used for discovery, search and replication of user, computer, and service account information on Windows.
    • Active Directory Domain Services provide a Windows Active Directory domain(s) used to authenticate computers and users.
    • Devices are domain-joined when they are a member of Active Directory domain. Domain-joined is a device state which not only provides the device with a domain computer identity, but also lights up various domain-joined services.
    • Group Managed Service Accounts , often abbreviated as gMSA, are a type of Active Directory account that makes it easy to secure services using Active Directory without sharing a password. Multiple machines or containers share the same gMSA as needed to authenticate connections between services.
  • CredentialSpec PowerShell Module - This module is used to configure Group Managed Service Accounts to be used with containers. The script module and example steps are available at windows-server-container-tools, see ServiceAccount

How it Works

Today, group Managed Service Accounts are often used to secure connections between one computer or service to another. The general steps to use one are:

  1. Create a gMSA
  2. Configure the service to run as the gMSA
  3. Give the domain-joined host running the service access to the gMSA secrets in Active Directory
  4. Allow access to gMSA on the other service such as a database or file Shares

When the service is launched, the domain-joined host automatically gets the gMSA secrets from Active Directory, and runs the service using that account. Since that service is running as the gMSA, it can access any resources the gMSA is allowed to.

Windows Containers follow a similar process:

  1. Create a gMSA. By default, a domain administrator or account operator must do this. Otherwise they can delegate the privileges to create & manage gMSAs to admins who manage services which use them. You will need at least one Windows Server 2012 or later domain controller in your domain, but there is no requirement to use a specific domain functional level. See gMSA Getting started
  2. Give the domain-joined container host access to the gMSA
  3. Allow access to gMSA on the other service such as a database or file Shares
  4. Use the CredentialSpec PowerShell module from windows-server-container-tools to store settings needed to use the gMSA
  5. Start the container with an extra option --security-opt "credentialspec=..."

Note

You might need to allow anonymous SID/Name translation on the container host as described here as you might otherwise get errors that accounts can't be translated to SIDs.

However, before exploring the need to allow anonymous SID/Name translation, ensure that the following actions are taken:

  1. The name of the gMSA account should match the name of the service (ex. "myapp").
  2. Include the -h argument to specify the hostname the container should use when launched. docker run --security-opt "credentialspec=file://myapp.json" -d -p 80:80 -h myapp.mydomain.local <imagename>
  3. The Service Principal Name (SPN) used when creating the gMSA account should match the -h argument used when the container is run. If you did not add SPNs to the gMSA during creation, they can be added to properties of the account afterwards.

When the container is launched, the installed services running as Local System or Network Service will appear to run as the gMSA. This is similar to how those accounts work on a domain-joined hosts, except a gMSA is used instead of a computer account.

Diagram - Service Accounts

Example Uses

SQL Connection Strings

When a service is running as Local System or Network Service in a container, it can use Windows Integrated Authentication to connect to a Microsoft SQL Server.

Example:

Server=sql.contoso.com;Database=MusicStore;Integrated Security=True;MultipleActiveResultSets=True;Connect Timeout=30

On the Microsoft SQL Server, create a login using the domain and gMSA name, followed by a $. Once the login is created, it can be added to a user on a database and given appropriate access permissions.

Example:

CREATE LOGIN "DEMO\WebApplication1$"
    FROM WINDOWS
    WITH DEFAULT_DATABASE = "MusicStore"
GO

USE MusicStore
GO
CREATE USER WebApplication1 FOR LOGIN "DEMO\WebApplication1$"
GO

EXEC sp_addrolemember 'db_datareader', 'WebApplication1'
EXEC sp_addrolemember 'db_datawriter', 'WebApplication1'

To see it in action, check out the recorded demo available from Microsoft Ignite 2016 in the session "Walk the Path to Containerization - transforming workloads into containers".