Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow SSH User Certificate Principal to be limited to auth'd name #6056

Closed
sgowie opened this issue Jan 16, 2019 · 11 comments
Closed

Allow SSH User Certificate Principal to be limited to auth'd name #6056

sgowie opened this issue Jan 16, 2019 · 11 comments

Comments

@sgowie
Copy link

sgowie commented Jan 16, 2019

Is your feature request related to a problem? Please describe.
Defining SSH roles for user pubkey signing at scale forces grouping of prospective principal agents. This could be separated by functional teams, but that still permits the impersonation of a team member. The audit backend(s) present a hash of the requested/issued principals, which only effectively allows you to determine a change in pattern of issuance by user.

Describe the solution you'd like
If the allowed and default users can be configured to behave as a template, inheriting the authenticated username of the requestor this would reduce the role sprawl of the SSH CA backend, and/or allowed users per role. If the desired user is not present on the target machine, authentication will fail and a more explicit role would be used to allow the user to assume the service/management account on the host.

Describe alternatives you've considered
1 - An external process to create a per-user SSH CA role, and associated team-grouped policy, with periodic consolidation against active directory. This would still allow members of a given team to authenticate as a different user, however the change in role for the request would be an easier behaviour to detect
2 - Automatically disambiguate requested/issued principal hashes over time, building an indexed rainbow table to reference

Explain any additional use-cases

Additional context
Being able to effectively enforce 1:1 mappings from AD Authenticated users to short-lived SSH certificates would encourage adoption and simplify the user management and authentication. SSH authentication could eliminate the use of passwords, and AuthorizedKeysFile can be set to /dev/null to ensure that centralised identity management covers *nix hosts without additional agent sprawl.

@jovandeginste
Copy link

I was trying to achieve this same thing. Is there any security issue for implementing this? I'm now resorting to looping over all known users and generating a custom role for each (with Terraform).

@jefferai
Copy link
Member

jefferai commented Mar 1, 2019

It's simply not implemented currently, there's no security issue.

@daveadams
Copy link
Contributor

I've just run into this. I'd like to be able to use this policy:

  path "ssh/sign/self-login" {
    capabilities = ["update"]
    required_parameters = ["valid_principals"]
    allowed_parameters = {
      "valid_principals" = ["{{identity.entity.aliases.auth_ldap_abcdef01.name}}"]
    }
  }

But as per the policy docs, only the path element supports this sort of injection.

I haven't dug into the code yet, but I'm thinking enabling templating of these other fields in policies shouldn't require a huge amount of new code. I may work on a PR along those lines unless @jefferai and the Vault team have any concerns about that approach.

@JakobP
Copy link

JakobP commented Jul 4, 2019

@daveadams did you by any chance look at how difficult it would be to implement injection like you mentioned?

I might be interested in working on it, since it is relevant to the organisation I'm currently working for.

@daveadams
Copy link
Contributor

I got started on it and it got messier than I had hoped, and I never got it into a working state before I had to move on. The relevant code is parsePaths() in vault/policy.go.

My approach was to isolate the code for templating the path into a subfunction, and then for the two loops for key, val := range pc.AllowedParametersHCL and for key, val := range pc.DeniedParametersHCL those val interface{}s need to be templated if they are strings, but recursed if they are maps. Perhaps there are some utility functions handy for applying a function to any string value leaves in a map[string]interface{} type.

Good luck, and I look forward to any solution you come up with. Happy to test it out on my use case if that would help.

@vedavyaskadudas
Copy link

Im stuck at the same spot. If one of you experts can enable this, it will greatly benefit us all!
Another option i tried was to specify "allowed_users" value to be "{{token_display_name}}". Something like the snippet below:

{
    "allow_user_certificates": true,
    "allowed_users": "{{token_display_name}}",
    "default_extensions": [
        {
          "permit-pty": ""
        }
    ],
    "key_type": "ca",
    "default_user": "centos",
    "ttl": "30m0s",
    "allow_user_key_ids": "false",
    "key_id_format": "{{token_display_name}}"
}
EOH

But looks like {{token_display_name}} value is not substituted for "allowed_users". It, however is substituted for "key_id_format", when i modify the above role by setting allowed_users to "*"

Maybe that is an area of the code base you can look at and allow substituting "{{token_display_name}}" as a value for "allowed_users" ?

@fredrikhgrelland
Copy link
Contributor

@vedavyaskadudas an improvement that enables this has been merged to master and will be a part of the next release. See #7548

@vedavyaskadudas
Copy link

Thank you @fredrikhgrelland! If i want to try it out by building from master, do i still specify "allowed_users": "root,{{identity.entity.aliases.$(vault auth list -format=json | jq -r '.["userpass/"].accessor').name}}"
as specified in your example in #7548? or have the instructions changed? If so, please point me to the correct way of mapping allowed_users to the authenticated user.
Cant wait to try it out :)

@fredrikhgrelland
Copy link
Contributor

@vedavyaskadudas it has not changed, but I t requires a Boolean set to allow templating. In the ui, you need to set a checkbox to allow templates policies, and a template such as {{identity.entity.aliases.mount_accessor_xyz.name}}. You need to find the accessor from the auth source.

@vedavyaskadudas
Copy link

@fredrikhgrelland - I tried vault-1.4.0-beta1 and it worked like a charm!
Thank you for your contribution. This finally makes SSH Certificates usable without any compromises IMO. i.e. without using shared principals.

@briankassouf
Copy link
Contributor

Sounds like this issue is fixed via #7548 so I'm going to close this out. Please let us know if this isn't the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants