Help us shape the future of Go! Take the 2026 Go Developer Survey

connection

package
v0.2.51 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MPL-2.0 Imports: 33 Imported by: 0

Documentation

Overview

Package connection is a principal's identity at an outside service: Alice's GitHub account, a pony's own machine account, an app installation acting for a team. The chassis holds the credential and renews it; a stack names the connection and never sees a token (docs/todo-connections.md in the service overlay).

Two declarations take part, both small YAML files a stack deploys, parsed at apply and activate like SANDBOXES/ and CAPS/:

OPS/<stack>/PROVIDERS/<name>.yaml     how authentication at the service
                                      works, where each credential may go,
                                      and which stacks may use it (one
                                      active stack per name in a tenant)
OPS/<stack>/CONNECTIONS/<provider>.yaml  how THIS stack uses an identity:
                                      the origins it calls, the header the
                                      token goes on

A connection's identity is (tenant, principal, provider, label), never a stack: moving a provider's file to another stack changes no row.

This file is the leaf layer: the reserved-path vocabulary, with no dependency on stores, so the CLI, the admin producer and the control-event applier can import it cheaply.

Index

Constants

View Source
const (
	// KindOAuth2 is the authorization-code flow: the person signs in, the
	// chassis holds and renews the tokens.
	KindOAuth2 = "oauth2"
	// KindGitHubApp is OAuth 2 plus the app's own key, which mints
	// installation tokens (a later slice). Its user flow is oauth2's.
	KindGitHubApp = "github_app"
)

Provider kinds: how authentication at the service works.

View Source
const (
	// CredentialOAuth2 is a user access token (and its refresh token).
	CredentialOAuth2 = "oauth2"
	// CredentialInstallation is a GitHub App installation token, minted
	// from the app's key (a later slice).
	CredentialInstallation = "github_app_installation"
)

Credential kinds: which credential a consumer uses, and what a row holds.

View Source
const (
	ClientAuthBody  = "body"
	ClientAuthBasic = "basic"
)

How the client authenticates at the token destination.

View Source
const (
	// RotationSingleUse: a refresh token works once; the answer carries the
	// next one. Re-sending a used one is refused, and may end the family.
	RotationSingleUse = "single_use"
	// RotationReusable: the refresh token stays valid until revoked.
	RotationReusable = "reusable"
)

Refresh-token rotation, the provider's own behaviour, declared rather than assumed.

View Source
const (
	// OnUncertainReconnect: the old refresh token is never re-sent; the
	// current access token serves until it expires, then the owner
	// reconnects.
	OnUncertainReconnect = "reconnect"
	// OnUncertainRetry: one more try, under a new claim.
	OnUncertainRetry = "retry"
)

What follows a renewal whose outcome is unknown (a timeout after the request was sent, a claim its holder never completed).

View Source
const (
	MaxTitle     = 64
	MaxScopes    = 32
	MaxOrigins   = 16
	MaxConsumers = 64
)

Ceilings on one declaration.

View Source
const (
	DefaultMarginFraction = 0.2
	DefaultMarginFloorS   = 60
	DefaultMarginCeilingS = 900
)

Margin defaults: renewal starts when a fifth of the lifetime is left, never under a minute before expiry, never more than 15 minutes before — and never in a token's first half-life (Provider.Margin).

View Source
const (
	ProviderDir = "PROVIDERS"
	ConsumerDir = "CONNECTIONS"
	DeclExt     = ".yaml"
)

Reserved top-level directories and the declaration extension.

View Source
const (
	CodeInvalidArg  = "invalid_arg"
	CodeNotDeclared = "not_declared"
	CodeUnsupported = "unsupported"
	CodeNoClient    = "no_client" // the client id or secret is not set
	CodeStore       = "store"
	CodeBadState    = "bad_state"
	CodeExpired     = "expired"
	CodeGone        = "gone" // the flow was used or has expired
	CodeMismatch    = "mismatch"
	CodeRefused     = "refused" // the provider refused the code or the sign-in
	CodeUnavailable = "unavailable"
	CodeMissing     = "missing"
	CodeReconnect   = "reconnect"
	CodeBusy        = "busy"
	CodeDestination = "destination"
	CodeDenied      = "denied"
)

Error codes.

View Source
const (
	StatusActive    = "active"
	StatusUncertain = "uncertain" // a renewal's outcome is unknown
	StatusReconnect = "reconnect" // the provider refused the refresh token
)

