Authority
Cryptographic ownership of Smart Workflows. Authority is a Smart Action.
Authority executes as a Smart Action, producing cryptographic attestations of authorization. Can be simple (single signature) or complex (DAO governance).
Examples
w3-io/actions/authority/ed25519
v1Simple single-key authorization. Verify cryptographic signature from the workflow owner. Most common pattern for personal workflows.
Action Definition
# action.yml - Published in w3-io/actions repository
name: Single Key Authority
description: Simple Ed25519 signature verification
inputs:
pubkey:
description: Public key of workflow owner
required: true
outputs:
authorized:
description: Boolean authorization result
signer:
description: Recovered signer address
runs:
using: javascript
main: index.jsAuthority Configuration
authority:
uses: w3-io/actions/authority/ed25519@v1
with:
pubkey: "0x892b3c5e8d1f4a7c9e2b6d8a3f5c7e9b4d6a8c1e3b5d7a9c2e4f6b8d1a3c5e7"Execution
// Verify signature
const signer = recover_signer(
trigger_request,
authority_signature
);
if (signer === inputs.pubkey) {
return {
authorized: true,
signer: signer
};
}
return {
authorized: false,
reason: "Invalid signature"
};{
"authorized": true,
"signer": "0x892b3c5e8d1f4a7c9e2b6d8a3f5c7e9b4d6a8c1e3b5d7a9c2e4f6b8d1a3c5e7"
}Verification
// Everyone can verify the signature
fn verify(attestation: Attestation) -> bool {
let recovered = ecrecover(
attestation.trigger_hash,
attestation.signature
);
recovered == attestation.authority_pubkey
&& attestation.authority_pubkey == workflow.authority
}w3-io/actions/authority/multisig
v1M-of-N threshold signatures. Require multiple parties to approve workflow execution. Useful for shared workflows, corporate governance, or high-value operations.
Action Definition
# action.yml - Published in w3-io/actions repository
name: Multi-Signature Authority
description: M-of-N threshold signature verification
inputs:
signers:
description: Array of authorized public keys
required: true
threshold:
description: Minimum signatures required
required: true
outputs:
authorized:
description: Boolean authorization result
signers:
description: Array of signers who provided valid signatures
threshold_met:
description: M/N ratio
runs:
using: javascript
main: index.jsAuthority Configuration
authority:
uses: w3-io/actions/authority/multisig@v1
with:
signers:
- "0xabc123def456789abc123def456789abc123def456789abc123def456789abcd"
- "0xdef456789abc123def456789abc123def456789abc123def456789abc123def4"
- "0x123456789def123456789def123456789def123456789def123456789def1234"
threshold: 2Execution
// Collect and verify signatures
const signatures = trigger_request.authority_signatures;
const valid_signers = [];
for (const sig of signatures) {
const signer = recover_signer(trigger_request, sig);
if (inputs.signers.includes(signer)) {
valid_signers.push(signer);
}
}
if (valid_signers.length >= inputs.threshold) {
return {
authorized: true,
signers: valid_signers,
threshold_met: `${valid_signers.length}/${inputs.threshold}`
};
}
return {
authorized: false,
reason: "Insufficient signatures",
got: valid_signers.length,
need: inputs.threshold
};{
"authorized": true,
"signers": [
"0xabc123def456789abc123def456789abc123def456789abc123def456789abcd",
"0xdef456789abc123def456789abc123def456789abc123def456789abc123def4"
],
"threshold_met": "2/2"
}Verification
// Verify M-of-N threshold
fn verify(attestation: Attestation) -> bool {
let mut valid_count = 0;
for sig in attestation.signatures {
let signer = ecrecover(attestation.trigger_hash, sig);
if workflow.authority.signers.contains(signer) {
valid_count += 1;
}
}
valid_count >= workflow.authority.threshold
}w3-io/actions/authority/mood-check
v1🎭 Only authorize workflows when Becky is in a good mood (via Slack sentiment analysis). Demonstrates shadow execution verification for non-deterministic authority. Perfect for Friday deployments - if Becky's stressed, maybe wait until Monday!
Action Definition
name: Mood-Based Authority
description: Sentiment analysis authorization (shadow execution)
inputs:
base_authority:
description: Base authority pubkey
required: true
person:
description: Person email to check
required: true
sentiment_threshold:
description: Minimum mood score
required: true
slack_api_key:
description: Slack API key (encrypted)
required: true
encrypted: true
outputs:
authorized:
description: Authorization result
sentiment:
description: Mood score
becky_mood:
description: Emoji representation
runs:
using: tee # Needs Slack API key!
platform: intel_sgx
main: dist/index.js
secrets:
- slack_api_keyAuthority Configuration
authority:
uses: w3-io/actions/authority/mood-check@v1
with:
base_authority: "0x892b3c5e8d1f4a7c9e2b6d8a3f5c7e9b4d6a8c1e3b5d7a9c2e4f6b8d1a3c5e7"
person: "becky@company.com"
sentiment_threshold: 0.6
slack_api_key: "${{ secrets.SLACK_API_KEY }}"Execution
// Verify signature first
const signer = recover_signer(trigger_request, authority_signature);
if (signer !== inputs.base_authority) {
return { authorized: false, reason: "Invalid signature" };
}
// Check Becky's mood via Slack sentiment AI
const recent_messages = await slack.getRecentMessages({
user: inputs.person,
hours: 4
});
const sentiment = await ai.analyzeSentiment({
messages: recent_messages,
model: "sentiment-v2"
});
if (sentiment.score < inputs.sentiment_threshold) {
return {
authorized: false,
reason: "Becky seems stressed, maybe try again later? 😅",
sentiment: sentiment.score,
becky_mood: "😰",
suggestion: "It's 2/13/2026, maybe Monday is better"
};
}
return {
authorized: true,
sentiment: sentiment.score,
becky_mood: "😊",
message: "Becky's vibes are immaculate, workflow approved!"
};{
"authorized": true,
"sentiment": 0.78,
"becky_mood": "😊",
"message": "Becky's vibes are immaculate, workflow approved!"
}Verification
// Shadow execution: Multiple validators check Becky's mood
fn verify(attestation: Attestation) -> bool {
// Each validator calls Slack API + sentiment analysis
let my_sentiment = check_becky_mood();
// Outputs should correlate (similar sentiment score)
let similarity = abs(my_sentiment - attestation.sentiment);
// Allow 0.15 variance (sentiment is fuzzy)
similarity < 0.15
&& attestation.sentiment >= 0.6
}w3-io/actions/authority/dao
v1Onchain DAO governance via smart contract proposal voting. COMPOSITE ACTION: Reuses w3-io/actions/ethereum/contract-call for blockchain reads, then applies authorization logic. Demonstrates how complex Smart Actions compose from primitives.
Action Definition
name: DAO Governance Authority
description: Onchain voting authorization (composite)
inputs:
proposal_id:
description: Proposal to verify
required: true
dao_contract:
description: DAO contract address
required: true
min_quorum:
description: Min votes required
required: true
outputs:
authorized:
description: Vote passed result
eth_call_attestation:
description: Nested blockchain proof
runs:
using: composite
steps:
- uses: w3-io/actions/ethereum/contract-call@v1
- uses: w3-io/actions/internal/dao-logic@v1Authority Configuration
authority:
uses: w3-io/actions/authority/dao@v1
with:
proposal_id: 42
dao_contract: "0x742d35Cc6534C55A29f80225f451429db3eEf63e"
min_quorum: 100000Execution
// ═══════════════════════════════════════════════════════
// COMPOSITE SMART ACTION
// This action REUSES the generic Ethereum read primitive
// ═══════════════════════════════════════════════════════
// STEP 1: Invoke the primitive Ethereum contract-call action
const eth_call_result = await invoke_action({
uses: "w3-io/actions/ethereum/contract-call@v1",
with: {
contract: inputs.dao_contract,
function_signature: "getProposal(uint256)",
parameters: [inputs.proposal_id],
block: 18500123 // Proposal finalized at this block
}
});
// ethereum/contract-call returns:
// {
// result: { yes_votes: 150000, no_votes: 45000, ... },
// attestation: { block_hash, state_root, call_result, ... }
// }
// STEP 2: Post-process with DAO-specific authorization logic
const proposal = eth_call_result.result;
// Check quorum
if (proposal.yes_votes < inputs.min_quorum) {
return {
authorized: false,
reason: "Quorum not met",
yes_votes: proposal.yes_votes,
required: inputs.min_quorum,
// INCLUDE nested attestation
eth_call_attestation: eth_call_result.attestation
};
}
// Check vote passed
if (proposal.yes_votes <= proposal.no_votes) {
return {
authorized: false,
reason: "Vote failed",
yes_votes: proposal.yes_votes,
no_votes: proposal.no_votes,
eth_call_attestation: eth_call_result.attestation
};
}
// ✓ Authorized!
return {
authorized: true,
proposal_id: inputs.proposal_id,
yes_votes: proposal.yes_votes,
no_votes: proposal.no_votes,
quorum_met: true,
// NESTED ATTESTATION: Inherit cryptographic proof from primitive
eth_call_attestation: eth_call_result.attestation
};
// ═══════════════════════════════════════════════════════
// The DAO authority attestation INCLUDES the Ethereum
// call attestation - verification is recursive!
// ═══════════════════════════════════════════════════════{
"authorized": true,
"proposal_id": 42,
"yes_votes": 150000,
"no_votes": 45000,
"quorum_met": true,
"eth_call_attestation": {
"action": "w3-io/actions/ethereum/contract-call@v1",
"block_hash": "0x4a8e71c9d5f2b3a7e8c1f4d6b9a2e5c8d1f4b7a3",
"block_number": 18500123,
"state_root": "0x7d3f2e8a1c4b5d6e9f0a3c7b2d5e8f1a4c7b0d3e",
"call_result": {
"yes_votes": 150000,
"no_votes": 45000
},
"contract": "0x742d35Cc6534C55A29f80225f451429db3eEf63e",
"function_sig": "getProposal(uint256)"
}
}Verification
// Recursive verification of composite action
fn verify(attestation: DaoAuthorityAttestation) -> bool {
// STEP 1: Verify the nested Ethereum call attestation
// (This is the cryptographic proof!)
let eth_valid = verify_ethereum_call(
attestation.eth_call_attestation
);
if !eth_valid {
return false; // Blockchain read was fraudulent
}
// STEP 2: Verify the DAO logic was applied correctly
// (Deterministic post-processing)
let proposal = attestation.eth_call_attestation.call_result;
let quorum_met = proposal.yes_votes >= attestation.min_quorum;
let vote_passed = proposal.yes_votes > proposal.no_votes;
// Verify the authorization decision matches the data
(attestation.authorized == (quorum_met && vote_passed))
&& eth_valid
}
// ═══════════════════════════════════════════════════════
// Verification is RECURSIVE:
// 1. Verify primitive (ethereum/contract-call)
// 2. Verify composition (DAO logic)
//
// Security = Security of primitive + Determinism of glue
// ═══════════════════════════════════════════════════════Operations
The authority can perform the following operations on a workflow:
deploy_workflow— Deploy compiled workflow (bytecode + manifest), generates workflow_hash from contentdispatch_workflow— Manually trigger workflow execution (workflow_dispatch)update_workflow_authority— Transfer workflow ownership to new public keyupdate_workflow_payer— Change account paying for workflow executionupdate_workflow_triggers— Modify theon:conditions (schedules, blockchain events, etc.)archive_workflow— Permanently disable workflow, mark as deprecated
Note: Changing workflow logic requires deploying a new workflow with a new hash. There is no "update logic" operation.