Documentation
¶
Overview ¶
Package secretref is the reference to a stored secret a caller writes into a request, `{{secret:<name>}}`, and the redaction of a secret's value from whatever comes back (#2051).
A placeholder is filled at the last moment, as the request is built for sending, so everything that records the call (the audit row, the call record, a script's recording, the arguments a cut response hands back) holds the placeholder and never the value. What the upstream sends back is then put through a Redactor holding the values the request carried, so an upstream that echoes one cannot hand it to the caller.
The package knows nothing about where secrets are stored or who may use them: a Lookup answers for one name, and refuses by name.
Index ¶
- Constants
- Variables
- func Fill(s string, lookup Lookup, escape func(string) string) (string, error)
- func FillPath(path string, lookup Lookup) (string, error)
- func FillStrings(m map[string]string, lookup Lookup) (map[string]string, error)
- func FillValue(v any, lookup Lookup) (any, error)
- func JSONString(s string) string
- func Raw(s string) string
- func Redaction(name string) string
- func Transport(base http.RoundTripper) http.RoundTripper
- func ValidName(name string) bool
- type Lookup
- type Redactor
- func (r *Redactor) Add(name, value string)
- func (r *Redactor) Bytes(b []byte) []byte
- func (r *Redactor) Empty() bool
- func (r *Redactor) Error(err error) string
- func (r *Redactor) Reader(src io.ReadCloser) io.ReadCloser
- func (r *Redactor) Recording(lookup Lookup) Lookup
- func (r *Redactor) String(s string) string
- func (r *Redactor) Strings(h map[string][]string)
- type Request
Constants ¶
const MinValueLength = 6
MinValueLength is the shortest value a secret may hold. Redaction replaces every occurrence of a value in a response, and a value of a character or two would rewrite ordinary text.
const NamePattern = `[a-z0-9][a-z0-9_.-]{0,62}`
NamePattern is the grammar of a secret's name: lower case, digits, and . _ - after the first character. It is narrow so a name reads the same in a placeholder, a URL and a log line.
Variables ¶
var ErrMalformed = errors.New("malformed secret placeholder")
ErrMalformed is wrapped by the refusal of text that opens a placeholder and does not complete one.
Functions ¶
func Fill ¶
Fill replaces each placeholder in s with its secret's value as escape writes it. A placeholder whose lookup fails fails the fill, and so does text that opens a placeholder without completing one: neither is ever sent as written.
func FillPath ¶
FillPath fills the placeholders of a request path, in either form a path carries one: as the caller wrote it, or with its braces escaped by path_params substitution. The value is path-escaped, so it cannot add a segment.
func FillStrings ¶
FillStrings fills the values of a string map, returning a copy.
func FillValue ¶
FillValue fills every string in a JSON-shaped value (maps, lists and strings, nested), returning a copy: the value the caller passed is the one recorded, and keeps its placeholders. Map keys are filled too.
func JSONString ¶
JSONString writes a value as the inside of a JSON string, for a body sent as JSON text.
func Raw ¶
Raw writes a value as it is: for a body object, query values and header values, which are encoded on their way out.
func Transport ¶
func Transport(base http.RoundTripper) http.RoundTripper
Transport wraps base so that a response to a request whose context carries a Redactor with values in it comes back with them redacted: from every header value, and from the body as it is read, however it is read. A request that filled no placeholder passes through untouched.
The redacted body is a different length from the one the upstream sent, so its declared length is dropped.
Types ¶
type Lookup ¶
Lookup returns a secret's value, or an error that names the secret and says why it may not be used here.
type Redactor ¶
type Redactor struct {
// contains filtered or unexported fields
}
Redactor replaces the values of the secrets one call used with their redaction. A call adds each value as it fills it; the response side then passes everything it returns through the Redactor.
Each value is matched as written and in the forms an upstream echoes one in: escaped inside a JSON string (once, or twice for a JSON body echoed inside JSON), and query- and path-escaped.
func FromContext ¶
FromContext is the call's Redactor, or nil when the call made none, which every method treats as empty.
func WithRedactor ¶
WithRedactor returns ctx carrying a fresh Redactor, and the Redactor, for one call: the request side adds to it, the response side reads it.
func (*Redactor) Empty ¶
Empty reports whether no value was recorded, so a caller can skip the pass over a response that cannot need it.
func (*Redactor) Reader ¶
func (r *Redactor) Reader(src io.ReadCloser) io.ReadCloser
Reader redacts a stream, for a response written somewhere without being held whole. It holds back the bytes that could be the start of a value until the next read shows whether they are.
func (*Redactor) Recording ¶
Recording returns lookup with every value it answers recorded on r, so the response to the request it fills is redacted of them.
type Request ¶
type Request struct {
Path string
Headers map[string]string
Query map[string]any
Body any
ContentType string
}
Request is the parts of an outbound request a placeholder may sit in. ContentType is the type the body will be sent as, which says how a value written into a string body is escaped.