Module: Legion::Crypt::Attestation

Extended by:
Logging::Helper
Defined in:
lib/legion/crypt/attestation.rb

Constant Summary

Constants included from Logging::Helper

Logging::Helper::CompatLogger

Class Method Summary collapse

Methods included from Logging::Helper

handle_exception, log

Class Method Details

.create(agent_id:, capabilities:, state:, private_key:) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/legion/crypt/attestation.rb', line 12

def create(agent_id:, capabilities:, state:, private_key:)
  claim = {
    agent_id:     agent_id,
    capabilities: Array(capabilities),
    state:        state.to_s,
    timestamp:    Time.now.utc.iso8601,
    nonce:        SecureRandom.hex(16)
  }

  payload = Legion::JSON.dump(claim)
  signature = Legion::Crypt::Ed25519.sign(payload, private_key)
  log.info "Attestation created for agent #{agent_id}, state=#{state}"

  { claim: claim, signature: signature.unpack1('H*'), payload: payload }
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.attestation.create', agent_id: agent_id, state: state)
  raise
end

.fresh?(claim_hash, max_age_seconds: 300) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
51
52
53
54
55
# File 'lib/legion/crypt/attestation.rb', line 48

def fresh?(claim_hash, max_age_seconds: 300)
  timestamp = Time.parse(claim_hash[:timestamp])
  Time.now.utc - timestamp < max_age_seconds
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'crypt.attestation.fresh?',
                      agent_id: claim_hash[:agent_id] || claim_hash['agent_id'])
  false
end

.verify(claim_hash:, signature_hex:, public_key:) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/legion/crypt/attestation.rb', line 31

def verify(claim_hash:, signature_hex:, public_key:)
  payload = Legion::JSON.dump(claim_hash)
  signature = [signature_hex].pack('H*')
  result = Legion::Crypt::Ed25519.verify(payload, signature, public_key)
  agent_id = claim_hash[:agent_id] || claim_hash['agent_id']
  if result
    log.info "Attestation verified for agent #{agent_id}"
  else
    log.warn "Attestation verification failed for agent #{agent_id}"
  end
  result
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'crypt.attestation.verify',
                      agent_id: claim_hash[:agent_id] || claim_hash['agent_id'])
  raise
end