Attestation Framework
Attestation schemas and processes are still being finalized. Future integration with EAS (Ethereum Attestation Service) may change implementation details. Check reputation.oma3.org for current status.
Attestations are the foundation of trust in OMATrust. They provide cryptographic proof that a service has been verified, audited, or reviewed by trusted third parties.
What are Attestations?
An attestation is a cryptographically signed statement about a service, stored on-chain:
"I, [Issuer], verify that [Service] has [Property]"
Examples:
- "Trail of Bits verifies that did:web:defi.example.com passed security audit on 2025-01-15"
- "Oracle verifies that did:web:api.example.com owns the domain"
- "User Alice gives did:web:game.example.com a 5-star rating"
Properties:
- Immutable - Can't be changed after issuance
- Timestamped - Includes issuance date
- Cryptographically Signed - Issuer's signature proves authenticity
- On-Chain - Publicly queryable and verifiable
Types of Attestations
1. DID Ownership Attestations
Purpose: Prove the service owner controls the DID
Issued by: OMATrust oracle (automated)
Schemas:
OMA3/DIDOwnership
- General DID controlOMA3/DomainOwnership
- Specific to did:webOMA3/ContractOwnership
- Specific to did:pkh
Verification Methods:
For did:web:
1. Fetch https://example.com/.well-known/did.json
2. Check if wallet address in DID document
3. Issue attestation if match found
For did:pkh:
1. Extract contract address from DID
2. Query contract.owner() or contract.admin()
3. Verify matches connected wallet
4. Issue attestation
2. DataHash Attestations
Purpose: Verify the integrity of metadata at dataUrl
Issued by: OMATrust oracle (automated on registration)
Flow:
// 1. App registers with dataUrl
dataUrl: "https://api.example.com/metadata.json"
dataHash: "0xabc123..." (keccak256 of JSON content)
// 2. Oracle fetches and verifies
const fetched = await fetch(dataUrl);
const computed = keccak256(fetched);
if (computed === dataHash) {
// 3. Issue attestation
await resolver.attestDataHash(didHash, dataHash);
}
Clients can verify:
const verified = await resolver.checkDataHashAttestation(didHash, dataHash);
if (verified) {
// ✅ Metadata hasn't been tampered with
// ✅ Oracle confirmed the hash
}
3. Security Audit Attestations
Purpose: Prove a service passed professional security review
Issued by: Security firms, auditing companies
Examples:
- Trail of Bits
- CertiK
- OpenZeppelin
- Hacken
Schema Fields:
{
auditor: "Trail of Bits",
did: "did:web:defi.example.com",
auditType: "smart-contract-security",
passed: true,
reportUrl: "https://audits.trailofbits.com/report-123.pdf",
timestamp: 1735689600,
expiresAt: 1767225600, // Valid for 1 year
severity: {
critical: 0,
high: 0,
medium: 2,
low: 5
}
}
4. Compliance Attestations
Purpose: Prove regulatory or industry compliance
Examples:
- GDPR compliant
- SOC2 certified
- HIPAA compliant
- Age rating (ESRB, PEGI)
Issued by:
- Compliance auditors
- Industry certification bodies
- Legal firms
5. Performance/Uptime Attestations
Purpose: Verify SLA compliance, reliability
Issued by: Monitoring oracles, independent observers
Metrics:
{
did: "did:web:api.example.com",
uptime: 99.97,
avgResponseTime: 120, // ms
period: "30d",
timestamp: 1735689600
}
6. User Review Attestations
Purpose: Community feedback and ratings
Issued by: Verified users
Structure:
{
reviewer: "0xUser123...",
did: "did:web:game.example.com",
rating: 4.5,
category: "gameplay",
comment: "Great graphics, minor bugs",
timestamp: 1735689600
}
Anti-Sybil: Reviewers must be verified through:
- Proof of personhood
- On-chain activity history
- Social graph attestations
Attestation Architecture
Resolver Contract
Contract: OMA3ResolverWithStore.sol
Core Functions:
// Write attestation (issuers only)
function upsertDirect(
bytes32 didHash,
bytes32 controllerAddress,
uint64 expiresAt
) external onlyIssuer
// Check attestation (anyone)
function checkDID(bytes32 didHash, address controller)
view returns (bool)
function checkDataHashAttestation(bytes32 didHash, bytes32 dataHash)
view returns (bool)
Issuer Management
Adding issuers (admin only):
npx hardhat resolver-add-issuer \
--issuer 0xOracleAddress \
--network omachainTestnet
Removing issuers:
npx hardhat resolver-remove-issuer \
--issuer 0xOracleAddress \
--network omachainTestnet
Viewing attestations:
npx hardhat resolver-view-attestations \
--did "did:web:example.com" \
--network omachainTestnet
Maturation Period
Purpose: Prevent instant-trust attacks
Mechanism:
maturationTime: 60 seconds (default, configurable)
Attestations don't become "valid" until maturation period passes. This allows time for community review and prevents flash-loan style attacks.
Using Attestations (Client Perspective)
Frontend Verification
Check before displaying:
import { getResolverContract } from '@/lib/contracts/client';
import { readContract } from 'thirdweb';
import { ethers } from 'ethers';
async function verifyService(did: string, ownerAddress: string) {
const resolver = getResolverContract();
const didHash = ethers.id(did);
// Check DID ownership
const ownerVerified = await readContract({
contract: resolver,
method: 'function checkDID(bytes32, address) view returns (bool)',
params: [didHash, ownerAddress]
});
// Fetch app data
const app = await registry.getApp(did, 1);
// Check dataHash attestation
const dataVerified = await readContract({
contract: resolver,
method: 'function checkDataHashAttestation(bytes32, bytes32) view returns (bool)',
params: [didHash, app.dataHash]
});
return {
ownerVerified,
dataVerified,
trustScore: ownerVerified && dataVerified ? 'HIGH' : 'MEDIUM'
};
}
Smart Contract Integration
import "./OMA3ResolverWithStore.sol";
contract MyContract {
OMA3ResolverWithStore public resolver;
function verifyServiceBeforeUse(string memory did, address owner) public view returns (bool) {
bytes32 didHash = keccak256(bytes(did));
// Check ownership attestation
return resolver.checkDID(didHash, owner);
}
}
AI Agent Integration
# Python example for AI agents
import web3
from eth_utils import keccak
def verify_api_before_call(did: str, api_url: str):
resolver = get_resolver_contract()
did_hash = keccak(text=did)
# Check attestations
owner_verified = resolver.functions.checkDID(did_hash, expected_owner).call()
if not owner_verified:
raise Exception(f"API {api_url} failed ownership verification")
# Safe to call API
return requests.get(api_url)
Issuing Attestations (Auditor Perspective)
Becoming an Issuer
-
Request Authorization:
- Contact OMA3 governance
- Provide credentials/reputation
- Get issuer address approved
-
Fund Issuer Wallet:
- Get testnet OMA tokens from faucet
- For mainnet: acquire OMA tokens
-
Issue Attestations:
import { privateKeyToAccount } from 'thirdweb/wallets';
import { prepareContractCall, sendTransaction } from 'thirdweb';
const resolver = getResolverContract();
const issuerAccount = privateKeyToAccount({ privateKey });
const tx = prepareContractCall({
contract: resolver,
method: 'function upsertDirect(bytes32, bytes32, uint64)',
params: [didHash, controllerAddress, expiresAt]
});
const result = await sendTransaction({ transaction: tx, account: issuerAccount });
Best Practices for Issuers
1. Verify thoroughly before attesting:
- Don't rubber-stamp - reputation is on the line
- Use automated checks where possible
- Document verification process
2. Set appropriate expiration:
- Security audits: 6-12 months
- Uptime attestations: 30 days (renew frequently)
- Compliance: Match certification validity
3. Revoke if needed:
- If service is compromised, revoke attestation
- Update expiration to current timestamp
4. Track gas costs:
- Each attestation costs gas
- Batch attestations when possible
- Consider sponsorship for high-volume issuance
Attestation Economics
Cost Structure
Issuing attestation:
- Gas cost: ~50k-100k gas
- At 1 gwei: ~$0.01-0.02 per attestation
- Testnet: Free (faucet tokens)
Querying attestation:
- Free (view function)
- No gas cost for clients
Subsidization (Future)
On OMAchain mainnet, critical trust functions may be subsidized:
- DID ownership verification: Free
- Security audits from approved auditors: Discounted
- User reviews: Gas-sponsored
Revenue Model (Future)
Potential monetization for issuers:
- Premium attestation services
- Real-time monitoring attestations
- Expedited verification
- Detailed audit reports (off-chain, paid)
Security Considerations
Attestation Integrity
What's cryptographically guaranteed:
- ✅ Issuer signed the attestation
- ✅ Timestamp is accurate (block time)
- ✅ Attestation hasn't been modified
What's NOT guaranteed:
- ❌ Issuer is honest (trust the issuer's reputation)
- ❌ Verification was thorough (depends on issuer)
- ❌ Service hasn't changed since attestation
Mitigation Strategies
1. Issuer Reputation:
- Track issuer history
- Require multiple attestations from different issuers
- Penalize issuers who issue false attestations
2. Expiration:
- All attestations should expire
- Force periodic re-verification
- Shorter expiration for high-risk services
3. Redundancy:
- Require N-of-M attestations
- Example: 3 out of 5 auditors must attest
4. Continuous Monitoring:
- Oracles continuously check services
- Revoke attestations if issues detected
- Real-time status updates
Common Patterns
Pattern 1: Initial Registration
1. Developer mints app NFT
2. Automated oracle verifies DID ownership
3. Oracle attests dataHash
4. Service is "verified" (basic trust)
Pattern 2: Professional Audit
1. Developer requests audit from Trail of Bits
2. Trail of Bits conducts review
3. If passed, Trail of Bits issues attestation
4. Service shows "Audited by Trail of Bits" badge
Pattern 3: Continuous Verification
1. Monitoring oracle watches service uptime
2. Every 24 hours, issues fresh uptime attestation
3. Clients see real-time reliability data
4. If downtime exceeds threshold, oracle stops attesting
Pattern 4: Community Reviews
1. User tries service, has good experience
2. User (verified via proof-of-personhood) submits review attestation
3. Aggregate score computed from all reviews
4. Service displays: "4.5/5 stars from 127 verified users"
API Reference
Frontend Verification
Verify and attest (unified endpoint):
POST /api/verify-and-attest
Content-Type: application/json
{
"did": "did:web:example.com",
"connectedAddress": "0x123...",
"requiredSchemas": ["oma3.ownership.v1"]
}
Response:
{
"ok": true,
"status": "ready",
"attestations": {
"present": ["oma3.ownership.v1"],
"missing": []
},
"txHashes": ["0xabc..."],
"elapsed": "1234ms"
}
This endpoint is idempotent - it checks for existing attestations first (fast path), only verifying and writing new attestations if needed.
Smart Contract Queries
Check DID ownership:
function checkDID(bytes32 didHash, address controller)
external view returns (bool);
Check dataHash:
function checkDataHashAttestation(bytes32 didHash, bytes32 dataHash)
external view returns (bool);
View all attestations for a DID:
// Use hardhat task
npx hardhat resolver-view-attestations \
--did "did:web:example.com" \
--network omachainTestnet
Trust Levels
Based on attestations, services can be categorized:
Level 1: Unverified
- Attestations: None
- Trust: Minimal
- Display: Show warning to users
- Recommendation: Proceed with caution
Level 2: Basic Verification
- Attestations: DID ownership
- Trust: Basic
- Display: "Verified owner"
- Recommendation: OK for low-risk interactions
Level 3: Data Verified
- Attestations: DID + dataHash
- Trust: Medium
- Display: "Verified & data integrity confirmed"
- Recommendation: Safe for general use
Level 4: Audited
- Attestations: DID + dataHash + security audit
- Trust: High
- Display: "Audited by [Firm]"
- Recommendation: Safe for financial/sensitive operations
Level 5: Comprehensive Trust
- Attestations: All of the above + compliance + user reviews
- Trust: Very High
- Display: "Fully verified - 5 attestations"
- Recommendation: High confidence for any use
Attestation Schemas (Future)
OMATrust will adopt EAS (Ethereum Attestation Service) schemas:
Security Audit Schema
{
auditor: address,
auditType: string,
passed: boolean,
reportIpfsHash: bytes32,
criticalIssues: uint8,
highIssues: uint8,
mediumIssues: uint8,
lowIssues: uint8,
auditDate: uint64,
expiresAt: uint64
}
Uptime Schema
{
oracle: address,
uptime: uint16, // basis points (9997 = 99.97%)
avgResponseTime: uint32, // milliseconds
periodDays: uint8,
timestamp: uint64
}
User Review Schema
{
reviewer: address,
rating: uint8, // 1-5 stars
category: string, // "ux", "performance", "support"
verified: boolean, // proof of personhood
timestamp: uint64
}
Roadmap
Current (Testnet)
- ✅ DID ownership attestations
- ✅ DataHash attestations
- ✅ Basic resolver contract
- ✅ Oracle verification via API
Phase 2 (Q1 2025)
- EAS integration for structured schemas
- Security audit attestations (partner with audit firms)
- Uptime monitoring oracles
- Multi-issuer support
Phase 3 (Q2 2025)
- User review attestations
- Proof-of-personhood integration
- Aggregated trust scores
- Cross-chain attestation bridging
Phase 4 (Q3 2025)
- Attestation marketplace
- Reputation staking
- Automated re-attestation
- AI agent verification protocols
For Developers
Getting verified:
- Register service at registry.omatrust.org
- Automatic DID + dataHash attestations issued
- Request professional audits (optional)
- Display attestation badges on your site
Displaying trust:
<!-- OMATrust Trust Badge -->
<div class="omatrust-badge" data-did="did:web:example.com">
<img src="https://cdn.omatrust.org/badges/verified.svg" alt="OMATrust Verified" />
<span>Verified • 3 Attestations</span>
</div>
For Auditors
Becoming an issuer:
- Build reputation in security community
- Apply to OMA3 governance
- Get authorized as issuer
- Issue attestations via resolver contract
Revenue opportunities:
- Charge clients for audits
- Issue attestations as service output
- Build reputation as trusted issuer
For Users/Clients
Checking trust before using a service:
// Simple check
const app = await registry.getApp(did, major);
const hasAttestation = await resolver.checkDID(didHash, app.minter);
if (hasAttestation) {
// ✅ Basic trust established
}
// Comprehensive check
const attestations = await queryAllAttestations(did);
const trustScore = calculateTrustScore(attestations);
if (trustScore > 80) {
// ✅ High confidence - proceed
} else if (trustScore > 50) {
// ⚠️ Medium confidence - proceed with caution
} else {
// ❌ Low confidence - warning to user
}
Best Practices
For Service Publishers
- Get basic attestations early - DID + dataHash give baseline trust
- Invest in audits - Security attestations significantly boost trust
- Maintain compliance - Keep certifications current
- Encourage reviews - Happy users build reputation
- Monitor attestations - Track expiration, renew proactively
For Attestation Issuers
- Verify thoroughly - Your reputation depends on accuracy
- Set appropriate expiration - Force re-verification at reasonable intervals
- Document process - Transparency builds trust in your attestations
- Respond to disputes - Have process for reviewing challenged attestations
- Track performance - Monitor false positive/negative rates
For Client Applications
- Check multiple attestations - Don't rely on single source
- Respect maturation - Wait for attestations to mature
- Cache verification results - Avoid redundant on-chain queries
- Fallback gracefully - Handle services without attestations
- Educate users - Explain what attestations mean
Next Steps
- Registration Guide - Register and get attested
- Client Guide - Query attestations
- Auditor Guide - Issue attestations
Questions about attestations? Visit reputation.oma3.org or join the OMA3 Discord.