jfrog / vault-plugin-secrets-artifactory

HashiCorp Vault Secrets Plugin for Artifactory
https://jfrog.com
Apache License 2.0
41 stars 20 forks source link

Token lease not being respected #22

Closed apr-1985 closed 1 year ago

apr-1985 commented 1 year ago

Artifactory version: 7.33.12 Vault Version: 1.12.2 Artifactory Plugin version: 0.2.0

I have set the Artifactory vault plugin following the instructions here https://www.jfrog.com/confluence/display/JFROG/Hashicorp+Vault+Artifactory+Secrets+Plugin

However when I request a token with a 1h lease even though the plugin returns the lease is for 1h it is valid of 1 YEAR in Artifactory.

❯ vault write artifactory/roles/ci \
∙ username="<redacted>" \
∙ scope="applied-permissions/groups:<redacted>" \
∙ default_ttl=1h max_ttl=3h
Success! Data written to: artifactory/roles/ci

Token has a lease_duration of 1h

❯ vault read artifactory/token/ci
Key                Value
---                -----
lease_id           artifactory/token/ci/xpFDZ5qdWmnaHUP49BLZl2ag
lease_duration     1h
lease_renewable    true
access_token       ey<redacted>
role               ci
scope              applied-permissions/groups:<redacted>
token_id           b79872ec-b8fc-4f1e-b7e0-53443e2aa578

But in Artifactory the token lives for a year

{
    "token_id" : "b79872ec-b8fc-4f1e-b7e0-53443e2aa578",
    "subject" : "jfac@01e7hr4k76vr470nkn64m81n3n/users/<redacted>",
    "expiry" : 1702977006,
    "issued_at" : 1671441006,
    "issuer" : "jfac@01e7hr4k76vr470nkn64m81n3n",
    "refreshable" : false
  }
apr-1985 commented 1 year ago

It looks like the lease is explicitly set to never expire which I guess means the token takes the access default (in my case the default of 1year). https://github.com/jfrog/artifactory-secrets-plugin/blob/master/artifactory.go#L89

I waited over 1 hour to check if Vault would revoke the token, but 90 minutes later and the token is still valid.

TJM commented 1 year ago

The way it is supposed to work is that Vault will "revoke" that token at the end of the lease. The fact that you also posted about an error revoking the admin token during rotation makes me wonder whether there is an error in the "RevokeToken" function.

It does also seem like the "max_ttl" should be enforced by setting that as the artifactory access token expiration, by default, but it does not do that, perhaps related to artifactory "issues" -- https://github.com/jfrog/artifactory-secrets-plugin/blob/v0.2.0/artifactory.go#L80-L89

EDIT: There was some information in https://jfrog.atlassian.net/browse/RTFACT-15293?focusedCommentId=66023 that indicates that the tokens are "successfully" (200) revoked, and removed from the token list, but that they still work. I consider this to be a serious problem, but this issue was closed (deferred). Perhaps @alexhung can check into this on their side?

alexhung commented 1 year ago

@TJM Thanks for bringing this to my attention. I'll take a quick look.

cc @mritunjaykumar

apr-1985 commented 1 year ago

Thanks for looking into this. Revoked tokens that still work is IMO a rather large security issue, especially with API keys going away soon. Leavers would be able to access the system until their access token expired, same with any accidentally leaked tokens.....

It also rather invalidates the point of this Vault plugin somewhat if tokens that Vault revokes live on till the Expiry.

Let me know if I can help in any way.

apr-1985 commented 1 year ago
vault read af_new/token/ci
Key                Value
---                -----
lease_id           af_new/token/ci/W7qfY4<SNIP>cTQ0in30
lease_duration     1h
lease_renewable    true
access_token       eyJ2Z<SNIP>cA
role               ci
scope              applied-permissions/groups:<SNIP>
token_id           411e0119-6aca-4bef-b498-cfc27296725d

In Artifactory token id 411e0119-6aca-4bef-b498-cfc27296725d shows up in the non-revocable tokens list with an expiry of 1 year which I guess is why Vault cannot revoke it after the 1h lease_duration.

I guess there is a bug in Artifactory that is not respecting the passing of values.Set("expires_in", "0") as a never expires token (same in the UI as mentioned in my other issue).

alexhung commented 1 year ago

@apr-1985 From my (albeit very quick) testing in 7.49.3, setting the expires_in field to 0 in the POST /access/api/v1/tokens request works to create a non-expiring token. There's no expires_in field when GET /access/api/v1/tokens and no expiry date in the web UI. I am able to revoke by DELETE /access/api/v1/tokens/{id}.

When I create a token with expires_in set to a non-zero value (say 900 = 15 min), I was not able to revoke it which is correct behavior.

{
    "code": "BAD_REQUEST",
    "message": "Token not revocable",
    "detail": "Token not revocable. Token expirationTimeMillis: 1673028200098, issuedAtMillis: 1673027300098, revocableExpiryThresholdMillis: 21600000"
}
apr-1985 commented 1 year ago

Thanks @alexhung It sounds like all my issues here are from being on an "older" version of Artifactory and recent changes to tokens should have fixed them.

I will try and get a demo licence next week and test.

TJM commented 1 year ago

FWIW, I tested this using the same version of Vault and Artifactory, but was unable to reproduce. I set the lease time to 5m so I didn't have to wait quite as long, but as soon as the lease expired, I saw this in the logs:

2023-01-06T15:57:04.686-0700 [INFO]  expiration: revoked lease: lease_id=artifactory/token/jenkins/TJGyjp5rHPs5zVY1gvQ2UjyF

... then immediately attempted to use it:

$ curl -H "Authorization: Bearer $JENKINS_TOKEN" -H "Content-type: application/json" http://127.0.0.1:8082/access/api/v1/cert/root
{
  "errors" : [ {
    "code" : "UNAUTHORIZED",
    "message" : "Bearer authentication failed, invalid token"
  } ]
}

So, I think the problem is that for some reason tokens are not being properly revoked on your system. I don't think this is a problem with the plugin itself. It may be the initial admin token does not have the ability to revoke tokens by ID or it may be that there is something else. I think once we solve the error on rotation in #23 this one will resolve itself. The "revoke" (DELETE) token command is the same for the end of a lease and rotating an admin token.