Documentation
¶
Overview ¶
Package policy evaluates host policy.
Policy is a floor, not an override (R-272), and is evaluated before grants — a policy that disables exec install-wide denies the owner too. It is a single versioned document rather than scattered columns, so applying policy to a running install is one transaction and one audit event (R-274).
Index ¶
- Constants
- func CheckValue(key string, value json.RawMessage) (json.RawMessage, error)
- func Describe(key string) string
- func FieldType(key string) (string, bool)
- func Fields() []string
- func SameValue(key string, a, b json.RawMessage) bool
- func ValidateIdleDays(stopName, deleteName string, stop, del int) error
- type Document
- func (d Document) ApprovalsNeeded() int
- func (d Document) AuditRetention() audit.Retention
- func (d Document) Channel() UpdateChannel
- func (d Document) DeployApprovalFor(appID string) bool
- func (d Document) EgressFor(app spec.Egress) EffectiveEgress
- func (d Document) EgressInstallMode() (spec.EgressMode, []string)
- func (d Document) EgressLooseningRule() EgressLoosening
- func (d Document) GraceHours() int
- func (d Document) InstallEgress() InstallEgress
- func (d Document) PublicSharingMode() PublicSharing
- func (d Document) StopsInsecureApps() bool
- func (d Document) StopsOrphanedApps() bool
- func (d Document) TokenExpiry(now time.Time) *time.Time
- func (d Document) ValidateAuditRetention() error
- func (d Document) ValidateEgress() error
- func (d Document) ValidateRules() error
- func (d Document) ValidateUpgrades() error
- type EffectiveEgress
- type EgressEntry
- type EgressLoosening
- type Evaluator
- func (e *Evaluator) Allows(ctx context.Context, p authz.Principal, verb authz.Verb, _ string) error
- func (e *Evaluator) AllowsAnonymousGrant(ctx context.Context, withPasscode bool) error
- func (e *Evaluator) AllowsScreening(ctx context.Context) string
- func (e *Evaluator) AllowsSource(ctx context.Context, src spec.Source) error
- func (e *Evaluator) AuditsAnonymousDenials(ctx context.Context) bool
- func (e *Evaluator) Document(ctx context.Context) (Document, error)
- func (e *Evaluator) IsolationFloors(ctx context.Context) (build, runtime spec.IsolationClass, err error)
- func (e *Evaluator) PublicSharing(ctx context.Context) (PublicSharing, error)
- func (e *Evaluator) RecordsAnonymousUse(ctx context.Context) bool
- func (e *Evaluator) Snapshot(ctx context.Context) (authz.Policy, error)
- type Fixed
- type InstallEgress
- type Loosening
- type Overlay
- type PublicSharing
- type Setting
- type Source
- type Store
- type UpdateChannel
- type Window
Constants ¶
const ( LoosenAllowlistAdd = "allowlist_add" LoosenDenylistRemove = "denylist_remove" LoosenBlockPrivate = "block_private_off" )
Loosening kinds: the three ways an app can loosen the install's rules (R-182). Nothing else an app can write loosens.
const ( InsecureWarn = "warn" InsecureStop = "stop" )
What InsecureAction may say.
const AllowUploads = "upload"
AllowUploads is the allowlist entry that admits uploaded source.
An upload has no host and no path, so no host entry can name it. Without an entry of its own, a non-empty allowlist either lets every upload through — which makes "only github.com/acme" mean nothing to anyone with a CLI token — or refuses them all with no way to say otherwise.
const DefaultDeployApprovalExpiryHours = 7 * 24
DefaultDeployApprovalExpiryHours is how long a deploy request waits for approval when policy does not say (R-156): a week, so a request made on a Friday survives the weekend.
const DefaultInsecureGraceHours = 24
DefaultInsecureGraceHours is the grace an install gets when it turns stopping on without saying how long. A day: long enough for somebody to see the warning in a working week's morning, short enough to mean something.
Variables ¶
This section is empty.
Functions ¶
func CheckValue ¶
func CheckValue(key string, value json.RawMessage) (json.RawMessage, error)
CheckValue reads value as the field key, as a startup setting is read, and returns it normalized. An error says why it does not read.
func FieldType ¶
FieldType is a policy field's type in words — "list", "true or false", "whole number" or "string" — and whether the field exists.
func SameValue ¶
func SameValue(key string, a, b json.RawMessage) bool
SameValue reports whether two encodings of the field key hold the same setting, treating absent as the zero value: a document that omits require_backup_before_destroy and one that sets it false say the same thing. An unknown key compares as the raw JSON.
func ValidateIdleDays ¶
ValidateIdleDays refuses idle days below zero, and a delete that would come no later than the stop, since both count from the same last activity (R-393). Shared with an app's own settings; the names are the ones the caller's reader typed (R-105).
Types ¶
type Document ¶
type Document struct {
// SourceAllowlist restricts where apps may be created from (R-092). Empty
// means no restriction — Pando ships permissive defaults (R-270).
SourceAllowlist []string `json:"source_allowlist,omitempty"`
// DisabledVerbs are denied install-wide, to everyone, including an app's
// owner. R-085's "host policy may disable exec install-wide" is this list
// containing app.exec.
DisabledVerbs []string `json:"disabled_verbs,omitempty"`
// AgentDisabledVerbs are denied to token principals only — the CLI token an
// agent holds, and the MCP server acting through one (R-262).
//
// This is O-12's resolution. The tempting alternative is a list of tools
// the MCP server refuses to expose, and it does not work: an agent holding
// a token can call the REST API directly, so an MCP-layer exclusion is a
// speed bump rather than a boundary. Expressed here, it is evaluated before
// grants for every surface, which is the only place it means anything.
//
// Default-closed: Default() ships the exclusions design 04 §3 lists, and an
// install can lift them by editing policy like any other rule.
AgentDisabledVerbs []string `json:"agent_disabled_verbs,omitempty"`
// AllowAnonymousGrants controls whether an app may be shared with everyone
// (R-076). Pointer so that "unset" is distinguishable from "explicitly
// false", which matters when a policy document is partially written.
//
// Superseded by PublicSharing, which says more; still read, so a policy
// file or environment that sets it keeps meaning what it meant — false is
// PublicSharingNone. PublicSharing wins when both are set.
AllowAnonymousGrants *bool `json:"allow_anonymous_grants,omitempty"`
// PublicSharing is how an app may be shared with everyone (R-076, R-075a):
// at all, only behind a passcode, or not at all.
PublicSharing PublicSharing `json:"public_sharing,omitempty"`
// MinBuildIsolation and MinRuntimeIsolation are floors (R-024, R-114).
// Separate because how isolated a build must be is a different question
// from how isolated the running app must be.
MinBuildIsolation spec.IsolationClass `json:"min_build_isolation,omitempty"`
MinRuntimeIsolation spec.IsolationClass `json:"min_runtime_isolation,omitempty"`
// Egress (R-181 – R-185). The install's rules are a floor (R-183): an
// app's own list narrows them, and only the loosening moves EgressFor
// names — adding to an allowlist, removing from a denylist, turning
// private-range blocking off — are subject to EgressLoosening.
//
// EgressMode is allow_all (empty), denylist or allowlist, and EgressList
// is the list it reads. EgressBlockPrivate works with any mode.
EgressMode spec.EgressMode `json:"egress_mode,omitempty"`
EgressList []string `json:"egress_list,omitempty"`
EgressBlockPrivate bool `json:"egress_block_private,omitempty"`
// EgressLoosening is whether an app may loosen the rules above: by
// somebody holding app.egress.loosen (empty, the default, R-270), only
// after a deploy approval (R-154), or never.
EgressLoosening EgressLoosening `json:"egress_loosening,omitempty"`
// EgressAllowlist is the field before issue #79, when there was no mode
// and an app's list replaced this one. Still read — a non-empty one with
// no EgressMode is an allowlist — so a policy file that sets it keeps
// meaning what its author wrote. Never enforced before, so an install that
// set it starts being held to it; that is what the setting said.
EgressAllowlist []string `json:"egress_allowlist,omitempty"`
// Deploy approval (R-154 – R-159). Off unless something here, or the app's
// own spec, turns it on.
//
// DeployApprovalRequired: every app's deploys need approval.
// DeployApprovalApps: these apps' deploys do, whatever their owners say.
// DeployApprovalCount: how many approvals a deploy needs; zero is one.
// DeployApprovalExpiryHours: how long a request waits; zero is forever.
// Default() ships seven days.
DeployApprovalRequired bool `json:"deploy_approval_required,omitempty"`
DeployApprovalApps []string `json:"deploy_approval_apps,omitempty"`
DeployApprovalCount int `json:"deploy_approval_count,omitempty"`
DeployApprovalExpiryHours int `json:"deploy_approval_expiry_hours,omitempty"`
// RequireBackupBeforeDestroy: an admin sets "never destroy without backup"
// once, and app owners cannot override downward (R-284).
RequireBackupBeforeDestroy bool `json:"require_backup_before_destroy,omitempty"`
// MaxTokenLifetimeDays caps how long a token may live; 0 means no cap.
// R-061 allows policy to forbid non-expiring tokens.
MaxTokenLifetimeDays int `json:"max_token_lifetime_days,omitempty"`
// MaxLogDiskBytes is R-224: the total this install will commit to app logs
// across every app. Zero means no aggregate limit.
//
// Enforced at plan time against the **sum of every app's cap**, not against
// measured usage — which is O-16's resolution. Bounding what is committed
// is the stronger guarantee: if every app's logs are capped and the caps
// sum under the budget, the total cannot exceed it. Measuring usage would
// mean acting after the disk was already filling, and the only remedy then
// is recreating containers, which the reconciler may not do on a schedule
// because an unrelated app turned chatty.
MaxLogDiskBytes int64 `json:"max_log_disk_bytes,omitempty"`
// MaxConcurrentDeploys is how many deploys each replica runs at once from
// the deploy queue (issue #93). Zero means one per CPU, and at least two
// (deploy.DefaultConcurrency). Per replica, because a build's cost lands
// on the machine that runs it. Read every time the queue looks for work,
// so a change applies without a restart; a deploy past the limit waits,
// and says how many are ahead of it.
MaxConcurrentDeploys int `json:"max_concurrent_deploys,omitempty"`
// IdleStopDays and IdleDeleteDays stop, and later delete, an app nobody
// has used for that many days, both counted from its last activity
// (R-393 – R-398, issue #131). Zero is off, the default. An app may set
// its own or turn either off (R-397), so these are defaults, not floors.
IdleStopDays int `json:"idle_stop_days,omitempty"`
IdleDeleteDays int `json:"idle_delete_days,omitempty"`
// StopOrphanedApps stops an app the moment none of its owners is active
// (R-408). On unless set false: nil is on, so an install whose stored
// policy predates the setting has it. Administrators are told either way
// (R-409).
StopOrphanedApps *bool `json:"stop_orphaned_apps,omitempty"`
// MaxAppsPerUser is how many apps a person may own unless their account or
// a group of theirs says otherwise (R-244). Zero is unlimited.
MaxAppsPerUser int `json:"max_apps_per_user,omitempty"`
// AllowCPUOversubscription and AllowMemoryOversubscription let the apps
// on a runtime together ask for more CPU, or more memory, than the runtime
// reports having (R-242 as amended for issue #72). Both off by default: a
// deploy that would oversubscribe is refused at plan time.
//
// Separate, because they fail differently. Too little CPU makes every app
// slower; too little memory makes the kernel kill one. An install packing
// many mostly-idle apps onto one host usually wants the first and not the
// second.
//
// There is no disk counterpart and there will not be one: disk is not a
// reservation the kernel shares out, and a full disk stops every app and
// Pando with them.
AllowCPUOversubscription bool `json:"allow_cpu_oversubscription,omitempty"`
AllowMemoryOversubscription bool `json:"allow_memory_oversubscription,omitempty"`
// Audit retention (R-347, R-348). The live audit log keeps
// AuditRetentionMonths whole months; an older month is archived, the
// archive read back and checked, and only then is the month removed.
//
// Zero is three months. Fewer than three is refused here, and the
// database refuses it again: the floor is held by the function that
// removes a month, so nothing the running server can write lowers it.
// More is anyone's choice.
//
// AuditArchive is where an archive goes: keep (empty, the default) under
// Pando's own directory, export to a backup destination — the default
// one, or AuditArchiveDestination — or off, which archives nothing and so
// removes nothing, the log growing as it did before retention existed.
AuditRetentionMonths int `json:"audit_retention_months,omitempty"`
AuditArchive audit.ArchiveMode `json:"audit_archive,omitempty"`
AuditArchiveDestination string `json:"audit_archive_destination,omitempty"`
// DisableAIScreening forbids AI screening of deployment plans install-wide
// (R-336). Default false, like everything else here: Pando ships permissive
// and configuration narrows (R-270).
//
// Worth an explicit setting rather than leaving it to whether an adapter is
// configured, because the two are different decisions made by different
// people. Screening sends repository contents to a provider (R-337), and an
// administrator who has to say no to that should not have to do it by
// deleting somebody else's adapter.
DisableAIScreening bool `json:"disable_ai_screening,omitempty"`
// DisableAnonymousUseAudit stops recording app.use for visitors who are
// not signed in (R-227). Default false: anonymous use of a public app is
// recorded like anyone's, once per browser session, because "who used this
// app" after a leak includes the people nobody knew by name. An install
// with a busy public site that does not want those rows turns it off.
DisableAnonymousUseAudit bool `json:"disable_anonymous_use_audit,omitempty"`
// DisableAnonymousDenialAudit stops recording authz.denied when somebody
// not signed in reaches an app that is not shared with them (design 06
// §6). Default false: every denial is audited, these included. Anyone can
// cause one write per request without an account — a crawler walking a
// private app's links does — so an install that does not want those rows
// turns it off. A signed-in person or a token refused is always recorded.
DisableAnonymousDenialAudit bool `json:"disable_anonymous_denial_audit,omitempty"`
// The security score (R-314 – R-316, design 09 §5).
//
// MinSecurityScore is the floor a deploy has to clear, 0 to 100. Zero is
// off, which is the shipped posture (R-270) — and so is an installation
// with no scanner configured, where this is inert and the console says so
// rather than silently blocking every deploy (R-317).
MinSecurityScore int `json:"min_security_score,omitempty"`
// InsecureAction is what happens to an app that is *already running* when
// it falls below the floor: "warn" or "stop". Empty means warn.
//
// A policy change or a newly published CVE is not a reason to take
// somebody's working service away without notice, so stopping is opt-in
// and grace comes with it (R-315).
InsecureAction string `json:"insecure_action,omitempty"`
// InsecureGraceHours is how long an app has after it is first found below
// the floor, before "stop" applies. Zero with InsecureAction "stop" means
// the default below, not "immediately" — an accidental zero must not empty
// a host.
InsecureGraceHours int `json:"insecure_grace_hours,omitempty"`
// IgnoreUnfixableFindings drops findings with no fix available from both
// the score and the list.
//
// Off by default, so the number means "what is wrong with this app" rather
// than "what could this app's owner do about it today" — and an upgrade
// does not silently move every score. An installation that has decided it
// only acts on what it can fix turns it on, and the two agree again: what
// is counted is what is shown.
IgnoreUnfixableFindings bool `json:"ignore_unfixable_findings,omitempty"`
// DisablePasswordSignIn refuses sign-in with a local username and
// password (issue #51), once people sign in through an external identity
// provider. Refused while no external provider is on, so it cannot empty
// the sign-in page. `pando admin enable-password-sign-in` is the way back
// when every provider is unreachable, and needs shell access on the host.
DisablePasswordSignIn bool `json:"disable_password_sign_in,omitempty"`
// DisableJITProvisioning refuses making an account at a first external
// sign-in, whatever each provider is set to. People then need an account
// first — pushed by SCIM, or linked by an administrator.
DisableJITProvisioning bool `json:"disable_jit_provisioning,omitempty"`
// RequireLocalTwoFactor requires two-factor authentication on every local
// account (R-405). An account without it can sign in with its password
// and do nothing but set it up; one with it cannot turn it off. Accounts
// from an identity provider are not affected: their provider decides.
// `pando admin reset-two-factor` is the way back for someone who has lost
// their authenticator and their recovery codes.
RequireLocalTwoFactor bool `json:"require_local_two_factor,omitempty"`
// DisableUpdateCheck stops Pando asking GitHub whether a newer release
// exists (R-349). Default false — on — so an install learns about a
// security release without anyone remembering to look; off sends no
// request at all, for an air-gapped install or one that may not call out.
DisableUpdateCheck bool `json:"disable_update_check,omitempty"`
// AllowPrivateWebhooks lets an event subscription's webhook reach a
// private, loopback or link-local address (R-372). Default false: anybody
// who can see an app can subscribe to it, and a webhook that may point
// anywhere is a way to make Pando send requests into its own network — to
// a cloud metadata address, or to the database it runs on.
AllowPrivateWebhooks bool `json:"allow_private_webhooks,omitempty"`
// UpdateChannel is which releases the check offers (R-350): stable, the
// default, or prerelease, which also offers release candidates.
UpdateChannel UpdateChannel `json:"update_channel,omitempty"`
// UpgradeInPlace lets Pando replace its own container with a newer
// release (R-355). Off by default, against R-270 on purpose: a version
// named in a Compose file or infrastructure-as-code is put back by its
// next apply, so whoever owns that configuration turns this on — usually
// there, as PANDO_POLICY_UPGRADE_IN_PLACE, which also locks it here.
UpgradeInPlace bool `json:"upgrade_in_place,omitempty"`
// AutoUpgradePatches upgrades to a new patch release of the running minor
// line inside MaintenanceWindow, with nobody present (R-361). Needs
// UpgradeInPlace and a window.
AutoUpgradePatches bool `json:"auto_upgrade_patches,omitempty"`
// MaintenanceWindow is when an automatic upgrade may start, in UTC:
// weekdays, a start time and a length, as "sun,wed 02:00 2h" (R-361).
// One string so that it reads the same in the config file, an
// environment variable and the API.
MaintenanceWindow string `json:"maintenance_window,omitempty"`
}
Document is the host policy (design 02 §2.5).
A single versioned document rather than scattered columns, so applying policy to a running install is one transaction and one audit event (R-274).
Policy is a floor, not an override (R-272): it can only deny. Nothing here grants anything, which is why it is evaluated before grants rather than mixed with them.
func (Document) ApprovalsNeeded ¶
ApprovalsNeeded is how many approvals a deploy needs, with the default of one applied.
func (Document) AuditRetention ¶
AuditRetention is what the audit archiver reads (R-347).
func (Document) Channel ¶
func (d Document) Channel() UpdateChannel
Channel is the update channel in force, stable when unset.
func (Document) DeployApprovalFor ¶
DeployApprovalFor reports whether host policy requires approval for an app's deploys: install-wide, or for this app by name. The app's own spec can require it too, which the approval service reads (R-154).
func (Document) EgressFor ¶
func (d Document) EgressFor(app spec.Egress) EffectiveEgress
EgressFor resolves an app's egress against the installation (R-182).
Entries that do not parse are left out rather than failing here: the spec and the policy are each validated when written, and a plan shown to somebody should not fail on a list it was already told about.
func (Document) EgressInstallMode ¶
func (d Document) EgressInstallMode() (spec.EgressMode, []string)
EgressInstallMode is the install's egress mode in force, reading the field from before issue #79 when the new one is unset.
func (Document) EgressLooseningRule ¶
func (d Document) EgressLooseningRule() EgressLoosening
EgressLooseningRule is the rule in force, with the default applied.
func (Document) GraceHours ¶
GraceHours is the grace in force, with the default applied.
func (Document) InstallEgress ¶
func (d Document) InstallEgress() InstallEgress
InstallEgress is the installation's egress rules in force, with the defaults and the field from before issue #79 read the way EgressFor reads them, so what an owner is shown is what their app is held to.
func (Document) PublicSharingMode ¶
func (d Document) PublicSharingMode() PublicSharing
PublicSharingMode is the rule in force, reading the older boolean when the new field is unset.
func (Document) StopsInsecureApps ¶
StopsInsecureApps reports whether policy says to stop them (R-316).
func (Document) StopsOrphanedApps ¶ added in v0.13.0
StopsOrphanedApps reports whether an app with no active owner is stopped (R-408). On unless turned off.
func (Document) TokenExpiry ¶ added in v0.13.0
TokenExpiry is when a token asked for without an expiry expires: never, unless policy caps how long a token may live (R-061), in which case the cap counted from now.
func (Document) ValidateAuditRetention ¶
ValidateAuditRetention refuses retention under the floor and a mode that is not one (R-348). Written for the administrator who typed it (R-105).
func (Document) ValidateEgress ¶
ValidateEgress checks the install's egress settings can be read.
func (Document) ValidateRules ¶
ValidateRules checks the settings that would otherwise be saved and enforce nothing, or enforce something nobody meant: an egress mode or entry that does not parse, or an approval count below zero. Written for the administrator who typed it (R-105).
func (Document) ValidateUpgrades ¶
ValidateUpgrades refuses automatic upgrades that could never run, or that have no window to run in (R-361).
type EffectiveEgress ¶
type EffectiveEgress struct {
// Mode and List are the install's rules with the app's additions and
// removals applied.
Mode spec.EgressMode `json:"mode"`
List []EgressEntry `json:"list"`
// AppMode and AppList are the app's own list, applied on top. Empty when
// the app has none.
AppMode spec.EgressMode `json:"app_mode,omitempty"`
AppList []string `json:"app_list,omitempty"`
BlockPrivate bool `json:"block_private"`
BlockPrivateFrom string `json:"block_private_from,omitempty"` // install | app
// Loosenings is every way this app is looser than the install, and Gate
// is what policy says they need. Gate is empty when there are none.
Loosenings []Loosening `json:"loosenings,omitempty"`
Gate EgressLoosening `json:"gate,omitempty"`
// Unused is the app's additions and removals that change nothing — adding
// to an install with no list, removing an entry it does not have. Shown as
// a warning (never a blocker): somebody wrote them expecting an effect.
Unused []string `json:"unused,omitempty"`
// Restricted is whether anything is refused at all. When it is not, the
// app runs exactly as it would with no egress controls (R-186).
Restricted bool `json:"restricted"`
// Rules is what a runtime adapter enforces.
Rules egress.Rules `json:"-"`
}
EffectiveEgress is the rules an app runs with, merged, with where each part came from (R-188). What the plan shows and what the runtime enforces are both read from here, so they cannot disagree.
func (EffectiveEgress) Forbidden ¶
func (e EffectiveEgress) Forbidden() bool
Forbidden reports whether the app loosens rules that policy says may not be loosened. Refused at plan time (R-183).
func (EffectiveEgress) NeedsApproval ¶
func (e EffectiveEgress) NeedsApproval() bool
NeedsApproval reports whether the app's loosenings make its deploy need approval (R-154).
type EgressEntry ¶
EgressEntry is one entry of the merged list, and whose it is.
type EgressLoosening ¶
type EgressLoosening string
EgressLoosening is what an app needs to loosen the install's egress rules (R-183).
const ( // EgressLooseningVerb: somebody holding app.egress.loosen may. The // default, because Pando ships permissive (R-270) and this is what an // install had before the setting existed. EgressLooseningVerb EgressLoosening = "verb" // EgressLooseningApproval: the deploy that carries it needs approval // (R-154). Anybody who may change the app's egress may propose one. EgressLooseningApproval EgressLoosening = "approval" // EgressLooseningForbidden: no app may, and a deploy that would is // refused at plan time. EgressLooseningForbidden EgressLoosening = "forbidden" )
func (EgressLoosening) Valid ¶
func (l EgressLoosening) Valid() error
Valid refuses a value that is none of the three. Empty is unset.
type Evaluator ¶
type Evaluator struct {
// contains filtered or unexported fields
}
Evaluator answers policy questions against the current document.
func New ¶
New builds an evaluator over a document source.
The document is loaded per evaluation rather than cached, because R-274 says policy applies to a running install: a cached policy would keep denying, or keep allowing, for however long the cache lived.
func Static ¶
Static builds an evaluator over a fixed document, for tests and for an install that has not written one yet.
func (*Evaluator) Allows ¶
Allows implements authz.Policy: it reports whether a verb is permitted at all.
Evaluated before grants (design 06 §2, step 5). A policy that disables exec install-wide denies the owner too.
func (*Evaluator) AllowsAnonymousGrant ¶
AllowsAnonymousGrant checks R-076: whether an app may be shared with everyone, with a passcode or without one.
func (*Evaluator) AllowsScreening ¶
AllowsScreening is host policy's veto over AI screening (R-336).
A reason rather than an error, and empty when it is allowed. This is not a failure — it is a posture, and it is shown in the review as one. An unreadable policy document denies: a screening that cannot be checked against policy is one that has not been checked, and the safe direction is the one that sends nothing anywhere.
func (*Evaluator) AllowsSource ¶
AllowsSource checks the source allowlist (R-092).
Called before any clone or pull, so a blocked source produces zero disk writes. The check being here rather than inside the clone path is the whole point: by the time you are cloning, you have already written to disk.
An entry is a host (github.com), a host suffix (.corp.example), or a host and a path prefix (github.com/acme, ghcr.io/acme/web, 123456789012.dkr.ecr.us-east-1.amazonaws.com/team). A path prefix matches on whole segments, so github.com/acme does not admit github.com/acme-evil. Git URLs and image references are read the same way, which is how one list restricts "named orgs, named repos, a specific forge, or registry namespaces" alike. An upload is admitted only by the entry `upload`.
func (*Evaluator) AuditsAnonymousDenials ¶
AuditsAnonymousDenials reports whether a data-plane denial of somebody not signed in is written to the audit log as authz.denied. A policy that cannot be read audits it, as RecordsAnonymousUse does.
func (*Evaluator) IsolationFloors ¶
func (e *Evaluator) IsolationFloors(ctx context.Context) (build, runtime spec.IsolationClass, err error)
IsolationFloors returns the build and runtime floors (R-024, R-114).
func (*Evaluator) PublicSharing ¶
func (e *Evaluator) PublicSharing(ctx context.Context) (PublicSharing, error)
PublicSharing is the host's rule for sharing with everyone, for the console to offer only what it allows.
func (*Evaluator) RecordsAnonymousUse ¶
RecordsAnonymousUse reports whether a visit by someone not signed in is written to the audit log as app.use (R-227). A policy that cannot be read records it: when unsure, keep the record.
type Fixed ¶
type Fixed struct {
Key string `json:"key"`
Value json.RawMessage `json:"value"`
Source Source `json:"source"`
}
Fixed is one policy field set at startup.
type InstallEgress ¶
type InstallEgress struct {
Mode spec.EgressMode `json:"mode"`
List []string `json:"list"`
BlockPrivate bool `json:"block_private"`
Loosening EgressLoosening `json:"loosening"`
}
InstallEgress is the installation's egress rules as an app's owner edits against them (R-182): the mode and list in force, whether private addresses are blocked, and what loosening them needs (R-183).
type Loosening ¶
type Loosening struct {
Kind string `json:"kind"`
Entry string `json:"entry,omitempty"`
// Message is written for the app's owner (R-105).
Message string `json:"message"`
}
Loosening is one way an app's egress is looser than the install's.
func NewLoosenings ¶
func NewLoosenings(prev, next EffectiveEgress) []Loosening
NewLoosenings is what next loosens that prev did not: the part of a change the loosening gate is asked about (R-183). A loosening already running was already allowed.
type Overlay ¶
type Overlay struct {
// contains filtered or unexported fields
}
Overlay is the policy fields set at startup.
func NewOverlay ¶
NewOverlay checks each setting against the policy document and returns the overlay. A setting that is not a policy field, or will not read as one, is an error that stops startup: a misspelt or malformed policy is a policy that silently does not apply, which is worse than not starting.
func (*Overlay) Changes ¶
Changes reports the first fixed field that incoming sets differently from its startup value, with that value's source. Fields left as the startup value — which is what GET /policy hands back — are not a change.
func (*Overlay) Restore ¶
Restore returns incoming with every fixed field put back to what stored holds, so a save never writes a startup value into the stored document.
func (*Overlay) Wrap ¶
Wrap returns a store that reads the effective document — the stored one with the startup fields over it — and saves without writing a startup value into the stored one. Everything that reads policy goes through it, so no reader can see a stored value the startup config has replaced.
type PublicSharing ¶
type PublicSharing string
PublicSharing is the host's rule for sharing an app with everyone.
const ( // PublicSharingAllowed: public, with or without a passcode. PublicSharingAllowed PublicSharing = "allowed" // PublicSharingPasscodeOnly: public only behind a passcode. PublicSharingPasscodeOnly PublicSharing = "passcode_only" // PublicSharingNone: no app may be shared with everyone. PublicSharingNone PublicSharing = "none" )
func (PublicSharing) Valid ¶
func (p PublicSharing) Valid() error
Valid refuses a value that is none of the three. Empty is unset.
type Setting ¶
Setting is one field as the config gives it: a string from the environment, or a typed value from the config file.
type Source ¶
type Source struct {
Kind string `json:"kind"`
Name string `json:"name,omitempty"`
Key string `json:"key,omitempty"`
}
Source is where a fixed value was set, as the config package reports it.
type Store ¶
type Store interface {
Load(ctx context.Context) (Document, error)
Save(ctx context.Context, doc Document, updatedBy string) error
}
Store is where the policy document is kept.
type UpdateChannel ¶
type UpdateChannel string
UpdateChannel is which releases the update check offers (R-350).
const ( // UpdateChannelStable offers releases only. UpdateChannelStable UpdateChannel = "stable" // UpdateChannelPrerelease also offers release candidates. UpdateChannelPrerelease UpdateChannel = "prerelease" )
func (UpdateChannel) Valid ¶
func (c UpdateChannel) Valid() error
Valid refuses a value that is neither. Empty is unset, which is stable.
type Window ¶
type Window struct {
Days []time.Weekday
Start time.Duration // since midnight UTC
Length time.Duration
}
Window is a parsed maintenance window (R-361): the weekdays it opens on, the UTC time it opens and how long it stays open. A window that runs past midnight belongs to the day it opened on.
func ParseWindow ¶
ParseWindow reads "sun,wed 02:00 2h": weekdays by their first three letters, or "daily", a 24-hour UTC start time, and a whole number of hours from 1 to 24. Errors are written for the administrator who typed it (R-105).