Documentation
¶
Overview ¶
Package cloudcred is where the two Burrow Cloud credentials live on disk, and the only place that decides which file is which.
Signing in issues a pair (cloud ADR-0028 §2): the person's, which authenticates `burrow`, and the agent's, which authenticates `burrow-agent`. They are two files rather than one so that revoking either leaves the other working — losing a laptop and cutting off the agent that runs on it are different decisions, and a single credential cannot express both.
Both files hold a token, so both are written to a fresh O_EXCL temporary and renamed into place under a 0700 directory. That gives three properties os.WriteFile does not: the token is never on disk under permissions somebody else set (WriteFile applies its mode only when it CREATES the file, so an existing 0644 file would stay 0644 while holding a credential); a symlink where the destination should be cannot redirect the token out of the directory; and a reader never sees a half-written file.
Nothing here ever puts a token in an error, a log line, or a returned string. An error message is the most likely place for a credential to end up somewhere it was never meant to be, so the errors below carry the PATH and never the contents — including the JSON decoder's own error, which is deliberately dropped rather than wrapped, because a syntax error quotes the byte it choked on and that byte can be part of a token.
Index ¶
- Constants
- Variables
- func Dir(kind Kind) (string, error)
- func Path(kind Kind) (string, error)
- func RejectedMessage(cred Credential) string
- func Store(kind Kind, cred Credential) (string, error)
- func Transport(baseURL string, kind Kind, clientName, version string) (client.Transport, error)
- type Credential
- type Kind
Constants ¶
const File = localconfig.CloudEndpoint + ".json"
File is the credential file's name. It is the endpoint, so a second managed endpoint would be a second file rather than an overwrite, and the extension says what is inside.
Variables ¶
var ErrNotSignedIn = errors.New("not signed in to Burrow Cloud")
ErrNotSignedIn reports that no credential of the requested kind is on disk. Callers match on it to distinguish "never signed in" from "signed in and something is wrong with the file".
Functions ¶
func Path ¶
Path returns the file a credential of this kind is read from and written to. It is the single answer to "where is it", used by both the writer and the reader, so the two cannot drift into writing one place and reading another.
func RejectedMessage ¶
func RejectedMessage(cred Credential) string
RejectedMessage is what a refused credential says. A person who signed in yesterday and is unauthorized today has one likely explanation and one action, and both belong in the message: the credential was revoked, and signing in again replaces it. A bare 401 says neither.
The credential's id is included so it can be matched against the console's list, which is the whole reason the id is stored. It is an identifier, not the token; the token appears nowhere.
func Store ¶
func Store(kind Kind, cred Credential) (string, error)
Store writes one credential to its kind's path, 0600 under a 0700 directory, and returns the path it wrote. MkdirAll only applies its mode on creation, so an existing directory is tightened explicitly rather than trusted.
func Transport ¶
Transport builds the control-plane transport for a Burrow Cloud target: the stored credential of the given kind, presented as a bearer credential over HTTPS (ADR-0078 §1). There is no cluster in the path, so there is no API-server proxy to route through and no install Secret to read a token out of — the credential sign-in produced is the whole of the authentication.
The kind is a parameter because the two binaries hold different credentials on purpose: `burrow` spends the person's and `burrow-agent` spends the agent's, so revoking one does not revoke the other (cloud ADR-0028 §2). Passing the wrong kind would spend the wrong credential, which is why Load also checks what the file says it is.
The token is read here and goes straight into the transport. It is never returned, printed, or put in an error.
Types ¶
type Credential ¶
type Credential struct {
Endpoint string `json:"endpoint"`
Kind Kind `json:"kind"`
TenantID string `json:"tenantId"`
CredentialID string `json:"credentialId"`
Name string `json:"name,omitempty"`
Token string `json:"token"`
}
Credential is one stored token and the facts needed to act on it: which endpoint it is for, which tenant it is scoped to, and the id the console's credential list addresses it by, so revoking the right row does not mean guessing.
func Load ¶
func Load(kind Kind) (Credential, error)
Load reads the credential of this kind. Every failure names the path and says to sign in again, because that is the one action that fixes all of them, and none of them quotes the file's contents.
type Kind ¶
type Kind string
Kind is which of the pair a credential is. It is stored in the file as well as implied by the directory, so somebody who opens one can see what they are holding without inferring it from the path — and so a file that ends up in the wrong directory is caught rather than spent.