Managing Enterprise Credentials
Image by: Pete Linforth, found on PixaBay.com

Managing Enterprise Credentials

Some companies get stuck on the treadmill of rotating keys to defend against old or exposed credentials or to satisfy a security checkbox. Worse, some assume no “bad actors” are in their systems - even though the mean time to discover a data breach is around 200-300 days (depending on your source). Fortunately there’s a solution that eliminates the need for key rotation.

Replace or supplant static credentials with machine identities, attribute-based access control (ABAC), and multi-factor authentication (MFA). We illustrate the benefits of this approach with Amazon Web Service (AWS) command-line interfaces (CLI), outlining the threat model, solution controls, and implementation details for two use cases: remote control and Infrastructure as Code (IaC).

Threat Model and a Control Solution

The threat model we’re using to guide our defenses includes:

  • Infected endpoints can result in exfiltrated credentials.
  • Insider threats can exploit overly-broad permissions and shared credentials.
  • Static credentials outlast staff terminations.
  • Bad actors move laterally and escalate privileges using found credentials.

Some controls that? assist this defense:

  • Avoid static credentials or require MFA with their use.
  • Use machine and user attributes (ABAC) to control access.
  • Decrypt credentials when needed, only in memory when possible, and remove them after use.
  • Use short-lived, self-expiring tokens.
  • Enforce least-privilege access and use authorization checks prior to role assumption.
  • Enable remote access through SSM and ABAC rather than private keys and internet-exposed ports.

Controls Explained

With ABAC, one or more properties of the actor (person, instance, or “principal”) must match a property of the target (instance or “resource”). This can be implemented by assigning tags to every principle and resource, along with policies that check for matching tags. Once implemented, only “dev”-tagged users can access “dev” instances (for example). This enables easy scaling of principals and resources with no policy changes.

When machines are the principal, the use of machine attributes for authorization is sometimes called “machine identity” - and can include tags, names, IPs, or other attributes. When a person is the principal, the AWS Identity and Access Manager (IAM) can enforce MFA authentication for both GUI and CLI functions. Although credentials are used in our model, they are not preserved unencrypted on disk, decrypted only when needed, require MFA, and are used just long enough to get short-term, self-expiring tokens in memory.?

The Security Token Service (STS) issues those short-term user tokens. Those tokens should allow no permissions other than role assumption. When users try to assume a role with those tokens, policy checks occur to confirm authorization, then STS issues new role tokens.

Users can assume a remote access role using these controls. To start, a user would decrypt static credentials into memory and combine them with an MFA code to get STS user tokens. He would then request the remote control role. After an authorization check, he would get new STS role tokens. Then he would request remote access to an instance. AWS would use ABAC checks to confirm that the user and instance tags match, and would verify that the role tokens are valid. Then the AWS Systems Manager (SSM) would open a remote control session. No private keys (“pem” files) or internet-exposed ports are required.

Remote Access Commands

Here’s the 5 commands to remotely access an AWS instance using the controls described above. Replace $variables as needed. Additional details follow.

c=/tmp/creds;pass aws/creds > $c;chmod +x $c;. $c;shred -uvz $c 2>/dev/null; rm -f $c # decrypt keys into memory

aws sts get-session-token --serial-number $arnMfa --token-code $mfa --duration-seconds 900 # get user STS token

aws sts assume-role --role-arn $arnRole --duration-seconds 3600 --role-session-name jane.ssm # get role token

id=$(aws ec2 describe-instances --region $region --filter "Name=tag:Name,Values=$instanceName” --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" $* --output text) # get id of instanceName to control

aws ssm start-session --target $id --region $region # start remote control of instanceName

Controls for Infrastructure as Code (IaC)

This methodology applies to other use cases. For example, IaC staff can avoid hard coding keys into terraform.tfvars files. Instead, they can:

  • get STS tokens for an IaC role, using the same process described above
  • export the tokens to the shell, with a preface, like: TF_VAR_AWS_ACCESS_KEY_ID
  • reference the token names in .tf files, like: AWS_ACCESS_KEY_ID

If a machine rather than a person is doing the terraforming, no MFA is likely available, so adjust the IaC role’s ABAC checks to check metadata of the terraforming principal machine (tag, name, source IP, etc.).