Row statuses.

View Source
const CookieName = "txco_connect"

CookieName is the per-flow browser cookie `start` sets and `finish` reads. Host-only (no Domain), so a callback on another host sees none.

View Source
const (

	// FlowTTL is how long a sign-in may take.
	FlowTTL = 10 * time.Minute
)
View Source
const KeyLabel = "txco/connection/v1"

KeyLabel is the derivation label of the signing key (secrets.DeriveKey). Part of the wire contract: changing it invalidates every live flow.

View Source
const RequestTimeout = 10 * time.Second

RequestTimeout bounds one credentialed request. Shorter than the renewal claim's lease (claimLease), so a claimant that is still waiting on the provider has not lost its claim.

View Source
const SandboxConsumerPrefix = "sandbox:"

SandboxConsumerPrefix marks a consumer entry that is a sandbox of the stack, not a capability: `loop: [sandbox:github]` lets the loop's SANDBOXES/github.yaml hand the token to the work that opens it.

Variables

View Source
var (
	// ErrBadState: malformed, forged, or signed under another key.
	ErrBadState = errors.New("connection: bad state")
	// ErrStateExpired: a genuine state past its expiry.
	ErrStateExpired = errors.New("connection: state expired")
)
View Source
var (
	// ErrNotFound: the principal has no such connection.
	ErrNotFound = errors.New("connection: not found")
	// ErrFlowGone: no such flow, or it was consumed or has expired.
	ErrFlowGone = errors.New("connection: no such sign-in, or it was already used")
	// ErrFenced: the row moved on (another node renewed it, or the claim
	// was not this writer's).
	ErrFenced = errors.New("connection: write fenced")
)
View Source
var ErrNotDeclared = errors.New("connection: not declared")

ErrNotDeclared: no active stack of the tenant declares the provider, or the stack has no consumer declaration for it.

Functions

func ConsumerName

func ConsumerName(p string) string

ConsumerName returns the provider a consumer declaration names: "CONNECTIONS/github.yaml" → "github"; "" when it is not a declaration.

func ConsumerPath

func ConsumerPath(provider string) string

ConsumerPath is the stack_files path of a stack's consumer declaration for a provider.

func IsConsumerPath

func IsConsumerPath(p string) bool

IsConsumerPath reports whether a stack_files path lives under CONNECTIONS/.

func IsProviderPath

func IsProviderPath(p string) bool

IsProviderPath reports whether a stack_files path lives under PROVIDERS/.

func Loopback

func Loopback(host string) bool

Loopback reports whether host is the local machine by name or literal: the one place an http:// origin, and a dial the private guard would refuse, is allowed on a development node.

func ProviderName

func ProviderName(p string) string

ProviderName returns the provider a declaration path belongs to: "PROVIDERS/github.yaml" → "github"; "" when the path is not a declaration (nested, wrong extension, bad name) — the shape validateStackFilePath enforces at upload.

func ProviderPath

func ProviderPath(name string) string

ProviderPath is the stack_files path of a provider's declaration.

func SameIssuer

func SameIssuer(declared, got string) bool

SameIssuer reports whether a callback's `iss` names the provider's issuer: the same URL, as normalizeIssuer sees both.

func SecretName

func SecretName(ref string) (string, bool)

SecretName returns the tenant secret a `secret:NAME` reference names, or ("", false) for a literal.

func ValidName

func ValidName(s string) bool

ValidName reports whether s may name a provider.

Types

type Account

type Account struct {
	URL     string `yaml:"url"`
	Subject string `yaml:"subject"`
	Name    string `yaml:"name"`
}

Account says how to learn who signed in: a GET at URL (an api origin) with the new token; Subject is the field holding the provider's stable id, Name the field holding the display name.

type App

type App struct {
	ID         string `yaml:"id"`
	PrivateKey string `yaml:"private_key"`
}

App is a GitHub App's own credentials (kind github_app).

type Config

type Config struct {
	// Node is the node's egress guard; Open reports that its policy is
	// open (development), which allows loopback origins.
	Node egress.Guard
	Open bool
	// SlugToID resolves a tenant slug (what a request pins) to the tenant
	// id the rows key on.
	SlugToID  func(ctx context.Context, slug string) (string, error)
	UserAgent string
	Logger    *zap.Logger
}

Config is what New needs beside the store and the seams.

type Consumer

type Consumer struct {
	Provider string   `yaml:"provider"`
	Kind     string   `yaml:"kind"`
	Origins  []string `yaml:"origins"`
	Use      Use      `yaml:"use"`
	// contains filtered or unexported fields
}

Consumer is one CONNECTIONS/<provider>.yaml: how the declaring stack uses an identity at that provider.

func ParseConsumer

func ParseConsumer(data []byte) (*Consumer, error)

ParseConsumer strictly decodes and validates a consumer declaration. The file's own name (the provider it is for) is checked by the caller against Consumer.Provider.

func (*Consumer) OriginAllowed

func (c *Consumer) OriginAllowed(o Origin) bool

OriginAllowed reports whether the consumer declares o.

func (*Consumer) OriginList

func (c *Consumer) OriginList() []Origin

OriginList is the consumer's origins, parsed, in declaration order.

type Decls

type Decls interface {
	// Provider resolves (tenant slug, name) → the declaring stack and its
	// active declaration, or ErrNotDeclared.
	Provider(ctx context.Context, tenant, name string) (string, *Provider, error)
	// Consumer resolves (tenant slug, stack, provider) → the stack's active
	// consumer declaration, or ErrNotDeclared.
	Consumer(ctx context.Context, tenant, stack, provider string) (*Consumer, error)
}

Decls finds the declarations: a provider by name across the tenant's active stacks, and a stack's consumer declaration for a provider.

type Destinations

type Destinations struct {
	// Authorization is where the browser goes to sign in. No credential is
	// sent there.
	Authorization string `yaml:"authorization"`
	// Token is where a code or refresh token is exchanged: the client
	// credentials go here and nowhere else.
	Token string `yaml:"token"`
	// Revocation is "none", or an RFC 7009 endpoint the token being revoked
	// is posted to.
	Revocation string `yaml:"revocation"`
	// API is every origin an access token may be sent to; a consumer
	// narrows it to the origins it calls.
	API []string `yaml:"api"`
}

Destinations is where each credential may go. Each kind of credential reaches one kind of destination and no other (Service.send).

type Error

type Error struct {
	Code    string
	Message string
}

Error is what a caller shapes for a rule: a code (without the `txco_connection_` prefix the op adds) and a message that never holds material.

func (*Error) Error

func (e *Error) Error() string

type FinishInput

type FinishInput struct {
	Tenant, TenantID string
	Stack            string
	Host, Path       string // the request's
	Code, State      string
	Iss              string
	ProviderError    string // the provider's `error` query parameter, if any
	Cookie           string // the flow cookie's value
}

FinishInput is read from the callback request the managing stack is serving — never from a WITH clause.

type FinishResult

type FinishResult struct {
	Row         Row
	Provider    *Provider
	ClearCookie string
}

FinishResult is the stored connection's metadata and the cookie line that clears the flow cookie.

type Flow

type Flow struct {
	NonceHash   string
	TenantID    string
	PrincipalID string
	Provider    string
	Label       string
	Kind        string
	Stack       string
	RedirectURI string
	BrowserHash string
	Initiator   string
	ExpiresAt   time.Time
	ConsumedAt  *time.Time
}

Flow mirrors a connection_flows row.

type Margin

type Margin struct {
	Fraction float64 `yaml:"fraction"`
	FloorS   int     `yaml:"floor_s"`
	CeilingS int     `yaml:"ceiling_s"`
}

Margin is when renewal starts: a fraction of the lifetime, clamped.

type Material

type Material struct {
	Access  string `json:"a,omitempty"`
	Refresh string `json:"r,omitempty"`
	// TokenType is the provider's word for the access token ("bearer");
	// kept for the record, the consumer's format decides the header.
	TokenType string `json:"t,omitempty"`
}

Material is what a row holds, sealed: the tokens. It never leaves this package except as a header value on a request (Service.Use) or a form field at the token destination (renew).

type NewRow

type NewRow struct {
	TenantID, PrincipalID, Provider, Label, Kind string
	Subject, Account                             string
	Scopes                                       []string
	ExpiresAt, RefreshExpiresAt                  *time.Time
	LifetimeS                                    int64
	CreatedBy                                    string
}

NewRow is what a finished sign-in stores.

type Origin

type Origin struct {
	Scheme string
	Host   string // lower case, IDNA ASCII
	Port   string // always set: the scheme's default when the URL had none
}

