Documentation
¶
Overview ¶
Package taint tracks symbolic sources through the Actions execution AST. It never evaluates expressions, executes scripts, or reads secret values.
Index ¶
- func PrimeAuthoredJavaScript(ctx context.Context, documents []*aw.Document, rule Rule, ...) error
- func VisitInterpolations(ctx context.Context, text, path string, ...) error
- type CoverageGap
- type ExpressionError
- type Finding
- type JavaScriptBatchParser
- type JavaScriptInput
- type JavaScriptMode
- type JavaScriptNode
- type JavaScriptOptions
- type JavaScriptParseResult
- type JavaScriptParser
- type JavaScriptResult
- type Kind
- type Result
- func Analyze(input *actions.Workflow, rule Rule) (Result, error)
- func AnalyzeAuthoredDocument(ctx context.Context, document *aw.Document, rule Rule) (Result, error)
- func AnalyzeAuthoredJavaScript(ctx context.Context, document *aw.Document, rule Rule) (Result, error)
- func AnalyzeAuthoredScripts(ctx context.Context, document *aw.Document, rule Rule) (Result, error)
- func AnalyzeDocument(document *aw.Document, compiled *actions.Workflow, rule Rule) (Result, error)
- func CheckSecretLeaks(workflow *actions.Workflow) (Result, error)
- type Rule
- type Site
- type Source
- type TextExpression
- type TypeScriptParser
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func PrimeAuthoredJavaScript ¶
func PrimeAuthoredJavaScript(ctx context.Context, documents []*aw.Document, rule Rule, options JavaScriptOptions) error
PrimeAuthoredJavaScript batches the deterministically rendered entry sources across documents. The discovery pass does not evaluate JavaScript or modules. Additional sources discovered through actual data flow are parsed on demand.
func VisitInterpolations ¶
func VisitInterpolations(ctx context.Context, text, path string, visit func(start, end, line int, node actionlint.ExprNode) error) error
VisitInterpolations visits parsed Actions expressions with byte offsets and text-relative lines. Quoted '}}' and doubled single quotes are expression data, not delimiters. Parse errors are value-free; earlier visits are retained.
Types ¶
type CoverageGap ¶
CoverageGap identifies incomplete analysis without including script contents. Line, when present, is relative to the run script.
type ExpressionError ¶
ExpressionError identifies a parsing coverage gap without exposing values.
func (*ExpressionError) Error ¶
func (e *ExpressionError) Error() string
type JavaScriptBatchParser ¶
type JavaScriptBatchParser interface {
ParseBatch(context.Context, []string) ([]JavaScriptParseResult, error)
}
JavaScriptBatchParser amortizes native compiler startup across independent scripts. A syntax failure belongs to its script, not the entire batch.
type JavaScriptInput ¶
type JavaScriptMode ¶
type JavaScriptMode string
const ( JavaScriptFast JavaScriptMode = "fast" JavaScriptDeep JavaScriptMode = "deep" )
type JavaScriptNode ¶
type JavaScriptNode struct {
Kind string `json:"kind"`
Text string `json:"text"`
Line int `json:"line"`
Name *JavaScriptNode `json:"name"`
Expression *JavaScriptNode `json:"expression"`
Initializer *JavaScriptNode `json:"initializer"`
DeclarationList *JavaScriptNode `json:"declarationList"`
Body *JavaScriptNode `json:"body"`
Block *JavaScriptNode `json:"block"`
Left *JavaScriptNode `json:"left"`
Right *JavaScriptNode `json:"right"`
OperatorToken *JavaScriptNode `json:"operatorToken"`
Condition *JavaScriptNode `json:"condition"`
WhenTrue *JavaScriptNode `json:"whenTrue"`
WhenFalse *JavaScriptNode `json:"whenFalse"`
ThenStatement *JavaScriptNode `json:"thenStatement"`
ElseStatement *JavaScriptNode `json:"elseStatement"`
TryBlock *JavaScriptNode `json:"tryBlock"`
CatchClause *JavaScriptNode `json:"catchClause"`
FinallyBlock *JavaScriptNode `json:"finallyBlock"`
VariableDeclaration *JavaScriptNode `json:"variableDeclaration"`
ArgumentExpression *JavaScriptNode `json:"argumentExpression"`
ModuleSpecifier *JavaScriptNode `json:"moduleSpecifier"`
ImportClause *JavaScriptNode `json:"importClause"`
NamedBindings *JavaScriptNode `json:"namedBindings"`
PropertyName *JavaScriptNode `json:"propertyName"`
Incrementor *JavaScriptNode `json:"incrementor"`
Operand *JavaScriptNode `json:"operand"`
Statements []*JavaScriptNode `json:"statements"`
Declarations []*JavaScriptNode `json:"declarations"`
Arguments []*JavaScriptNode `json:"arguments"`
Parameters []*JavaScriptNode `json:"parameters"`
Elements []*JavaScriptNode `json:"elements"`
Properties []*JavaScriptNode `json:"properties"`
TemplateSpans []*JavaScriptNode `json:"templateSpans"`
Clauses []*JavaScriptNode `json:"clauses"`
Other []*JavaScriptNode `json:"other"`
}
JavaScriptNode is a projection of the native TypeScript compiler's AST. Unrecognized syntax is retained in Other, never dropped by the parser.
func (*JavaScriptNode) Children ¶
func (n *JavaScriptNode) Children() []*JavaScriptNode
Children includes every projected child, including otherwise unmodeled syntax.
type JavaScriptOptions ¶
type JavaScriptOptions struct {
Context context.Context
Parser JavaScriptParser
Files fs.FS
RuntimePaths map[string]string
// An empty mode preserves the original, deep library API behavior.
Mode JavaScriptMode
}
JavaScriptOptions enables native AST analysis explicitly. Files is the repository source filesystem, not the runner's filesystem. RuntimePaths maps operator-verified runner asset directories to corresponding repository paths. Without a mapping, generated/dynamic paths remain unresolved.
type JavaScriptParseResult ¶
type JavaScriptParseResult struct {
Node *JavaScriptNode
Err error
}
type JavaScriptParser ¶
type JavaScriptParser interface {
Parse(context.Context, string) (*JavaScriptNode, error)
}
type JavaScriptResult ¶
func AnalyzeJavaScript ¶
func AnalyzeJavaScript(input JavaScriptInput, rule Rule, options JavaScriptOptions) (JavaScriptResult, error)
AnalyzeJavaScript never executes the input or resolves a secret value. Sources are caller-provided symbolic bindings (plus Rule.IsSource), sinks reuse Rule.IsSink, and Rule.IsJavaScriptFilter declassifies whole expressions.
type Result ¶
type Result struct {
Findings []Finding
Gaps []CoverageGap
}
func Analyze ¶
Analyze resolves a copy of the AST and visits jobs in dependency order. Environment scopes and step execution order are preserved. Shell-local assignments are conservative unions across control-flow paths.
func AnalyzeAuthoredDocument ¶
AnalyzeAuthoredDocument follows explicit AW execution nodes and the prompt. It does not compile, expand imports, or assume generated execution behavior.
func AnalyzeAuthoredJavaScript ¶
func AnalyzeAuthoredJavaScript(ctx context.Context, document *aw.Document, rule Rule) (Result, error)
AnalyzeAuthoredJavaScript returns new authored script flows without duplicating the ordinary shell/prompt findings already checked in the compiled graph.
func AnalyzeAuthoredScripts ¶
AnalyzeAuthoredScripts checks non-step script entry points. Compiled runtime wrappers are deliberately not parsed: each entry uses its actual call contract.
func AnalyzeDocument ¶
AnalyzeDocument checks the AW prompt and script entry points alongside its compiled Actions graph. Fast mode avoids generated JavaScript traversal. Callers compile through workflow.Compiler.CompileDocument so imports and compiler-generated steps use exactly the same execution model as gh aw.
type Rule ¶
type Rule struct {
ID string
IsSource func(reference string) bool
IsSink func(Site) bool
IsFilter func(actionlint.ExprNode) bool
ActionSources func(uses string) []string
JavaScript *JavaScriptOptions
IsJavaScriptFilter func(*JavaScriptNode) bool
}
Rule separates sources, disclosure sinks, and value-removing filters. Filters must apply to the entire expression, not merely one of its children. ActionSources names credential outputs produced by a known action.
func SecretLeakRule ¶
func SecretLeakRule() Rule
SecretLeakRule reports disclosure, not ordinary credential consumption. Encoding, formatting, masking registration, and env indirection do not remove taint. Boolean predicates deliberately declassify presence/equality results.
type Site ¶
Site identifies a sink without including its potentially sensitive contents. Line is relative to the run script; Path is an AST property path.
type TextExpression ¶
TextExpression describes one interpolation without retaining its contents. Line is relative to the supplied text and Sources contains symbolic origins.
func AnalyzeText ¶
func AnalyzeText(ctx context.Context, text, path string, rule Rule, bindings map[string][]Source) ([]TextExpression, error)
AnalyzeText tracks sources in direct Actions interpolations, without treating shell expansions as executable interpolation. Bindings are symbolic Actions references, such as env.title, not shell variables. Results preceding a malformed expression are returned alongside the value-free parsing error.
type TypeScriptParser ¶
type TypeScriptParser struct {
ModuleDirectory string
NodeExecutable string
Environment []string
// contains filtered or unexported fields
}
TypeScriptParser uses only the upstream-exported native-preview API. ModuleDirectory must contain an explicitly installed, exactly pinned @typescript/native-preview@7.0.0-dev.20260707.2. Nothing is downloaded at runtime.
func (*TypeScriptParser) Parse ¶
func (p *TypeScriptParser) Parse(ctx context.Context, source string) (*JavaScriptNode, error)
func (*TypeScriptParser) ParseBatch ¶
func (p *TypeScriptParser) ParseBatch(ctx context.Context, sources []string) ([]JavaScriptParseResult, error)
Source Files
¶
- authored.go
- authored_scripts.go
- expression.go
- javascript.go
- javascript_batch.go
- javascript_calls.go
- javascript_closures.go
- javascript_eval.go
- javascript_metadata.go
- javascript_modules.go
- javascript_native.go
- javascript_sources.go
- javascript_summaries.go
- javascript_values.go
- javascript_workflow.go
- secrets.go
- shell.go
- shell_predicate.go
- taint.go
- text.go
- workflow.go