Skip to main content

Secret API

Table of Contents

Top

upsquad/secret/v1/secret.proto

DescribeRequest

DescribeRequest addresses one secret for metadata-only lookup.

FieldTypeLabelDescription
secret_idstringThe logical id of the secret to describe.

DescribeResponse

DescribeResponse returns metadata-only fields for a named secret. The value field is deliberately absent; callers that attempt to add one are rejected by the CI grep-gate.

FieldTypeLabelDescription
secret_idstringLogical id of the secret described.
last_rotated_atgoogle.protobuf.TimestampUTC timestamp of the most recent rotation, or null when the secret has never been rotated.
last_rotated_bystringActor principal id of the most recent rotate, or empty when the secret has never been rotated.
last_rotated_by_clearanceint32Actor clearance at last rotation, or 0 when the secret has never been rotated.
presentboolTrue when the secret has a non-empty value stored in the backend. False when the secret has never been rotated or was removed.
version_idstringOpaque version tag (`sha256(value

RotateRequest

RotateRequest carries the new plaintext secret value. The value field is scrubbed from all log lines and audit event payloads by the reflection-based RedactInterceptor (internal/secret/redact.go) BEFORE the request reaches any logger, tracer, or audit sink. Callers never put tenant_id in the request body — it is taken from the authenticated context, not from the wire.

FieldTypeLabelDescription
secret_idstringThe logical id of the secret, e.g. "hmac.signing_key", "scm.github.app_private_key". Stable across rotations — every rotate of the same secret reuses the same secret_id. L3 read clearance so the Describe widget can label the input; L5 edit clearance because changing the secret_id reference on a caveman form is a platform-operator action.
valuebytesThe new plaintext value as opaque octets. HLD §2.3 locks bytes (not string) — secrets are binary (X25519 private keys, PEM blocks, signed tokens) and MUST NOT be forced through UTF-8 validation. Hard max 4096 bytes; larger payloads are rejected at the service boundary before any backend I/O. This field is scrubbed by the RedactInterceptor via the edit_clearance=L5 annotation — any future bytes field tagged L5 is scrubbed automatically.

RotateResponse

RotateResponse returns metadata about the just-written secret. NEVER includes the value. All fields are L3-readable metadata — the widget labels (HLD §2.5) consume them.

FieldTypeLabelDescription
secret_idstringLogical id of the secret that was rotated (echoed from the request).
last_rotated_atgoogle.protobuf.TimestampUTC timestamp the rotation was committed to the backend. Renders in the widget label "Last rotated: {last_rotated_at} by …".
last_rotated_bystringActor principal id (Clerk user id or platform-service id). Populated by the service layer at commit time from authctx.ClerkUserID(ctx); never trusted from the request body.
last_rotated_by_clearanceint32Actor clearance at commit time (1..5 — mirrors the caveman ClearanceLevel enum ordinals; HLD §2.3 locks int32 on the wire). Populated by the service layer from authctx.ClearanceLevel(ctx).
version_idstringOpaque version identifier — `sha256(value

SecretRef

SecretRef references a secret by id without carrying its value. Config protos embed this whenever a field carries a secret; the generator (LLD-3) emits the write-only Rotate widget whenever a field's type is SecretRef.

FieldTypeLabelDescription
secret_idstringLogical id of the referenced secret.

SecretWriteService

SecretWriteService manages named secrets with a write-only surface.

NO Get / View / Read / Reveal RPC is present or permitted. The CI grep-gate at .github/workflows/secret-grep-gate.yml rejects any PR that adds one (LLD-2 #766 §7 Definition of Done).

Method NameRequest TypeResponse TypeDescription
RotateRotateRequestRotateResponseRotate sets or rotates the value of a named secret for the caller's tenant. Clearance L5 required (enforced at the gateway interceptor AND in the service layer — defence in depth). The plaintext value is scrubbed from all logs, spans, and audit payloads by the reflection-based RedactInterceptor BEFORE any sink is written.
DescribeDescribeRequestDescribeResponseDescribe returns metadata for a named secret (secret_id, last_rotated_at, last_rotated_by, last_rotated_by_clearance, version_id, presence). NEVER returns the value. Clearance L3 required (tenant admin + above).

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)