An Origin is where a credential may be sent: scheme, host and port, exactly — never a host name alone, so a port the declaration did not name is refused. `https://` only, except `http://` to a loopback host on a development node.

func OriginOf

func OriginOf(u *url.URL) (Origin, error)

OriginOf is the origin a request URL reaches, normalized the same way, so a declaration and a request compare exactly.

func ParseOrigin

func ParseOrigin(s string) (Origin, error)

ParseOrigin reads "https://api.github.com" or "https://host:8443". A path other than "/" (or none), a query, a fragment or user info is refused: an origin names a place, not a resource.

func (Origin) String

func (o Origin) String() string

String is the canonical form: the default port left out.

type Provider

type Provider struct {
	Title        string              `yaml:"title"`
	Kind         string              `yaml:"kind"`
	Issuer       string              `yaml:"issuer"`
	Destinations Destinations        `yaml:"destinations"`
	ClientID     string              `yaml:"client_id"`
	ClientSecret string              `yaml:"client_secret"`
	ClientAuth   string              `yaml:"client_auth"`
	PKCE         bool                `yaml:"pkce"`
	Scopes       []string            `yaml:"scopes"`
	Account      *Account            `yaml:"account"`
	Refresh      Refresh             `yaml:"refresh"`
	App          *App                `yaml:"app"`
	Consumers    map[string][]string `yaml:"consumers"`
	// contains filtered or unexported fields
}

Provider is one PROVIDERS/<name>.yaml: how authentication at a service works, where each credential may go, and which stacks may use its connections for which capabilities. Parsed strictly: an unknown key is a deploy error.

func ParseProvider

func ParseProvider(data []byte) (*Provider, error)

ParseProvider strictly decodes and validates a provider declaration.

func (*Provider) APIOrigin

func (p *Provider) APIOrigin(o Origin) bool

APIOrigin reports whether o is one of the provider's api destinations.

func (*Provider) Allows

func (p *Provider) Allows(stack, capability string) bool

Allows reports whether stack may use this provider's connections for the capability (or, as "sandbox:<name>", for that sandbox). No wildcards: the stack and the capability are both named.

func (*Provider) ConsumerStacks

func (p *Provider) ConsumerStacks() []string

ConsumerStacks is the sorted list of stacks the provider names.

type Refresh

type Refresh struct {
	Rotation    string `yaml:"rotation"`
	OnUncertain string `yaml:"on_uncertain"`
	Margin      Margin `yaml:"margin"`
}

Refresh is the provider's renewal behaviour.

type ReleaseInput

type ReleaseInput struct {
	Tenant    string // slug
	Stack     string // the stack whose SANDBOXES/ declares the sandbox
	Provider  string
	Principal string
	Sandbox   string
}

ReleaseInput is one sandbox entry that names this provider (`connection:<provider>`): whose connection, by which stack's sandbox. Every field is the run grant's own, never the asking program's.

type Row

type Row struct {
	ID               string
	TenantID         string
	PrincipalID      string
	Provider         string
	Label            string
	Kind             string
	Subject          string
	Account          string
	Status           string
	Scopes           []string
	Generation       int64
	ExpiresAt        *time.Time
	LifetimeS        int64
	RefreshExpiresAt *time.Time
	ClaimID          string
	ClaimUntil       *time.Time
	CreatedBy        string
	CreatedAt        time.Time
	UpdatedAt        time.Time
	// contains filtered or unexported fields
}

Row mirrors a connections row. The material is not in it: Open returns it, to the one caller that sends it.

func (Row) String

func (r Row) String() string

String is the identity a log line or error names: never material.

type Secrets

type Secrets interface {
	Materialize(ctx context.Context, tenant, stack, name string) ([]byte, error)
}

Secrets materializes a tenant secret a declaration references, in the declaring stack's scope (the tenant secret store's own fallback rule).

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service — see the package comment.

func New

func New(store *Store, decls Decls, sec Secrets, signer *Signer, cfg Config) (*Service, error)

New builds the service. signer is keyed from the master key under KeyLabel (secrets.DeriveKey).

func (*Service) Finish

func (s *Service) Finish(ctx context.Context, in FinishInput) (FinishResult, *Error)

Finish consumes the flow, exchanges the code and stores the tokens.

func (*Service) HTTPClient

func (s *Service) HTTPClient(u *url.URL) *http.Client

HTTPClient is the client a request that carries a connection's token is made with: guarded, and following no redirect.

func (*Service) List

func (s *Service) List(ctx context.Context, tenantID, principal string) ([]Row, error)

List is a principal's connections, metadata only.

func (*Service) ListProvider

func (s *Service) ListProvider(ctx context.Context, tenantID, provider string) ([]Row, error)

ListProvider is every connection at a provider, metadata only.

func (*Service) ProviderDecl

func (s *Service) ProviderDecl(ctx context.Context, tenant, name string) (string, *Provider, error)

ProviderDecl resolves a provider's declaration: the declaring stack and the declaration, or ErrNotDeclared. For the ops that must know who may list a provider's connections.

func (*Service) Release

func (s *Service) Release(ctx context.Context, in ReleaseInput) (string, Row, *Error)

Release hands over the principal's current token at the provider for a sandbox, renewing it when due: the bare token, for the work that opened the sandbox to hold. The provider must name the stack's sandbox as a consumer (`<stack>: [sandbox:<name>]`). There is no destination check: the token is meant to leave for the machine the work runs on.

func (*Service) ReleaseCheck

func (s *Service) ReleaseCheck(ctx context.Context, in ReleaseInput) *Error

ReleaseCheck answers whether the principal holds a connection this stack's sandbox may release, without renewing or reading its material: what the grant gateway shows the tenant's rules before it decides. A nil error: release would find it.

func (*Service) Revoke

func (s *Service) Revoke(ctx context.Context, tenant, tenantID, principal, provider string) (Row, bool, *Error)

Revoke removes a connection and, when the provider has a revocation destination, tells it. It returns false when there was none.

func (*Service) SetClock

func (s *Service) SetClock(now func() time.Time)

SetClock replaces the service's and its store's clock (tests).

func (*Service) Start

func (s *Service) Start(ctx context.Context, in StartInput) (StartResult, *Error)

Start records a flow and builds the provider's sign-in URL.

func (*Service) SweepFlows

func (s *Service) SweepFlows(ctx context.Context) (int64, error)

SweepFlows is for a periodic sweeper: flows past expiry are deleted.

func (*Service) Use

func (s *Service) Use(ctx context.Context, in UseInput) (UseResult, *Error)

Use decides whether this request may carry the principal's token at this provider, renews the token when due, and returns the header. Four facts must agree (docs/todo-connections.md §4): the pinned principal and capability, the executing stack as a consumer the provider names, and the destination in both declarations.

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer signs states and derives verifiers under one key.

func NewSigner

func NewSigner(key []byte, keyVersion int) (*Signer, error)

NewSigner returns a Signer over key (32 bytes from secrets.DeriveKey) of the given master-key generation. The Signer keeps its own copy.

type StartInput

type StartInput struct {
	Tenant, TenantID string
	Stack            string // the managing stack, as dispatched (a slot reduces to its base)
	Principal        string
	Provider         string
	Kind             string // "" is oauth2
	Label            string // "" in this slice
	RedirectURI      string
	Host             string // the request's host: where the cookie goes
	Initiator        string // who the stack says is connecting, for the record
}

StartInput is what the managing stack asks for.

type StartResult

type StartResult struct {
	URL       string
	ExpiresAt time.Time
	Cookie    string // a Set-Cookie line
	Provider  *Provider
}

StartResult is the sign-in URL and the cookie the response must set.

type Store

type Store struct {
	DB      *sql.DB
	Dialect registry.Dialect
	MK      secrets.MasterKeyProvider
	// contains filtered or unexported fields
}

Store reads and writes the two connection tables in the auth database (db/schema/*/auth/0009_connections.sql): `connections`, one row per identity, holding only the current material; and `connection_flows`, a sign-in in progress, consumed once.

Not the tenant secret store: a secret is the operator's, versioned forever and fed to every node; a connection is a principal's, renewed every few hours on whichever node uses it, in the shared auth database.

func NewStore

func NewStore(db *sql.DB, d registry.Dialect, mk secrets.MasterKeyProvider) *Store

NewStore builds a Store over an open, migrated auth DB. A nil dialect is SQLite. mk seals and opens material; nil means every open fails.

func (*Store) Claim

func (s *Store) Claim(ctx context.Context, id string, generation int64, claimID string, until time.Time, status string) (bool, error)

Claim takes the row's renewal for claimID until `until`. It succeeds for one caller: the row at this generation, in the status the caller saw (active; or uncertain, when the provider's rule allows a retry), with no claim at all. An expired claim does not count as none — nobody takes over a renewal whose outcome is unknown (ReleaseStale is what clears one, as uncertain).

func (*Store) ConsumeFlow

func (s *Store) ConsumeFlow(ctx context.Context, nonceHash string) (Flow, error)

ConsumeFlow marks the flow used and returns it. Exactly one caller gets it: a replayed state, a racing second callback, or an expired flow is ErrFlowGone. The code is exchanged only after this.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, tenantID, principalID, provider, label string) (Row, bool, error)

Delete removes a connection. It returns the row it removed, for the revocation at the provider, and false when there was none.

func (*Store) DeletePrincipal

func (s *Store) DeletePrincipal(ctx context.Context, tenantID, principalID string) (int64, error)

DeletePrincipal removes every connection of a principal (the principal is gone).

func (*Store) Get

func (s *Store) Get(ctx context.Context, tenantID, principalID, provider, label string) (Row, error)

Get is one connection by its identity.

func (*Store) ListByPrincipal

func (s *Store) ListByPrincipal(ctx context.Context, tenantID, principalID string) ([]Row, error)

ListByPrincipal is every connection of a principal, by provider.

func (*Store) ListByProvider

func (s *Store) ListByProvider(ctx context.Context, tenantID, provider string) ([]Row, error)

ListByProvider is every connection at a provider, by principal.

func (*Store) Open

func (s *Store) Open(ctx context.Context, r Row) (Material, error)

Open decrypts a row's material. The caller zeroes nothing: the strings are short-lived values on one request.

func (*Store) Put

func (s *Store) Put(ctx context.Context, in NewRow, m Material) (Row, error)

Put stores a connection: a new row, or the identity's existing row re-sealed at the next generation with status active and no claim. A reconnect replaces whatever was there.

func (*Store) PutFlow

func (s *Store) PutFlow(ctx context.Context, f Flow) error

PutFlow records a sign-in that has started.

func (*Store) Release

func (s *Store) Release(ctx context.Context, r Row, claimID string) error

Release clears a claim whose request was never sent: nothing changed, the next use may claim again.

func (*Store) ReleaseStale

func (s *Store) ReleaseStale(ctx context.Context, r Row) (bool, error)

ReleaseStale clears a claim past its lease and marks the row uncertain: the claimant may have died after sending the refresh token. It fences on the stale claim's id, so a claimant that finishes late is fenced too.

func (*Store) Reload

func (s *Store) Reload(ctx context.Context, id string) (Row, error)

Reload re-reads a row by id (after a claim, to see what the claimant wrote). ErrNotFound when it was deleted meanwhile.

func (*Store) Renew

func (s *Store) Renew(ctx context.Context, r Row, claimID string, m Material, expiresAt, refreshExpiresAt *time.Time, lifetimeS int64) (Row, error)

Renew writes a renewal's result, fenced by the claim and the generation: a late writer whose claim was cleared, or whose generation moved on, is ErrFenced and changes nothing.

func (*Store) SetClock

func (s *Store) SetClock(now func() time.Time)

SetClock replaces the store's clock (tests).

func (*Store) SetStatus

func (s *Store) SetStatus(ctx context.Context, r Row, claimID, status string) error

SetStatus writes a renewal's verdict (reconnect, uncertain) under the claim, and clears it. Fenced like Renew.

func (*Store) SweepFlows

func (s *Store) SweepFlows(ctx context.Context) (int64, error)

SweepFlows deletes flows past their expiry (consumed or not). Every node may run it; the delete is idempotent.

type Use

type Use struct {
	Header string `yaml:"header"`
	Format string `yaml:"format"`
}

Use is how the token goes on a request: a header and a `{}` template.

type UseInput

type UseInput struct {
	Tenant     string
	Stack      string // the executing op's stack
	Provider   string
	Principal  string
	Capability string
	URL        *url.URL
}

UseInput is one request that names a connection: the op's own stack, the pinned principal and capability, and where the request goes.

type UseResult

type UseResult struct {
	Header string
	Value  string
	Token  string
	Row    Row
}

UseResult is the header to set: the consumer's declared header and the token in its declared format. Token is the bare token, for an op that gives a format of its own; it goes on the request and nowhere else.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL