body common control
{
  bundlesequence => { "autorun_ssh_key_distribution" };
  inputs => { "$(sys.libdir)/stdlib.cf" };
}

bundle common ssh_key_info
{
  meta:
    "description"
      string => "This bundle defines common ssh key information, like which
                 directory and server keys should be sourced from.";

  vars:
    "key_server" string => "$(sys.policy_hub)";

    # We set the path to the repo in a common bundle so that we can reference
    # the same path when defining access rules and when copying files.
    # This directory is expected to contain one file for each users authorized
    # keys, named for the username. For example: /srv/ssh_authorized_keys/kelly
    "repo_path" string => "/srv/ssh_authorized_keys";
}

bundle agent autorun_ssh_key_distribution
{
  meta:
    # Here we simply tag the bundle for use with the `services_autorun`
    # feature.
    "tags" slist => { "autorun" };

  vars:
    "users" slist => { "bob", "frank", "kelly" };

  methods:
    "Distribute SSH Keys"
      usebundle => ssh_key_distribution($(users)),
      if => userexists($(users)),
      comment => "It's important that we make sure each of these users
                  ssh_authorized_keys file has the correct content and
                  permissions so that they can successfully log in, if
                  the user exists on the executing agents host.";
}

bundle agent ssh_key_distribution(users)
{
  meta:
    "description"
      string => "Ensure that specified users are able to log in using their ssh
                 keys";

  vars:
    # We get the users UID so that we can set permission appropriately
    "uid[$(users)]" int => getuid($(users));

  files:
    "/home/$(users)/.ssh/."
      create => "true",
      perms => mo(700, "$(uid[$(users)])"),
      comment => "It is important to set the proper restrictive permissions and
                  ownership so that the ssh authorized_keys feature works
                  correctly.";

    "/home/$(users)/.ssh/authorized_keys"
      perms => mo(600, "$(uid[$(users)])"),
      copy_from => remote_dcp(
        "$(ssh_key_info.repo_path)/$(users)", $(ssh_key_info.key_server)
      ),
      comment => "We centrally manage and users authorized keys. We source each
                  users complete authorized_keys file from the central server.";
}

bundle server ssh_key_access_rules
{
  meta:
    "description"
      string => "This bundle handles sharing the directory where ssh keys
                 are distributed from.";

  access:
    # Only hosts with class `policy_server` should share the path to ssh
    # authorized_keys
    policy_server::
      "$(ssh_key_info.repo_path)"
        admit => { @(def.acl) },
        comment => "We share the ssh authorized keys with all authorized
                    hosts.";
}
