Documentation
¶
Overview ¶
Package condition implements AWS IAM's policy Condition grammar and evaluation semantics: the operator registry (StringEquals, IpAddress, DateGreaterThan, ...), the ForAllValues/ForAnyValue/IfExists modifiers, and ${...} policy-variable substitution. It has no knowledge of any particular policy type (identity, trust, or resource-based) — callers supply a statement's raw Condition block, a request's context-key values, and the enclosing document's Version, and get back whether the condition holds. This lets both iamapi/policy (IAM identity/trust policies) and auth (S3 bucket policies) share one implementation and one AWS-verified behavior, rather than maintaining two.
Index ¶
- func Evaluate(raw json.RawMessage, ctxVars map[string][]string, version string) (matched bool, ok bool)
- func GlobMatch(pattern, s string) bool
- func ParseIPOrCIDR(s string) bool
- func ShapeValid(raw json.RawMessage) bool
- func SubstitutePolicyVariables(s string, ctxVars map[string][]string) string
- type Block
- type ParsedOperator
- type Qualifier
- type Values
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Evaluate ¶
func Evaluate(raw json.RawMessage, ctxVars map[string][]string, version string) (matched bool, ok bool)
Evaluate evaluates a policy statement's Condition block against ctxVars - context-key values keyed however the caller's policy type documents them (e.g. "aws:<GlobalKey>" for IAM identity/S3 bucket policies, "<provider-url>:<claim>" for trust-policy evaluation). An absent or empty Condition always matches. version is the enclosing document's Version element: a ${...} policy variable in a Condition value is only ever substituted when version is exactly "2012-10-17" AND the operator is one of conditionVariableOperators - AWS requires the 2012-10-17 policy version to use variables at all, and never expands them for Numeric/Date/Bool/Binary/IP/Null operators even then. A variable that doesn't qualify is left as literal text, the same fallback used for an absent/multivalued context key - so it simply won't match a real condition value, rather than silently expanding into something AWS itself wouldn't.
matched reports whether the condition holds; ok reports whether it could be evaluated at all. ok is false only for a Condition block Parse would already reject - i.e. only for a document stored before write-time validation existed, or containing a future operator this package doesn't yet recognize. Callers MUST treat ok=false as "cannot rule out a hidden Deny" and deny the whole evaluation, never as a non-match.
func GlobMatch ¶
GlobMatch implements the small wildcard grammar IAM Action/Resource/Arn patterns use: '*' matches any run of characters (including none), '?' matches exactly one character, everything else matches literally.
func ParseIPOrCIDR ¶
ParseIPOrCIDR reports whether s is a valid IP address or CIDR range, for write-time validation of an IP-semantic condition key's value (e.g. AWS rejects PutBucketPolicy for a non-IP aws:SourceIp value with "Invalid IP address in Conditions", independent of which operator wraps it).
func ShapeValid ¶
func ShapeValid(raw json.RawMessage) bool
ShapeValid reports whether raw (a statement's Condition block) satisfies Parse without error - write-time validation of the condition grammar alone (operator names), with no opinion on condition keys.
func SubstitutePolicyVariables ¶
SubstitutePolicyVariables replaces every ${key} placeholder in s with the single value ctxVars holds for key, looked up the same case-insensitive way as a Condition key. AWS only allows a single-valued context key to be used as a policy variable; a placeholder naming an absent or multivalued key is left as literal text, same as any other substring - so it simply won't match a real resource ARN or condition value, rather than being silently dropped and turning a Deny that relies on it into a no-op.
Types ¶
type Block ¶
Block is a statement's Condition object, decoded to operator name -> key -> value(s).
func Parse ¶
func Parse(raw json.RawMessage) (Block, error)
Parse decodes raw (a statement's Condition block) into a Block, validating only its JSON shape and that every operator name is one ParseOperatorName recognizes - not condition key names, which are meaningful only to a specific policy type (IAM identity policies accept arbitrary custom/tag keys; S3 bucket policies validate against AWS's fixed key catalogue) and so are the caller's responsibility. An absent, null, or empty raw decodes to a nil Block with no error, matching Evaluate's "always matches" contract for a statement with no Condition at all.
type ParsedOperator ¶
ParsedOperator is a condition operator name decomposed into its set qualifier, base operator, and IfExists flag.
func ParseOperatorName ¶
func ParseOperatorName(name string) (ParsedOperator, bool)
ParseOperatorName decomposes name (e.g. "ForAllValues:StringNotEqualsIfExists") into a ParsedOperator, reporting ok=false if the base operator (after stripping a recognized qualifier prefix and IfExists suffix) isn't one conditionRegistry recognizes, or is "Null" (Null has no IfExists variant - "NullIfExists" is rejected here since after suffix-stripping "Null" isn't itself in conditionRegistry). A bare "Null", optionally qualifier-prefixed, is accepted
type Qualifier ¶
type Qualifier int
Qualifier is IAM's multivalued-context-key set operator, given as a "ForAllValues:"/"ForAnyValue:" prefix on a condition operator name.
type Values ¶
type Values []string
Values decodes the value(s) of a single Condition operator/key pair. Unlike Action/Resource's string-only representation, a Condition value may also be a bare JSON number or boolean rather than a string, so e.g. "5.50" round-trips as "5.50", not "5.5". A JSON null value or a non-scalar (object/array) element is rejected.