For Ansible (another common IaC tool), export the tokens as “-e name=value” on the ansible-playbook call. Do this for all the name/value pairs from the IaC STS role tokens. Reference those names in the Ansible files as needed.

Implementation Detail

This section provides more hints towards working code.

Pass:

  • Users desiring secure access with MFA can apply defense-in-depth by encrypting their keys with the “pass” program (passwordstore.org). Pass encrypts information using GPG, is scriptable, follows Unix philosophy, can auto-lock on screensaver activation or other events, and makes backups simple.
  • The “pass aws/creds” command shown earlier refers to a pass path that is populated with AWS credentials using a simple bash export line, like: pass insert -m aws/creds <<< “export AWS_ACCESS_KEY_ID=AKIA….”.
  • An alternative to pass is to leave the AWS credentials in plain text at ~/.aws/credentials. Assuming the AWS policies are set correctly, those credentials will be useless without MFA.

Policies:

  • Enabling AWS ABAC checks and role assumption requires writing policies. For example, the $arnRole above would include an Allow Effect statement for 3 SSM actions and 3 resources, with Condition checks for the ssmAllowed tag and StringLike role, e.g., “aws:ResourceTag/role": "*${aws:PrincipalTag/role}*”. This checks that the role tag on the resource and the principal match.
  • MFA is enforced by writing a policy that sets another Condition check using BoolIfExists aws:MultiFactorAuthPresent.
  • Remotely controllable instances must have SSM agents installed (or included in the Amazon Machine Image) and a policy attached that allows SSM actions. AWS provides this. Add ABAC checks to that.
  • For more hints on writing policies, search for AWS ABAC policy, AWS SSM policy, or AWS MFA policy.

Aliases:

  • For ease of use, wrap the aws commands with aliases to simplify execution. The aliases should export variable names and values. For example, the result of the first AWS STS command is json output containing CapitalCamelCase variables. The alias would make the AWS call, parse the json output, and export those as SNAKE_CASE, e.g., AccessKeyId is exported as AWS_ACCESS_KEY_ID. Same for AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN. For terraform actions, preface those exports with TF_VAR_.
  • For even easier use, one alias can call the others. Then a remote control request could be done in a single command, like: ssm 123456 remoteAccess someInstance us-east-1. That would pass your MFA code (123456) into IAM to authenticate, assume the remoteAccess role, and remote into someInstance in the us-east-1 region.

More:

  • AWS commercial and govcloud accounts have different capabilities, so test policies and scripts on both and adjust as needed.
  • Assign the same tag name and values to both the principal(s) and resource(s). One-to-many and many-to-one mapping of role tags between principals and resources is also possible by adjusting the AWS policies.
  • SSM also allows port forwarding and scp. However scp requires pem files - but the encryption tunnels through SSM and uses IAM for authentication, so this doesn’t open a vulnerability.

Implementation Summary:

The work described above functions correctly if all of these are true:

  • Attributes (such as role tags) match on principals and resources.
  • Policies are associated with principles and resources to check attributes (ABAC).
  • Users have valid keys and provide an MFA code, and are associated with a policy that allows role assumption.
  • For remote actions, the SSM agent is installed on the instance or included with the AMI.
  • All the usual caveats (the instance is on and running, the name exists in the specified region, the internet connection is working, etc.).

Conclusion

Additional advantages to using the controls above include:

  • Resources and users can be added or removed from access simply by changing tags.
  • No decrypted credentials persist on disk in any files (~/aws/.credentials, terraform.tfvars, etc.).
  • Tokens auto-expire after short intervals (usually 1-4 hours).
  • There’s no pem keys or open ssh ports.
  • When staff leave, no key rotation is necessary. Just disable their accounts.

This justifies, explains, and demonstrates a model for securing access to resources - without the usual vulnerabilities of static credentials - using encryption, MFA, ABAC policies, least-privilege roles, and short-term tokens.


About the author: DavidEason.com does cyber and many things security related, including reading and writing about it and training others, full-time and for fun.

要查看或添加评论,请登录

David Eason的更多文章

  • DevSecOps Balance

    DevSecOps Balance

    DevSecOps is a process for developing (dev) secure (sec) software that can be deployed into operational (ops)…

  • Safer (Computing) at Home

    Safer (Computing) at Home

    Our "new normal" finds more folks juggling home and work responsibilities at the same time, in the same place. This…

社区洞察

其他会员也浏览了