Skip to content

Show real token expiry by parsing the JWT exp claim instead of the requested value #4

@saadqbal

Description

@saadqbal

Problem

`tracebloc cluster info` prints:

```
expires in: ~10m0s (server may cap shorter)
```

That's the *requested* expiration. The kube-apiserver may cap shorter via `--service-account-max-token-expiration` (often set to 1h or shorter on hardened clusters). Customers reading the displayed value and pasting it into a script expecting that exact validity window get confusing 401s when the token actually expires earlier.

Fix

After `MintIngestorToken` succeeds, parse the JWT's `exp` claim and show the actual expiration window:

```go
import "github.com/golang-jwt/jwt/v5" // or hand-roll: the JWT payload is base64-decoded JSON

claims := jwt.MapClaims{}
// JWT format: header.payload.signature; we only need the payload
parts := strings.Split(tok.Token, ".")
if len(parts) == 3 {
payload, _ := base64.RawURLEncoding.DecodeString(parts[1])
_ = json.Unmarshal(payload, &claims)
if exp, ok := claims["exp"].(float64); ok {
actualExp := time.Until(time.Unix(int64(exp), 0))
printf "expires in: %s (server-decided)", actualExp
}
}
```

Hand-rolling avoids the jwt dep + signature-validation complexity — we don't need to verify the token, we just want to read its expiry.

Static-secret tokens are unbounded; existing "never (static-secret fallback)" message stays accurate.

Acceptance criteria

  • A TokenRequest-minted token with a server-capped expiration displays the capped value, not the requested one
  • The displayed window decrements correctly across multiple invocations of the same minted token (verify by storing + re-displaying)
  • Static-secret path unchanged
  • Malformed JWT (truncated, wrong format) falls back gracefully to the requested-value display rather than crashing

Found by

Self-review of PR #2. Filed as v0.2 hardening; the existing display is accurate-enough for the MVP and the misleading-window concern doesn't actually break any v0.1 flow (the token is short-lived enough that customers don't keep it around).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions