9.8 KiB
Core Pack Actions
Overview
All actions in the core pack follow Attune's secure-by-design architecture:
- Parameter delivery: stdin (JSON format) - never environment variables
- Output format: Explicitly declared (text, json, or yaml)
- Output schema: Describes structured data shape (json/yaml only)
- Execution metadata: Automatically captured (stdout/stderr/exit_code)
Parameter Delivery Method
All actions:
- Read parameters from stdin as JSON
- Use
parameter_delivery: stdinandparameter_format: jsonin their YAML definitions - DO NOT use environment variables for parameters
Output Format
All actions must specify an output_format:
text- Plain text output (stored as-is, no parsing)json- JSON structured data (parsed into JSONB field)yaml- YAML structured data (parsed into JSONB field)
Output schema:
- Only applicable for
jsonandyamlformats - Describes the structure of data written to stdout
- Should NOT include stdout/stderr/exit_code (captured automatically)
Environment Variables
Standard Environment Variables (Provided by Worker)
The worker automatically provides these environment variables to all action executions:
| Variable | Description | Always Present |
|---|---|---|
ATTUNE_ACTION |
Action ref (e.g., core.http_request) |
✅ Yes |
ATTUNE_EXEC_ID |
Execution database ID | ✅ Yes |
ATTUNE_API_TOKEN |
Execution-scoped API token | ✅ Yes |
ATTUNE_RULE |
Rule ref that triggered execution | ❌ Only if from rule |
ATTUNE_TRIGGER |
Trigger ref that caused enforcement | ❌ Only if from trigger |
Use cases:
- Logging with execution context
- Calling Attune API (using
ATTUNE_API_TOKEN) - Conditional logic based on rule/trigger
- Creating child executions
- Accessing secrets via API
Example:
#!/bin/bash
# Log with context
echo "[$ATTUNE_ACTION] [Exec: $ATTUNE_EXEC_ID] Processing..." >&2
# Call Attune API
curl -s -H "Authorization: Bearer $ATTUNE_API_TOKEN" \
"$ATTUNE_API_URL/api/v1/executions/$ATTUNE_EXEC_ID"
# Conditional behavior
if [ -n "$ATTUNE_RULE" ]; then
echo "Triggered by rule: $ATTUNE_RULE" >&2
fi
See Execution Environment Variables for complete documentation.
Custom Environment Variables (Optional)
Custom environment variables can be set via execution.env_vars field for:
- Debug/logging controls (e.g.,
DEBUG=1,LOG_LEVEL=debug) - Runtime configuration (e.g., custom paths, feature flags)
- Action-specific context (non-sensitive execution context)
Environment variables should NEVER be used for:
- Action parameters (use stdin instead)
- Secrets or credentials (use
ATTUNE_API_TOKENto fetch from key vault) - User-provided data (use stdin parameters)
Implementation Patterns
Bash/Shell Actions
Shell actions read JSON from stdin using jq:
#!/bin/bash
set -e
set -o pipefail
# Read JSON parameters from stdin
INPUT=$(cat)
# Parse parameters using jq
PARAM1=$(echo "$INPUT" | jq -r '.param1 // "default_value"')
PARAM2=$(echo "$INPUT" | jq -r '.param2 // ""')
# Check for null values (optional parameters)
if [ -n "$PARAM2" ] && [ "$PARAM2" != "null" ]; then
echo "Param2 provided: $PARAM2"
fi
# Use the parameters
echo "Param1: $PARAM1"
Advanced Bash Actions
For more complex bash actions (like http_request.sh), use curl or other standard utilities:
#!/bin/bash
set -e
set -o pipefail
# Read JSON parameters from stdin
INPUT=$(cat)
# Parse parameters
URL=$(echo "$INPUT" | jq -r '.url // ""')
METHOD=$(echo "$INPUT" | jq -r '.method // "GET"')
# Validate required parameters
if [ -z "$URL" ]; then
echo "ERROR: url parameter is required" >&2
exit 1
fi
# Make HTTP request with curl
RESPONSE=$(curl -s -X "$METHOD" "$URL")
# Output result as JSON
jq -n \
--arg body "$RESPONSE" \
--argjson success true \
'{body: $body, success: $success}'
Core Pack Actions
Simple Actions
- echo.sh - Outputs a message
- sleep.sh - Pauses execution for a specified duration
- noop.sh - Does nothing (useful for testing)
HTTP Action
- http_request.sh - Makes HTTP requests with authentication support (curl-based)
Pack Management Actions (API Wrappers)
These actions wrap API endpoints and pass parameters to the Attune API:
- download_packs.sh - Downloads packs from git/HTTP/registry
- build_pack_envs.sh - Builds runtime environments for packs
- register_packs.sh - Registers packs in the database
- get_pack_dependencies.sh - Analyzes pack dependencies
Testing Actions Locally
You can test actions locally by piping JSON to stdin:
# Test echo action
echo '{"message": "Hello from stdin!"}' | ./echo.sh
# Test echo with no message (outputs empty line)
echo '{}' | ./echo.sh
# Test sleep action
echo '{"seconds": 2, "message": "Sleeping..."}' | ./sleep.sh
# Test http_request action
echo '{"url": "https://api.github.com", "method": "GET"}' | ./http_request.sh
# Test with file input
cat params.json | ./echo.sh
Migration Summary
Before (using environment variables):
MESSAGE="${ATTUNE_ACTION_MESSAGE:-}"
After (using stdin JSON):
INPUT=$(cat)
MESSAGE=$(echo "$INPUT" | jq -r '.message // ""')
Security Benefits
- No process exposure - Parameters never appear in
ps,/proc/<pid>/environ - Secure by default - All actions use stdin, no special configuration needed
- Clear separation - Action parameters vs. environment configuration
- Audit friendly - All sensitive data flows through stdin, not environment
YAML Configuration
All action YAML files explicitly declare parameter delivery and output format:
name: example_action
ref: core.example_action
runner_type: shell
entry_point: example.sh
# Parameter delivery: stdin for secure parameter passing (no env vars)
parameter_delivery: stdin
parameter_format: json
# Output format: text, json, or yaml
output_format: text
parameters:
type: object
properties:
message:
type: string
description: "Message to output (empty string if not provided)"
required: []
# Output schema: not applicable for text output format
# For json/yaml formats, describe the structure of data your action outputs
# Do NOT include stdout/stderr/exit_code - those are captured automatically
# Do NOT include generic "status" or "result" wrappers - output your data directly
Best Practices
Parameters
- Always use stdin for action parameters
- Use jq for bash scripts to parse JSON
- Handle null values - Use jq's
// "default"operator to provide defaults - Provide sensible defaults - Use empty string, 0, false, or empty array/object as appropriate
- Validate required params - Exit with error if required parameters are missing (when truly required)
- Mark secrets - Use
secret: truein YAML for sensitive parameters - Never use env vars for parameters - Parameters come from stdin, not environment
Environment Variables
- Use standard ATTUNE_ variables* - Worker provides execution context
- Access API with ATTUNE_API_TOKEN - Execution-scoped authentication
- Log with context - Include
ATTUNE_ACTIONandATTUNE_EXEC_IDin logs - Custom env vars via execution.env_vars - For debug flags and configuration only
- Never log ATTUNE_API_TOKEN - Security sensitive
- Check ATTUNE_RULE/ATTUNE_TRIGGER - Conditional behavior for automated vs manual
- Use env vars for runtime context - Not for user data or parameters
Output Format
- Specify output_format - Always set to "text", "json", or "yaml"
- Use text for simple output - Messages, logs, unstructured data
- Use json for structured data - API responses, complex results
- Use yaml for readable config - Human-readable structured output
- Define schema for structured output - Only for json/yaml formats
- Don't include execution metadata - No stdout/stderr/exit_code in schema
- Use stderr for errors - Diagnostic messages go to stderr, not stdout
- Return proper exit codes - 0 for success, non-zero for failure
Dependencies
All core pack actions have zero runtime dependencies:
- Bash actions: Require
jq(for JSON parsing) andcurl(for HTTP requests) - Both
jqandcurlare standard utilities available in all Attune worker containers - No Python, Node.js, or other runtime dependencies required
Execution Metadata (Automatic)
The following are automatically captured by the worker and should NOT be included in output schemas:
stdout- Raw standard output (captured as-is)stderr- Standard error output (written to log file)exit_code- Process exit code (0 = success)duration_ms- Execution duration in milliseconds
These are execution system concerns, not action output concerns.
Example: Using Environment Variables and Parameters
#!/bin/bash
set -e
set -o pipefail
# Standard environment variables (provided by worker)
echo "[$ATTUNE_ACTION] [Exec: $ATTUNE_EXEC_ID] Starting execution" >&2
# Read action parameters from stdin
INPUT=$(cat)
URL=$(echo "$INPUT" | jq -r '.url // ""')
if [ -z "$URL" ]; then
echo "ERROR: url parameter is required" >&2
exit 1
fi
# Log execution context
if [ -n "$ATTUNE_RULE" ]; then
echo "Triggered by rule: $ATTUNE_RULE" >&2
fi
# Make request
RESPONSE=$(curl -s "$URL")
# Output result
echo "$RESPONSE"
echo "[$ATTUNE_ACTION] [Exec: $ATTUNE_EXEC_ID] Completed successfully" >&2
exit 0
Future Considerations
- Consider adding a bash library for common parameter parsing patterns
- Add parameter validation helpers
- Create templates for new actions in different languages
- Add output schema validation tooling
- Add helper functions for API interaction using ATTUNE_API_TOKEN