[Bug] Vault accepts a value it later refuses to inject, and the audit trail cannot separate refused from absent

Aperta
#68 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
go

Direzione di ricerca

Start with the fs-vault create-secret, replace-secret, run-with-secret, read-secret, and list-audit-events command paths, then reproduce both cases from the issue. Check where field values are validated and where delegated reads become audit events. Done means invalid values are refused on write and the audit trail distinguishes denied access to an existing field from a missing field.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

ti version

0.2.7 (6c950c77a601d0d55394c4b2f64483ae93d522db, 2026-09-27), bundled ti-drive9 companion 60b63d6

Command family

fs-vault

Operating system and architecture

macOS 14.6, darwin/arm64, for both problems. Problem 1 was also seen on Ubuntu, linux/amd64.

Summary

One validation problem and one question about the audit trail.

Covers observations 7 and 4 from a review of the TiDB Cloud Filesystem documentation.

Problem 1: a control byte is accepted on write and refused on use

Command
ti fs-vault create-secret --secret-name ctl --field K="$(printf 'ab\001cd')"
ti fs-vault run-with-secret --secret-path /n/vault/ctl -- /bin/sh -c 'echo injected'
Reproduction steps
  1. Create or replace a secret whose field value contains a control byte.
  2. Observe that the command reports success.
  3. Run run-with-secret to inject that field.
Expected behavior

The write is refused, at the moment the value is supplied, naming the offending byte.

Actual behavior

create-secret and replace-secret both accept the value and report success at exit 0.
run-with-secret then refuses to inject it at exit 1:

ti [ERROR]: vault with: secret value for key "K" contains forbidden control byte 0x01 at offset 2

A secret with a clean value runs normally through the same command, which confirms the refusal
is about the stored value rather than the invocation. The secret is stored in a state where it cannot
be used, and the caller only discovers this at the point of use, which may be much later and
in a different place.

Validating at write time would remove the failure entirely. As it stands the documentation has
to warn readers about a value the product accepted without complaint, which is a weaker
remedy.

Problem 2: a delegated read cannot be told apart from a missing field

Command
ti fs-vault create-grant --scope db/DB_URL --permission read --agent-id a1 --ttl 30m --token-only
ti fs-vault read-secret --secret-name db --field PASSWORD --vault-token "<delegated-token>"
ti fs-vault read-secret --secret-name db --field NOPE --vault-token "<delegated-token>"
ti fs-vault list-audit-events --output text
Reproduction steps
  1. Grant a delegated token access to one field of a secret.
  2. Read a different field of that secret with it.
  3. Read a field that does not exist at all.
  4. Compare the messages and the audit entries.
Actual behavior

Both cases return vault get: not found at exit 1, and both record secret.denied in the audit
trail. The granted field reads normally at exit 0.

  DB_URL     exit=0
  PASSWORD   exit=1   vault get: not found
  NOPE       exit=1   vault get: not found

TIME                  AGENT  ACTION          SECRET  FIELD
2026-09-28T03:42:11Z  a1     secret.denied   db      NOPE
2026-09-28T03:42:11Z  a1     secret.denied   db      PASSWORD
2026-09-28T03:42:11Z  a1     secret.read     db      DB_URL

Note that NOPE appears in the FIELD column as though it were a real field of the secret.

Hiding existence from the caller is a common and defensible vault design, so the message may
well be deliberate. The part worth asking about is the audit trail. An auditor reading
secret.denied cannot tell whether someone was refused access to a field that exists or asked
for a field that never existed. Those are different events, and only one of them is worth
investigating.

This is a question rather than a bug report. Please confirm whether the current behaviour is
intended, and if so I will document it as designed.

Sensitive-data confirmation

No API keys, file system or Vault tokens, database credentials, connection strings, SQL, or
customer data appear above. No real secret values are reproduced. File systems used for these
measurements were deleted afterwards.

Lingua principale
Go
Stelle
3
Fork
4
Merge medio
3g 19h
PR unite (30g)
5

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di tidbcloud/ti-cli

Tutte le issue di tidbcloud/ti-cli

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.