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

What's an example model for getting access to creds on this plugin? #59

Closed
DrDaveD opened this issue Jul 22, 2021 · 4 comments
Closed
Labels
question Further information is requested

Comments

@DrDaveD
Copy link
Contributor

DrDaveD commented Jul 22, 2021

It's not really explained in the README, so I have a question. How do most people obtain the vault tokens to get access to the creds paths for this plugin? I don't understand how its useful to use the builtin oidc flows to obtain a refresh token without at the same time providing a vault token associated with a policy that provides access to the corresponding creds.

This is why I have been using the hashicorp/vault-plugin-auth-jwt plugin to do authentication and associate it with a policy, and then pass its refresh_token on to this plugin. It requires using a pull request that the maintainers have expressed an interest in but haven't merged for over a year, so if there were a way that I could use only this plugin that would be great. I just don't see how it can be done with only a secrets plugin.

@impl
Copy link
Member

impl commented Jul 25, 2021

Obviously I can't speak for anyone else, but here's an idea of how we use this plugin in Relay:

Our Vault clients are typically one of our internal APIs, either part of our configuration interface that users use to input new connection information, which is authenticated using Kubernetes service accounts; or our metadata API, which authenticates using a JWT, but one provided by our internal services and not OIDC. We're not directly connecting provider users through this plugin to Vault.

An example flow for writing/reading credentials would look like:

  1. Customer creates account and gets access to our web UI/API.
  2. Customer requests to associate their GitHub account with their Relay account.
  3. Our API requests an auth code URL from the plugin for the GitHub provider and returns that to our web UI.
  4. Our web UI sends the customer through the OAuth flow for GitHub and receives the result at some /callback?code=abc123 path.
  5. Web UI submits the code through to our API, which then writes the code to creds/some-account-id/some-connection-id.
  6. Customer creates a workflow and references the name of the connection they just created (for example, to create a step that opens a PR on GitHub).
  7. When the customer runs the workflow, we issue a JWT internally (by looking up their account record in our database first) that can be used to authenticate to Vault with a policy that allows reading from creds/some-account-id/*.
  8. The JWT gets encrypted and placed onto some metadata in our Kubernetes cluster, and when a step in the workflow needs to read that connection data, we proxy the request to Vault and log in with that JWT first.

Is that helpful at all? I think it's fairly different from the way you use it, but of course it's hard to tell without going into more depth about your infrastructure configuration. We're firmly in the multitenant SaaS space for how we use the plugin, though.

@impl impl added the question Further information is requested label Jul 25, 2021
@DrDaveD
Copy link
Contributor Author

DrDaveD commented Aug 2, 2021

Yes, thanks Noah, that is helpful. I'm still a little unclear on a couple of points though:

  1. Is a vault token needed for any of the steps 1 to 5? If so, where does it come from? I imagine it can be done with a statically created token that your web api holds and gives write access to creds/*.
  2. How exactly do you associate an internally-generated JWT from step 7 with a Vault policy?

@impl
Copy link
Member

impl commented Aug 9, 2021

Yes, thanks Noah, that is helpful. I'm still a little unclear on a couple of points though:

  1. Is a vault token needed for any of the steps 1 to 5? If so, where does it come from? I imagine it can be done with a statically created token that your web api holds and gives write access to creds/*.

Steps 3 and 5 require a Vault token. It could be statically created, but in our case, we use the Kubernetes auth method to authenticate a specific service account. You're correct in that it only has write access.

  1. How exactly do you associate an internally-generated JWT from step 7 with a Vault policy?

We use the JWT auth plugin, just not in an OIDC configuration. We only need to configure Vault with the JWT signer's public key. Our installation process looks roughly like this:

# Load the public key from somewhere.
jwt_pubkey="$(curl ...)"

# Enable the plugin.
vault auth enable -path=jwt-tenants jwt

# Set the public key configuration.
jq -n --arg jwt_validation_pubkey "${jwt_pubkey}" '{
    "jwt_validation_pubkeys": [$jwt_validation_pubkey],
    "jwt_supported_algs": ["RS256", "RS512"]
}' | vault write auth/jwt-tenants/config -

# Create a role for authentication.
vault write auth/jwt-tenants/role/tenant - <<EOT
{
    "name": "tenant",
    "role_type": "jwt",
    "bound_audiences": ["k8s.relay.sh/metadata-api/v1"],
    "user_claim": "relay.sh/tenant-id",
    "token_type": "batch",
    "token_policies": ["tenant"],
    "claim_mappings": {
        "relay.sh/domain-id": "domain_id",
        "relay.sh/tenant-id": "tenant_id"
    }
}
EOT

jwt_accessor="$(vault auth list -format=json | jq -r '."jwt-tenants/".accessor')"

# Write the policy with specific restrictions based on the JWT.
vault policy write tenant - <<EOT
path "customers-oauth/creds/{{identity.entity.aliases.${jwt_accessor}.metadata.tenant_id}}/*" {
    capabilities = ["read"]
}
EOT

Then a JWT signed by $jwt_pubkey can be authenticated to the tenant role and by association gets the tenant policy.

@DrDaveD
Copy link
Contributor Author

DrDaveD commented Aug 11, 2021

Very clever, I don't think I would have thought of anything like that. Thanks for the details.

@DrDaveD DrDaveD closed this as completed Aug 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants