Documentation
¶
Overview ¶
Package approval defines the approval-gate backend abstraction. The server asks a Backend to request grants for a change's (class, target) gates, lists their state to decide whether a gate is satisfied, and revokes them after apply. The server never holds standing privilege — it only requests; humans approve in the backing provider. gcp-pam is the first real backend; Fake backs the tests.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Backend ¶
type Backend interface {
// RequestGrant ensures an open grant exists for req — create-or-reuse,
// idempotent: a second request for the same (class,target,pr,environment)
// returns the existing open grant rather than creating a duplicate.
RequestGrant(ctx context.Context, req Request) (Grant, error)
// ListGrants returns the grants on a (class, target) entitlement across all
// PRs (the caller filters by Request).
ListGrants(ctx context.Context, class, target string) ([]Grant, error)
// Revoke revokes the open grants matching req. Idempotent (a no-op when none).
Revoke(ctx context.Context, req Request) error
}
Backend is an approval provider. The server requests grants and reads their state; it can never approve (that is a human action in the provider).
type Fake ¶
type Fake struct {
// Pool is an optional list of requester identities that the Fake leases like
// gcppam does: when req.Requester is empty and Pool is non-empty, the first
// pool entry that is not already the Requester of an open grant is chosen.
// Empty Pool ⇒ no requester (existing tests are unaffected).
Pool []string
// contains filtered or unexported fields
}
Fake is an in-memory Backend for tests. Grants start AWAITING; a test calls Approve to simulate an approver flipping a grant ACTIVE. Safe for concurrent use (the reconcile loop may call it while a test mutates it).
func (*Fake) Approve ¶
Approve flips the grant for req to ACTIVE (test-only: simulates an approver).
func (*Fake) ListGrants ¶
func (*Fake) RequestGrant ¶
type Grant ¶
type Grant struct {
Name string // backend-assigned resource name/id
State GrantState
Request Request // correlation, parsed back from the grant by the backend
Requester string // the requesting identity (populated by backends that pool requesters); "" when N/A
}
Grant is a backend's record of an approval grant for a Request.
type GrantState ¶
type GrantState string
GrantState is the lifecycle of an approval grant, normalised across backends.
const ( StateAwaiting GrantState = "AWAITING" // requested; awaiting an approver StateActivating GrantState = "ACTIVATING" // approved; becoming active StateActive GrantState = "ACTIVE" // approved and active StateDenied GrantState = "DENIED" StateRevoked GrantState = "REVOKED" StateExpired GrantState = "EXPIRED" )
func (GrantState) Open ¶
func (s GrantState) Open() bool
Open reports whether the state is a live, non-terminal grant.
type Request ¶
type Request struct {
Class string
Target string
PR int
Environment string
// Requester is an optional pre-leased pool identity. When set, the backend
// requests the grant AS this identity instead of leasing one — so all of a
// PR's gates share one elevated requester. Empty ⇒ the backend leases.
Requester string
}
Request correlates a gate to a change: a classification class against a target (e.g. a cloud project/account), for a specific PR and environment.
type SlotCollisionError ¶ added in v0.9.5
type SlotCollisionError struct {
// BlockingGrant is the open grant occupying the slot.
BlockingGrant Grant
}
SlotCollisionError is returned by RequestGrant when the PAM create call fails because an open grant for a different (PR, environment) already holds the requester's slot on this entitlement. Callers can detect this with errors.As and decide whether to auto-revoke the blocker.
func (*SlotCollisionError) Error ¶ added in v0.9.5
func (e *SlotCollisionError) Error() string