diff --git a/audit/format.go b/audit/format.go index 86b00f8a25..919da125e4 100644 --- a/audit/format.go +++ b/audit/format.go @@ -102,9 +102,10 @@ func (f *AuditFormatter) FormatRequest( Error: errString, Auth: AuditAuth{ - DisplayName: auth.DisplayName, - Policies: auth.Policies, - Metadata: auth.Metadata, + DisplayName: auth.DisplayName, + Policies: auth.Policies, + Metadata: auth.Metadata, + RemainingUses: req.ClientTokenRemainingUses, }, Request: AuditRequest{ @@ -255,6 +256,7 @@ func (f *AuditFormatter) FormatResponse( DisplayName: resp.Auth.DisplayName, Policies: resp.Auth.Policies, Metadata: resp.Auth.Metadata, + NumUses: resp.Auth.NumUses, } } @@ -362,11 +364,13 @@ type AuditResponse struct { } type AuditAuth struct { - ClientToken string `json:"client_token"` - Accessor string `json:"accessor"` - DisplayName string `json:"display_name"` - Policies []string `json:"policies"` - Metadata map[string]string `json:"metadata"` + ClientToken string `json:"client_token"` + Accessor string `json:"accessor"` + DisplayName string `json:"display_name"` + Policies []string `json:"policies"` + Metadata map[string]string `json:"metadata"` + NumUses int `json:"num_uses,omitempty"` + RemainingUses int `json:"remaining_uses,omitempty"` } type AuditSecret struct { diff --git a/http/handler.go b/http/handler.go index a12a83c62b..fb9b7a8a1e 100644 --- a/http/handler.go +++ b/http/handler.go @@ -274,6 +274,7 @@ func requestAuth(core *vault.Core, r *http.Request, req *logical.Request) *logic te, err := core.LookupToken(v) if err == nil && te != nil { req.ClientTokenAccessor = te.Accessor + req.ClientTokenRemainingUses = te.NumUses } } diff --git a/logical/request.go b/logical/request.go index 4a3f85bf7e..1c4f88bbff 100644 --- a/logical/request.go +++ b/logical/request.go @@ -85,6 +85,10 @@ type Request struct { // WrapInfo contains requested response wrapping parameters WrapInfo *RequestWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info"` + // ClientTokenNumUses represents the allowed number of uses left on the + // token supplied + ClientTokenRemainingUses int `json:"client_token_remaining_uses" structs:"client_token_remaining_uses" mapstructure:"client_token_remaining_uses"` + // For replication, contains the last WAL on the remote side after handling // the request, used for best-effort avoidance of stale read-after-write lastRemoteWAL uint64 diff --git a/vault/audit_test.go b/vault/audit_test.go index 344605bc0a..5e97da86f4 100644 --- a/vault/audit_test.go +++ b/vault/audit_test.go @@ -444,6 +444,7 @@ func TestAuditBroker_LogResponse(t *testing.T) { b.Register("bar", a2, nil) auth := &logical.Auth{ + NumUses: 10, ClientToken: "foo", Policies: []string{"dev", "ops"}, Metadata: map[string]string{ diff --git a/vault/router.go b/vault/router.go index c691c745a7..dd2d23220b 100644 --- a/vault/router.go +++ b/vault/router.go @@ -283,6 +283,10 @@ func (r *Router) routeCommon(req *logical.Request, existenceCheck bool) (*logica // Cache the identifier of the request originalReqID := req.ID + // Cache the client token's number of uses in the request + originalClientTokenRemainingUses := req.ClientTokenRemainingUses + req.ClientTokenRemainingUses = 0 + // Cache the headers and hide them from backends headers := req.Headers req.Headers = nil @@ -304,6 +308,7 @@ func (r *Router) routeCommon(req *logical.Request, existenceCheck bool) (*logica req.ID = originalReqID req.Storage = nil req.ClientToken = clientToken + req.ClientTokenRemainingUses = originalClientTokenRemainingUses req.WrapInfo = wrapInfo req.Headers = headers // This is only set in one place, after routing, so should never be set diff --git a/vault/token_store.go b/vault/token_store.go index 37154dace0..1cd611ca0a 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -1689,6 +1689,7 @@ func (ts *TokenStore) handleCreateCommon( // Generate the response resp.Auth = &logical.Auth{ + NumUses: te.NumUses, DisplayName: te.DisplayName, Policies: te.Policies, Metadata: te.Meta,