Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Odin Scan is an AI-powered smart contract security scanner that detects vulnerabilities across multiple blockchain platforms. It combines multi-agent AI analysis with deterministic static analysis to produce high-confidence findings with minimal false positives.

Supported Platforms

PlatformLanguagesEcosystem
CosmWasmRustCosmos SDK chains (Osmosis, Neutron, Terra, etc.)
EVMSolidity, VyperEthereum, Arbitrum, Base, Polygon, BSC, and all EVM-compatible chains
Solana (SVM)RustSolana (Anchor and native programs)

Odin Scan automatically detects the platform based on your project structure, or you can specify it explicitly.

Key Differentiators

Multi-Agent AI Analysis

Odin Scan runs multiple independent AI models in parallel, using the most advanced large language models available. Each model analyzes your code with platform-aware expertise. When multiple models flag the same issue, the finding’s confidence is automatically boosted, reducing noise and surfacing real vulnerabilities. The model lineup is continuously updated to incorporate the latest advances in AI reasoning.

Deterministic Static Analysis

Odin Scan ships platform-specific rules that catch known vulnerability patterns with zero ambiguity. These deterministic checks complement the AI-based detection to provide comprehensive coverage.

Verification Pipeline

Every AI-generated finding passes through a verification pipeline that cross-checks findings against the code and considers repository context (audit history, compiler version, trust model) to produce accurate final severity ratings.

Proof-of-Concept Generation

For confirmed vulnerabilities, Odin Scan can generate executable proof-of-concept code that demonstrates the exploit scenario, making it easier to understand and reproduce issues during remediation.

Integration Options

Odin Scan fits into your development workflow through three integration points:

  • GitHub Action – Drop a workflow file into your repository and receive security findings as PR comments, inline annotations, and GitHub Code Scanning alerts via SARIF upload. See GitHub Action Setup.
  • REST API – Submit code for analysis programmatically and retrieve structured results. See API Reference.

Who It Is For

  • Smart contract developers who want automated security checks integrated into their CI pipeline
  • Security teams performing initial triage before manual review
  • Auditors looking for a fast first pass to identify areas of concern in large codebases

Feature Overview

  • Multi-platform support with automatic detection (CosmWasm, EVM, Solana)
  • Multi-agent AI analysis with confidence boosting from cross-agent agreement
  • Deterministic static analysis rules
  • SARIF output for GitHub Code Scanning integration
  • PR comments with configurable visibility modes (full, counts, private)
  • Severity thresholds to gate CI pipelines
  • Proof-of-concept generation for confirmed vulnerabilities
  • Context-aware analysis using README, compiler info, and audit history
  • JSON, Markdown, and SARIF output formats

Quick Start

Get Odin Scan running on your repository in five minutes.

Step 1: Sign Up

Create an account at odinscan.ai. You can sign up with GitHub to automatically link your repositories.

Step 2: Create an API Key

  1. Go to Settings > API Keys in the Odin Scan dashboard
  2. Click Create API Key
  3. Copy the generated key (format: odin_sk_*)
  4. Add it as a repository secret in GitHub:
    • Navigate to your repository on GitHub
    • Go to Settings > Secrets and variables > Actions
    • Click New repository secret
    • Name: ODIN_SCAN_API_KEY
    • Value: paste your API key

Step 3: Add the GitHub Action

Create a workflow file at .github/workflows/security-scan.yml:

name: Security Scan
on:
  pull_request:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

This minimal configuration will:

  • Automatically detect your project’s platform (CosmWasm, EVM, or Solana)
  • Run the full analysis pipeline
  • Post a summary comment on the pull request
  • Upload SARIF results to GitHub Code Scanning
  • Fail the workflow if critical or high severity findings are detected

Step 4: Push a PR

Open a pull request against your main branch. The Odin Scan action will run automatically. Once the analysis completes, you will see:

  • A PR comment summarizing findings by severity
  • Inline annotations on the diff highlighting specific vulnerabilities
  • Security alerts in the repository’s Security tab (via SARIF)

Step 5: View the Full Report

Click the report link in the PR comment or navigate to odinscan.ai to view the full analysis report. The dashboard provides:

  • Detailed vulnerability descriptions with affected code locations
  • Remediation guidance for each finding
  • Proof-of-concept code (when available)
  • Historical scan comparisons across PRs

Next Steps

Overview

Odin Scan processes smart contract code through a proprietary analysis pipeline that combines AI analysis with deterministic static checks and a verification layer. The pipeline is designed to maximize detection accuracy while minimizing false positives.

How It Works

When you submit code for analysis, Odin Scan performs the following high-level steps:

  1. Platform Detection — Odin Scan examines your repository to determine whether you are building on CosmWasm, EVM, or Solana. You can also specify the platform explicitly.

  2. Context Understanding — Odin Scan gathers context about your project (README, compiler version, audit history, trust model) to tailor the analysis to your specific environment.

  3. AI + Static Analysis — Multiple AI models and deterministic static analysis rules analyze your code in parallel. Each analyzer operates independently to maximize coverage. See Multi-Agent AI and Static Analysis for more on each approach.

  4. Verification — Findings are cross-checked, deduplicated, and verified against the source code. False positive reduction runs automatically to ensure the findings that reach your report are accurate and actionable.

  5. Report Generation — Verified findings are formatted into the requested output: JSON, Markdown, or SARIF for GitHub Code Scanning. Each finding includes a title, description, severity, confidence, code location, and remediation guidance.

What You Get

Every scan produces a structured report containing:

  • Findings with severity (Critical, High, Medium, Low, Informational) and confidence levels
  • Code locations pinpointing the exact file and line number
  • Remediation guidance explaining how to fix each issue
  • Proof-of-concept code demonstrating exploit scenarios (when available)
  • Context-aware severity adjusted for your project’s specific environment

See Vulnerability Categories for the full breakdown of how findings are classified.

Multi-Agent AI

Odin Scan uses multiple independent AI models to analyze smart contract code. Each model operates on the same codebase, and their findings are aggregated to boost confidence through cross-model agreement.

How Multiple Models Work Together

Odin Scan maintains a lineup of the most advanced large language models available. Each model brings different reasoning strengths to the analysis. Running them in parallel and comparing results produces higher-quality findings than any single model alone.

The specific models are continuously updated as new, more capable models become available – ensuring Odin Scan always uses state-of-the-art AI for vulnerability detection.

Basic vs Pro Analysis

The depth of AI analysis depends on your subscription plan:

  • Basic plan – Odin Scan uses a single, capable AI model to analyze your code. This provides solid coverage for catching common vulnerability patterns and is well-suited for quick checks during development.
  • Pro plan – Odin Scan runs multiple bleeding-edge AI models in parallel, each analyzing independently. Cross-model consensus boosts finding confidence and catches subtle vulnerabilities that a single model might miss. This is the full multi-agent pipeline described below.

How It Works

Independent Analysis

Each AI model receives the smart contract source code along with relevant project context (compiler version, audit history, trust model). The models analyze the code independently – they do not see each other’s results. This independence is intentional: correlated findings from independent sources provide stronger signal than findings from a single source.

Confidence Boosting

When two or more models identify the same vulnerability (matched by category and code location), the finding’s confidence level is automatically increased:

  • A finding from a single model retains its original confidence
  • A finding confirmed by two models is promoted to at least Medium confidence
  • A finding confirmed by all models is promoted to High confidence

This mechanism filters noise. If only one model flags an issue and the others do not, it may still be valid, but it receives lower confidence and is subject to stricter verification.

Context-Aware Analysis

Odin Scan provides the AI models with repository context so they can reason about the broader environment of the contract. This includes:

  • Project description from README files
  • Compiler version and configuration
  • Audit history references to previous security reviews
  • Interface details about external integrations
  • Trust model information about administrative privileges

This context helps the AI models reduce false positives that would arise from analyzing code in isolation. For example, an access control pattern flagged as missing may be intentional in a contract where the admin is a governance module.

Platform-Specific Analysis

Each platform receives tailored analysis that focuses on the vulnerability patterns most relevant to that ecosystem:

  • CosmWasm – entry point access control, state management, cross-contract call safety, IBC-related risks, and cosmwasm-std API misuse
  • EVM – reentrancy, integer overflow, storage layout, delegatecall risks, flash loan attacks, and ERC standard compliance
  • Solana – account validation, signer checks, PDA derivation, CPI safety, and rent-exemption issues

The analysis rules are continuously updated as new vulnerability patterns emerge across each ecosystem.

Supported Platforms

Odin Scan supports three smart contract platforms. Each platform has dedicated analysis logic and platform-specific rules.

CosmWasm

Language: Rust Ecosystem: Cosmos SDK chains (Osmosis, Neutron, Terra, Injective, Juno, etc.)

Detection

Odin Scan identifies CosmWasm projects by checking for cosmwasm-std in Cargo.toml dependencies.

Analysis Features

  • Entry point analysis (instantiate, execute, query, migrate, sudo)
  • State management validation (storage reads/writes, key collision detection)
  • Access control checks on privileged operations
  • Cross-contract message handling and reply safety
  • IBC entry point validation
  • Addr::unchecked() usage detection
  • Unsafe arithmetic operation detection
  • Deterministic static analysis rules

Common Vulnerability Patterns

  • Missing access control on execute handlers
  • Unsafe math operations without overflow protection
  • Unvalidated addresses passed to contract state
  • Storage key collisions between different state items
  • Unbounded iteration over state maps

EVM

Languages: Solidity, Vyper Ecosystem: Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche, and all EVM-compatible chains

Detection

Odin Scan identifies EVM projects by the presence of .sol files combined with framework configuration:

  • foundry.toml (Foundry)
  • hardhat.config.js or hardhat.config.ts (Hardhat)

Analysis Features

  • Multi-agent AI analysis with EVM-specific rules
  • Solidity compiler version detection and version-specific checks
  • Reentrancy detection across external calls
  • Storage layout analysis
  • Access control and authorization pattern checks
  • ERC standard compliance verification

Common Vulnerability Patterns

  • Reentrancy via external calls before state updates
  • Integer overflow/underflow in older Solidity versions
  • Unprotected selfdestruct or delegatecall
  • Front-running and MEV exposure
  • Flash loan attack vectors
  • Missing input validation on public functions
  • Storage collision in proxy/upgrade patterns

Solana (SVM)

Language: Rust Ecosystem: Solana

Detection

Odin Scan identifies Solana projects by:

  • Anchor.toml and programs/ directory (Anchor framework)
  • Native Solana program structure with solana-program dependency

Analysis Features

  • Account validation and ownership checks
  • Signer verification analysis
  • PDA (Program Derived Address) derivation correctness
  • CPI (Cross-Program Invocation) safety
  • Anchor constraint validation (has_one, constraint, seeds)
  • Rent-exemption and account lifecycle checks

Common Vulnerability Patterns

  • Missing signer checks on privileged instructions
  • Incorrect account ownership validation
  • PDA seed collision or incorrect derivation
  • Unsafe CPI without proper account validation
  • Missing close account cleanup (leaving rent behind)
  • Type confusion between account structures

Auto-Detection

By default, Odin Scan automatically determines the platform by examining the repository structure. The detection order is:

  1. Check for CosmWasm markers (cosmwasm-std dependency)
  2. Check for EVM markers (.sol files with Foundry/Hardhat config)
  3. Check for Solana markers (Anchor.toml or solana-program dependency)

If detection is ambiguous or the repository contains multiple platforms, you can specify the platform explicitly:

# In the GitHub Action
- uses: odin-scan/odin-scan-action@v1
  with:
    api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
    platform: cosmwasm   # or: evm, solana

Platform Comparison

FeatureCosmWasmEVMSolana
AI AnalysisYesYesYes
Static AnalysisYesYesPlanned
PoC GenerationYesYesYes
Auto-DetectionYesYesYes

Vulnerability Categories

Odin Scan classifies findings using a structured system of severity levels, confidence levels, and vulnerability categories. Each finding includes actionable information to help developers understand and remediate the issue.

Severity Levels

SeverityDescription
CriticalExploitable vulnerabilities that can lead to direct loss of funds, total contract takeover, or irreversible damage. Requires immediate attention.
HighSignificant vulnerabilities that can lead to partial fund loss, unauthorized privilege escalation, or major contract malfunction under specific conditions.
MediumIssues that could lead to unexpected behavior, minor fund risk, or contract malfunction under unlikely but possible conditions.
LowCode quality issues, minor inefficiencies, or patterns that deviate from best practices but pose limited direct risk.
InformationalObservations, suggestions, and style issues with no direct security impact. Includes findings demoted by the severity adjustment stage.

Confidence Levels

Each finding carries a confidence level that reflects how certain Odin Scan is about the reported vulnerability:

ConfidenceDescription
HighFinding confirmed by multiple sources (cross-agent agreement or static analysis match). High likelihood of being a true positive.
MediumFinding reported by at least one AI agent with supporting evidence in the code. Likely a true positive but warrants manual review.
LowFinding reported by a single source with limited supporting evidence. May be a false positive – review recommended.

Confidence is boosted automatically when multiple independent analyzers flag the same issue. See Multi-Agent AI for details on the confidence boosting mechanism.

Vulnerability Categories

Odin Scan uses the following categories to classify findings:

Reentrancy

External calls that allow re-entering the contract before state updates are completed. Applies to EVM (cross-function and cross-contract reentrancy) and CosmWasm (via submessage replies).

Integer Overflow

Arithmetic operations that exceed the maximum or minimum value of their type. Relevant to older Solidity versions (pre-0.8.0) and Rust code using unchecked operations.

Access Control

Missing or insufficient authorization checks on privileged operations. Includes admin functions without ownership verification, missing signer checks on Solana, and unprotected entry points in CosmWasm.

State Management

Incorrect handling of contract state: reading stale data, writing state in the wrong order, failing to persist storage changes, or introducing race conditions between state transitions.

Input Validation

Insufficient validation of external inputs including function parameters, message fields, and account data. Covers missing bounds checks, type confusion, and unvalidated addresses.

Logic Errors

Flaws in business logic that cause the contract to behave contrary to its intended design. Includes incorrect fee calculations, broken invariants, and flawed conditional logic.

Gas Optimization

Patterns that waste computational resources. Includes unbounded loops, redundant storage operations, and inefficient data structures. Classified as Low or Informational severity.

Denial of Service (DoS)

Patterns that allow an attacker to make the contract unusable. Includes griefing vectors, unbounded iteration over user-controlled data, and blocking withdrawal patterns.

Information Disclosure

Unintended exposure of sensitive data through events, return values, or predictable state. Includes leaking private data in public transaction logs.

Timestamp Dependence

Reliance on block timestamps for security-critical logic. Timestamps can be manipulated by validators within certain bounds, making them unreliable for randomness or precise time checks.

Finding Structure

Each finding reported by Odin Scan includes the following fields:

FieldDescription
TitleShort description of the vulnerability
DescriptionDetailed explanation of the issue, how it can be exploited, and why it matters
SeverityCritical, High, Medium, Low, or Informational
ConfidenceHigh, Medium, or Low
CategoryOne of the categories listed above
LocationFile path and line number(s) where the vulnerability exists
RemediationRecommended fix with code guidance
PoCProof-of-concept code demonstrating the exploit (when available)

False Positive Reduction

Odin Scan applies multiple layers to reduce false positives before findings reach the final report:

  1. Verification – AI-generated findings are cross-checked against the source code to confirm that the vulnerability is present and reachable.

  2. Severity Adjustment – Repository context (audit history, compiler version, trust model) is used to adjust findings that may not be applicable to the specific project environment. Findings below the configured threshold are reclassified as Informational.

The combination of these layers means the findings that appear in the final report have passed through multiple validation steps and are more likely to represent genuine issues.

Static Analysis

Odin Scan includes deterministic static analysis rules that complement the AI-based detection. These rules provide precise, reproducible checks for known vulnerability patterns with zero ambiguity.

How Static Analysis Complements AI

AI-based analysis excels at detecting complex, context-dependent vulnerabilities that require understanding intent and business logic. Static analysis excels at catching well-defined patterns with zero false positives in common cases.

AspectAI AnalysisStatic Analysis
Pattern detectionComplex, contextualWell-defined, deterministic
False positive rateHigher (reduced by verification)Very low
Novel vulnerabilitiesCan detect previously unseen patternsLimited to known patterns
ReproducibilityMay vary between runsIdentical results every run

By running both in parallel, Odin Scan achieves broad coverage (AI) with high precision (static analysis).

CosmWasm Rules

The following rules are currently available for CosmWasm contracts:

RuleSeverityDescription
missing_access_controlCriticalDetects execute handlers and privileged operations that lack authorization checks. Looks for functions that modify state or transfer funds without verifying the caller’s identity or role.
unsafe_mathHighIdentifies arithmetic operations that could overflow or underflow. Flags direct use of +, -, *, / operators on integer types instead of checked or saturating alternatives.
unchecked_addrHighFinds usage of Addr::unchecked() where user-supplied strings are converted to addresses without validation via deps.api.addr_validate().
input_validationMediumDetects missing validation on message fields and function parameters. Checks for unbounded strings, missing range checks on numeric inputs, and unvalidated enum variants.
storage_key_collisionsMediumIdentifies storage items that use identical or overlapping keys, which can cause silent data corruption when two state items write to the same storage slot.
predictable_randomnessMediumDetects use of predictable sources for randomness such as block height, block time, or transaction hashes. These values can be manipulated or predicted by validators.
unsaved_storageLowFinds state modifications that are computed but never persisted to storage. Catches cases where a value is loaded, modified in memory, but the save() call is missing.
unbounded_loopsLowIdentifies loops that iterate over collections without pagination or upper bounds. In a smart contract context, unbounded iteration can exceed gas limits and cause transaction failures.

Rule Details

Each rule provides:

  • Exact code location – file path and line number of the flagged pattern
  • Explanation – why the pattern is problematic
  • Remediation – suggested code change to resolve the issue
  • Code examples – demonstrating both the vulnerable and secure pattern

Platform Coverage

Static analysis rules are organized by platform. Each platform has its own set of rules tailored to its specific vulnerability landscape:

PlatformStatusRule CountNotes
CosmWasmActive8+ rulesFull coverage of common CosmWasm vulnerabilities
SolanaPlannedWill cover Anchor constraints, account validation, PDA safety
EVMActiveIncludes additional Solidity-specific checks

Integration With AI Analysis

Static analysis runs in parallel with AI analysis. When a static analysis rule and an AI model both flag the same code location for the same category, the aggregated finding receives a confidence boost. This cross-validation between deterministic and probabilistic detection methods produces high-confidence results.

Setup

This guide walks you through adding the Odin Scan GitHub Action to your repository. By the end, every pull request will be automatically scanned for smart contract vulnerabilities.

Prerequisites

Before you begin, make sure you have:

  1. An Odin Scan API key – sign up at odinscan.ai, then navigate to Settings > API Keys and create a new key. Keys start with odin_sk_.
  2. A repository containing smart contracts – CosmWasm (Rust), Solana (Rust/Anchor), or EVM (Solidity/Vyper).
  3. Repository admin access – required to add secrets and configure workflows.

Step 1: Store Your API Key

Add the API key as a GitHub repository secret:

  1. Go to your repository on GitHub.
  2. Navigate to Settings > Secrets and variables > Actions.
  3. Click New repository secret.
  4. Set the name to ODIN_SCAN_API_KEY and paste your key as the value.
  5. Click Add secret.

Step 2: Create the Workflow File

Create the file .github/workflows/odin-scan.yml in your repository with the following contents:

name: Odin Scan Security Analysis
on:
  pull_request:
    branches: [main, master]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

Step 3: Commit and Open a Pull Request

Push the workflow file to your repository. The next time a pull request targets main or master, Odin Scan will automatically analyze your contracts and report findings.

What Happens During a Scan

When the action runs, it:

  1. Sends your source code to the Odin Scan API for analysis.
  2. Waits for results (up to 30 minutes by default).
  3. Posts a PR comment summarizing any findings.
  4. Uploads SARIF to GitHub Code Scanning, so findings appear in the Security tab and as inline annotations on the diff.
  5. Uploads the full report as a workflow artifact.
  6. Fails the check if any findings meet or exceed the severity threshold (default: high).

Permissions Explained

The workflow requires three permissions:

PermissionPurpose
contents: readAllows the runner to check out your repository
security-events: writeRequired to upload SARIF results to GitHub Code Scanning
pull-requests: writeRequired to post the findings summary as a PR comment

If you disable SARIF upload or PR comments via inputs, you can remove the corresponding permission.

Next Steps

  • See Inputs for the full list of configuration options.
  • See Outputs to learn how to use scan results in subsequent workflow steps.
  • See Examples for complete workflow files covering common scenarios.
  • See Findings Visibility if your repository is public and you want to control what details appear in PR comments.

Inputs

All inputs are configured under the with: key in your workflow step. Only api-key is required; every other input has a sensible default.

Quick Reference

InputRequiredDefaultDescription
api-keyYesOdin Scan API key
platformNoautoTarget platform
severity-thresholdNohighMinimum severity to fail the build
fail-on-findingsNotrueFail workflow when findings exceed threshold
comment-on-prNotruePost summary comment on pull requests
findings-visibilityNofullDetail level in PR comments and annotations
upload-sarifNotrueUpload SARIF to GitHub Code Scanning
upload-artifactNotrueUpload full report as workflow artifact
timeoutNo1800Maximum wait time in seconds
github-tokenNo${{ github.token }}GitHub token for API calls
api-urlNohttps://api.odinscan.aiOdin Scan API base URL

Detailed Reference

api-key

  • Required: Yes
  • Type: String
  • Default: None

Your Odin Scan API key, which starts with odin_sk_. Create one at odinscan.ai/dashboard/settings under API Keys.

Always store this as a repository secret rather than hardcoding it in the workflow file:

api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

platform

  • Required: No
  • Type: String
  • Default: auto
  • Allowed values: auto, cosmwasm, solana, evm

Specifies which smart contract platform to analyze. When set to auto, the action inspects your repository contents and selects the appropriate analyzer:

  • EVM – detected by .sol files and Foundry/Hardhat configuration.
  • CosmWasm – detected by Rust files with a cosmwasm-std dependency.
  • Solana – detected by Rust files with Anchor or native Solana program structure.

Set this explicitly if auto-detection selects the wrong platform or if your repository contains contracts for multiple platforms.

platform: evm

severity-threshold

  • Required: No
  • Type: String
  • Default: high
  • Allowed values: critical, high, medium, low, none

The minimum severity level at which the action marks the workflow as failed. For example, setting medium causes the action to fail if any finding is rated medium, high, or critical.

Setting none means the action never fails due to findings, regardless of severity. This is useful when you want to collect data without blocking merges.

severity-threshold: medium

fail-on-findings

  • Required: No
  • Type: Boolean (as string)
  • Default: true

Controls whether the action sets a failing exit code when findings exceed the severity threshold. When set to false, findings are still reported (PR comments, SARIF, artifacts) but the workflow step always succeeds.

fail-on-findings: false

comment-on-pr

  • Required: No
  • Type: Boolean (as string)
  • Default: true

When enabled, the action posts a summary comment on the pull request with a breakdown of findings by severity. Requires the pull-requests: write permission.

The level of detail in the comment is controlled by findings-visibility.

comment-on-pr: true

findings-visibility

  • Required: No
  • Type: String
  • Default: full
  • Allowed values: full, counts, private

Controls how much detail is shown in PR comments and inline annotations. This is primarily relevant for public repositories where PR comments are visible to anyone.

  • full – shows severity table, finding titles, file locations, and descriptions.
  • counts – shows severity table only; no titles, file paths, or descriptions.
  • private – shows only a link to the private report; no details at all.

This setting does not affect SARIF uploads or workflow artifacts, which are protected by GitHub’s own permission model.

See Findings Visibility for a detailed explanation of each mode and its threat model.

findings-visibility: counts

upload-sarif

  • Required: No
  • Type: Boolean (as string)
  • Default: true

Uploads findings in SARIF format to GitHub Code Scanning. This enables native security alerts in the Security tab, inline annotations on pull request diffs, and alert tracking workflows.

Requires the security-events: write permission. On private repositories, GitHub Advanced Security must be enabled.

See SARIF Integration for details.

upload-sarif: true

upload-artifact

  • Required: No
  • Type: Boolean (as string)
  • Default: true

Uploads the full JSON analysis report as a workflow artifact. The artifact is downloadable from the workflow run summary and is retained according to your repository’s artifact retention settings (default: 90 days).

upload-artifact: true

timeout

  • Required: No
  • Type: Number (as string)
  • Default: 1800

Maximum number of seconds to wait for the analysis to complete. The default is 1800 seconds (30 minutes). Large repositories or complex contracts may require a higher value.

If the analysis does not complete within this window, the action fails with a timeout error.

timeout: 3600

github-token

  • Required: No
  • Type: String
  • Default: ${{ github.token }}

The GitHub token used for posting PR comments, uploading SARIF results, and cloning private repositories. The default github.token is automatically provided by GitHub Actions and is sufficient for most use cases.

You only need to override this if you require cross-repository access or elevated permissions not available through the default token.

github-token: ${{ secrets.GITHUB_TOKEN }}

api-url

  • Required: No
  • Type: String
  • Default: https://api.odinscan.ai

The base URL of the Odin Scan API. Most users do not need to change this.

Outputs

The Odin Scan action exposes several outputs that you can reference in subsequent workflow steps. These are useful for conditional logic, notifications, or custom reporting.

Output Reference

OutputTypeDescription
analysis-idStringUnique identifier for the analysis run
statusStringFinal analysis status: completed or failed
total-findingsNumberTotal number of findings across all severities
critical-countNumberNumber of critical-severity findings
high-countNumberNumber of high-severity findings
medium-countNumberNumber of medium-severity findings
low-countNumberNumber of low-severity findings
report-urlStringURL to the full report on Odin Scan
sarif-fileStringLocal path to the generated SARIF file

Accessing Outputs

To use outputs, assign an id to the Odin Scan step and reference its outputs using the steps.<id>.outputs.<name> syntax:

steps:
  - uses: actions/checkout@v4

  - name: Run Odin Scan
    id: scan
    uses: odin-scan/odin-scan-action@v1
    with:
      api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

  - name: Print results
    if: always()
    run: |
      echo "Analysis ID: ${{ steps.scan.outputs.analysis-id }}"
      echo "Status: ${{ steps.scan.outputs.status }}"
      echo "Total Findings: ${{ steps.scan.outputs.total-findings }}"
      echo "Critical: ${{ steps.scan.outputs.critical-count }}"
      echo "High: ${{ steps.scan.outputs.high-count }}"
      echo "Medium: ${{ steps.scan.outputs.medium-count }}"
      echo "Low: ${{ steps.scan.outputs.low-count }}"
      echo "Report: ${{ steps.scan.outputs.report-url }}"

Use if: always() on steps that reference outputs to ensure they run even when the scan step fails due to findings exceeding the severity threshold.

Example: Conditional Notification

You can use outputs to trigger notifications only when critical findings are detected:

- name: Notify on critical findings
  if: always() && steps.scan.outputs.critical-count != '0'
  run: |
    curl -X POST "${{ secrets.SLACK_WEBHOOK }}" \
      -H 'Content-Type: application/json' \
      -d '{
        "text": "Odin Scan found ${{ steps.scan.outputs.critical-count }} critical findings in ${{ github.repository }}. Report: ${{ steps.scan.outputs.report-url }}"
      }'

Example: Custom Threshold Logic

If you need more granular control than the built-in severity-threshold input, you can use outputs to implement custom pass/fail logic:

- name: Check findings
  if: always()
  run: |
    CRITICAL=${{ steps.scan.outputs.critical-count }}
    HIGH=${{ steps.scan.outputs.high-count }}
    TOTAL=$((CRITICAL + HIGH))
    if [ "$TOTAL" -gt 5 ]; then
      echo "Too many high+ findings ($TOTAL). Failing."
      exit 1
    fi

Findings Visibility

The findings-visibility input controls how much detail the action exposes in PR comments and inline annotations. This is a security control designed primarily for public repositories, where PR comments are visible to anyone.

Why This Matters

When the action reports a vulnerability – its title, file location, and description – on a public pull request, a threat actor monitoring the repository can read those details and exploit the issue before your team applies a fix.

The findings-visibility input lets you choose the right trade-off between transparency and security for your repository.

The Three Modes

ModePR CommentInline AnnotationsBest For
fullSeverity table with finding titles, file paths, and descriptionsShownPrivate repos where all viewers are trusted
countsSeverity table only – no titles, paths, or descriptionsSuppressedPublic repos that want an aggregate signal without broadcasting specific vulnerabilities
private“Findings detected – see private report” with a linkSuppressedPublic repos with production code where even aggregate counts could be a signal to attackers

full Mode

This is the default. The PR comment includes a severity breakdown table along with the title, file location, and description of each finding. Inline annotations appear directly on the pull request diff.

Threat model: All PR viewers are trusted. There is no information asymmetry to exploit. This mode is appropriate for private repositories and internal development.

findings-visibility: full

counts Mode

The PR comment shows only a severity breakdown table – for example, “2 critical, 1 high, 3 medium” – without revealing which vulnerabilities were found or where they are located. Inline annotations are suppressed.

Threat model: An attacker monitoring the PR learns that findings exist and their severity distribution, but not what the findings are or where they live in the code. This gives your team an at-a-glance signal for the PR without exposing actionable exploit details.

findings-visibility: counts

private Mode

The PR comment shows only a neutral message such as “Findings detected – see private report” along with a link to the full report on Odin Scan (which requires authentication). Inline annotations are suppressed.

Threat model: An attacker learns only that a scan ran. Even the count of findings is hidden, which prevents inferring that a PR touches security-sensitive code. This is the most restrictive mode.

findings-visibility: private

Annotation Suppression

Inline annotations (core.error and core.warning calls in GitHub Actions) render directly on the pull request diff with the full vulnerability title, file path, and description. On a public repository, they are just as visible as the PR comment itself.

When findings-visibility is set to counts or private, the action suppresses all inline annotations so that disclosure control is consistent across both channels.

Zero-Findings Behavior

The way the action reports zero findings differs by mode:

  • full and counts: The PR comment shows “No security findings detected.”
  • private: The PR comment shows “Security analysis complete.” – a neutral message that avoids leaking even the absence of findings as a signal.

Channels Not Affected

The findings-visibility setting only controls PR comments and inline annotations. The following channels always contain full finding details, regardless of this setting:

  • SARIF / Code Scanning – Results are visible only to users with security permissions on the repository, even on public repos. See SARIF Integration.
  • Workflow Artifacts – The full JSON report requires repository write access to download.

These channels are already protected by GitHub’s own permission model, so redaction is unnecessary.

Choosing a Mode

Repository TypeRecommended ModeReason
PrivatefullAll viewers are trusted; maximum detail is helpful
Public (open source)countsTeam gets severity signal; attackers cannot identify specific vulnerabilities
Public (production code)privateMinimizes information leakage; all details require authentication

Configuration

- uses: odin-scan/odin-scan-action@v1
  with:
    api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
    findings-visibility: private

See Inputs for the full list of configuration options.

SARIF Integration

The Odin Scan action uploads findings in SARIF (Static Analysis Results Interchange Format) to GitHub Code Scanning. This provides a native security experience within GitHub, including alerts in the Security tab, inline annotations on pull request diffs, and alert management workflows.

What Is SARIF

SARIF is an OASIS standard format for the output of static analysis tools. GitHub Code Scanning accepts SARIF uploads and uses them to display security alerts alongside your code. By uploading findings in SARIF format, Odin Scan integrates directly into GitHub’s built-in security infrastructure.

Enabling SARIF Upload

SARIF upload is enabled by default. To explicitly configure it:

- uses: odin-scan/odin-scan-action@v1
  with:
    api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
    upload-sarif: true

To disable it:

upload-sarif: false

Required Permissions

The workflow must have security-events: write permission to upload SARIF results:

permissions:
  contents: read
  security-events: write

Without this permission, the SARIF upload step will fail. The action will still complete, but findings will not appear in Code Scanning.

What You Get

Security Tab Alerts

Once SARIF results are uploaded, findings appear as alerts in your repository’s Security > Code Scanning tab. Each alert includes:

  • The vulnerability title and description.
  • The severity level.
  • The file and line where the issue was detected.
  • A link to the relevant code.

Inline Annotations on Pull Requests

Findings that affect files changed in a pull request appear as inline annotations directly on the diff view. Reviewers see warnings and errors next to the relevant lines without leaving the review interface.

When findings-visibility is set to counts or private, inline annotations are suppressed to prevent exposing vulnerability details on public repositories.

Alert Tracking and Dismissal

GitHub Code Scanning provides workflows for managing alerts over time:

  • Dismiss alerts as false positives, won’t fix, or used in tests.
  • Track resolution across branches and pull requests.
  • Re-open alerts if a fix is reverted.
  • Filter and search by severity, tool, or state.

This gives your team a persistent record of security findings beyond individual workflow runs.

Private Repository Requirements

On private repositories, GitHub Code Scanning requires GitHub Advanced Security to be enabled. This is a paid GitHub feature.

If GitHub Advanced Security is not enabled on your private repository, SARIF uploads will fail with an error. In this case, you can either:

  1. Enable GitHub Advanced Security for the repository.
  2. Disable SARIF upload (upload-sarif: false) and rely on PR comments and workflow artifacts for findings.

On public repositories, Code Scanning is available at no additional cost.

Accessing the SARIF File

The action exposes the local path to the generated SARIF file as the sarif-file output. You can use this in subsequent workflow steps for custom processing:

- name: Run Odin Scan
  id: scan
  uses: odin-scan/odin-scan-action@v1
  with:
    api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

- name: Process SARIF
  if: always()
  run: |
    echo "SARIF file: ${{ steps.scan.outputs.sarif-file }}"
    cat "${{ steps.scan.outputs.sarif-file }}" | jq '.runs[0].results | length'

Relationship to Findings Visibility

The findings-visibility setting does not affect SARIF uploads. Regardless of whether visibility is set to full, counts, or private, the full details of every finding are included in the SARIF upload. SARIF results are protected by GitHub’s own permission model – only users with security permissions can view Code Scanning alerts.

See Findings Visibility for details on controlling PR comment and annotation behavior.

Examples

This page provides complete workflow files for common use cases. Copy the one that best matches your needs and adjust as necessary.

Basic: Auto-Detect Platform

The simplest configuration. The action detects whether your repository contains CosmWasm, Solana, or EVM contracts and selects the appropriate analyzer automatically.

name: Odin Scan Security Analysis
on:
  pull_request:
    branches: [main, master]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}

Notes:

  • Triggers on pull requests targeting main or master.
  • Uses all default settings: high severity threshold, SARIF upload enabled, PR comments enabled, full findings visibility.
  • Platform is detected automatically from repository contents.

Full Configuration

Every input is set explicitly. This workflow also demonstrates how to access outputs in a subsequent step.

name: Odin Scan Full Security Analysis
on:
  pull_request:
    branches: [main, master, develop]
  push:
    branches: [main]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - name: Run Odin Scan
        id: scan
        uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
          platform: auto
          severity-threshold: medium
          fail-on-findings: true
          comment-on-pr: true
          findings-visibility: full
          upload-sarif: true
          upload-artifact: true
          timeout: 1800
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Print results
        if: always()
        run: |
          echo "Analysis ID: ${{ steps.scan.outputs.analysis-id }}"
          echo "Status: ${{ steps.scan.outputs.status }}"
          echo "Total Findings: ${{ steps.scan.outputs.total-findings }}"
          echo "Critical: ${{ steps.scan.outputs.critical-count }}"
          echo "High: ${{ steps.scan.outputs.high-count }}"
          echo "Report: ${{ steps.scan.outputs.report-url }}"

Notes:

  • Triggers on pull requests targeting main, master, or develop, and also on pushes to main.
  • Sets the severity threshold to medium, so any medium-or-above finding fails the build.
  • The id: scan attribute is required to reference outputs in the “Print results” step.
  • The if: always() condition ensures the results step runs even when the scan fails due to findings.

Solidity-Specific with Path Filters

This workflow only runs when Solidity files or build configuration files change, avoiding unnecessary scans on documentation or frontend changes.

name: Odin Scan EVM Analysis
on:
  pull_request:
    paths:
      - '**.sol'
      - 'foundry.toml'
      - 'hardhat.config.*'

jobs:
  security-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
          platform: evm
          severity-threshold: high

Notes:

  • The paths filter restricts the workflow to pull requests that modify .sol files, foundry.toml, or hardhat.config.*. This saves API usage and runner minutes on PRs that do not touch contract code.
  • The platform is set explicitly to evm since this workflow is purpose-built for Solidity projects.
  • The severity threshold is high, so only high and critical findings fail the build.

Public Repository with Private Findings

For public repositories where you want to avoid exposing vulnerability details in PR comments:

name: Odin Scan Security Analysis
on:
  pull_request:
    branches: [main]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: odin-scan/odin-scan-action@v1
        with:
          api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
          findings-visibility: private

Notes:

  • Sets findings-visibility to private, so the PR comment only shows a link to the authenticated report. No vulnerability titles, file paths, descriptions, or even counts are publicly visible.
  • SARIF uploads and workflow artifacts still contain full details, protected by GitHub’s permission model.
  • See Findings Visibility for a detailed explanation of the three visibility modes.

Further Reading

  • Inputs – full reference for all configuration options.
  • Outputs – how to use scan results in subsequent workflow steps.
  • SARIF Integration – details on GitHub Code Scanning integration.
  • Findings Visibility – controlling what details appear in public channels.

Privacy

This page explains what data the Odin Scan GitHub Action accesses, how that data is used, and what controls you have over it.

Data the Action Accesses

The action accesses the following information from your GitHub workflow environment:

Repository Information

  • Repository URL (e.g., https://github.com/owner/repo)
  • Repository name
  • Branch name
  • Commit SHA

Source Code

Your repository’s source code is sent to the Odin Scan API for analysis. Only the branch and commit specified in the workflow run is accessed.

GitHub Token

If provided via the github-token input, the token is used for:

  • Posting PR comments (requires pull-requests: write permission).
  • Uploading SARIF to Code Scanning (requires security-events: write permission).
  • Cloning private repositories for analysis.

The token is never logged or stored by the action. It is automatically scoped by GitHub Actions and expires after the workflow run.

API Key

Your Odin Scan API key (odin_sk_*) authenticates requests to the Odin Scan API. It is transmitted over HTTPS and automatically masked in GitHub Actions logs via core.setSecret().

What Is Sent to the Odin Scan API

The action sends the following data to api.odinscan.ai:

  • Repository URL, name, branch, and commit SHA.
  • Your source code (for security analysis).
  • Analysis configuration (platform, severity threshold).

This data is processed according to the Odin Scan Privacy Policy.

What Is Processed Locally

The following operations occur entirely within the GitHub Actions runner and are not sent to any external service:

  • Generating SARIF reports from API results.
  • Formatting PR comments.
  • Creating workflow annotations.
  • Uploading workflow artifacts to GitHub.

Data Retention

By the Action

The action itself is stateless. It does not store or retain any data beyond the lifetime of the workflow run.

By Odin Scan

Your source code is cloned, analyzed, and deleted immediately after the scan completes. Odin Scan does not store your repository code. Only analysis results, findings, and repository metadata are retained. See Data Handling for full details.

By GitHub

  • Workflow logs (including action output) are retained according to GitHub’s retention policies.
  • SARIF uploads are stored in GitHub Code Scanning.
  • Artifacts are retained per your repository settings (default: 90 days).

Third-Party Services

The action communicates with two external services:

ServicePurposeData Shared
Odin Scan API (api.odinscan.ai)Smart contract security analysisRepository URL, source code, analysis configuration
GitHub API (via @actions/github)PR comments, SARIF upload, repository accessControlled by workflow permissions

Privacy policies:

Security Measures

  • All API communication uses HTTPS with TLS 1.2 or higher.
  • API keys are masked in logs via core.setSecret().
  • No credentials are logged or persisted by the action.
  • GitHub tokens are used only within the workflow runner environment and are never transmitted to Odin Scan.

Your Rights

Control Over Data Collection

You control what data is sent by:

  • Choosing which repositories to scan.
  • Configuring workflow triggers (e.g., only on pull requests, specific branches).
  • Providing or withholding optional inputs such as github-token.

Access and Deletion

  • Analysis results: Managed through your Odin Scan account at odinscan.ai.
  • Workflow logs: Managed through your GitHub repository settings.
  • SARIF data: Managed through GitHub Code Scanning settings.

Compliance

The Odin Scan service complies with:

  • General Data Protection Regulation (GDPR)
  • California Consumer Privacy Act (CCPA)
  • GitHub Marketplace Developer Agreement
  • GitHub Terms of Service

For details on compliance and security practices, see Security.

Contact

For privacy-related questions:

API Authentication

Odin Scan uses a layered authentication model combining JWT-based authentication for the dashboard and API keys for programmatic access. All API endpoints that access user data require authentication.

Authentication Methods

JWT Authentication (Dashboard and Frontend)

The primary authentication method uses JSON Web Tokens (JWT) issued by Clerk. When you sign in through the Odin Scan dashboard, Clerk issues a signed JWT that the frontend includes with every API request.

How it works:

  1. You authenticate via the dashboard (email/password, GitHub OAuth, or Google OAuth).
  2. Clerk issues a signed JWT containing your user claims.
  3. The frontend sends this token with every request.
  4. The API validates the token signature against Clerk’s JWKS endpoint.
Authorization: Bearer <jwt-token>

JWT tokens are short-lived and automatically refreshed by the frontend. You do not need to manage JWT tokens directly unless you are building a custom integration.

API Key Authentication (Programmatic Access)

For scripts, CI/CD pipelines, and third-party integrations, Odin Scan supports API key authentication.

API key format:

odin_sk_<random-string>

All API keys use the odin_sk_ prefix followed by a cryptographically random string.

Using an API key:

You can pass the key in either of two headers:

Authorization: Bearer odin_sk_abc123def456...
api-key: odin_sk_abc123def456...

Both methods are equivalent. Use whichever is more convenient for your tooling.

Creating API Keys

  1. Sign in to the Odin Scan dashboard.
  2. Navigate to Settings > API Keys.
  3. Click Create New Key.
  4. Give the key a descriptive name (e.g., “GitHub Actions - Production”).
  5. Copy the key immediately – it will not be displayed again.

Revoking API Keys

To revoke a key:

  1. Go to Settings > API Keys.
  2. Find the key you want to revoke.
  3. Click Revoke.

Revoked keys stop working immediately. Any requests using a revoked key receive a 401 Unauthorized response.

Authentication Errors

Status CodeMeaning
401Missing or invalid authentication token/key
403Valid authentication, but insufficient permissions for the requested resource

Example error response:

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired authentication token"
  },
  "timestamp": "2025-01-15T10:30:00Z",
  "requestId": "req-abc123"
}

Security Best Practices

  • Never commit API keys to version control. Use environment variables or a secrets manager instead.
  • Rotate keys regularly. Create a new key, update your integrations, then revoke the old one.
  • Use the minimum scope necessary. If you only need read access, do not use a key with write permissions.
  • Store keys in a secrets manager such as AWS Secrets Manager, HashiCorp Vault, or your CI/CD platform’s built-in secrets storage (e.g., GitHub Actions secrets).
  • Monitor key usage. Review audit logs periodically for unexpected activity.
  • Revoke compromised keys immediately. If a key is accidentally exposed, revoke it and create a replacement.

Session Management

Behind the scenes, the API caches validated user sessions in Redis for 15 minutes. This reduces the overhead of repeated JWT validation on frequent API calls. Sessions are automatically invalidated on logout or token expiry.

Note: Multi-factor authentication (MFA) is supported through Clerk. Enable MFA in your account settings for an additional layer of security. See the Clerk documentation for configuration details.

Next Steps

REST API Reference

This page documents all public Odin Scan API endpoints. All authenticated endpoints require a valid JWT token or API key in the Authorization header. See Authentication for details.

Base URL:

https://api.odinscan.ai/

Analysis

Endpoints for creating, monitoring, and managing security analyses.

Create Analysis

POST /api/v1/analysis

Submits a repository for security analysis.

ParameterTypeRequiredDescription
repositoryUrlstringYesFull URL of the GitHub repository
branchstringNoBranch to analyze (defaults to the repository’s default branch)
frameworkstringNoTarget framework: cosmwasm, solana, evm, or auto
analysisTypestringNoAnalysis depth: full or quick
webhookUrlstringNoURL to receive a POST notification when the analysis completes

Auth required: Yes

Example request:

curl -X POST https://api.odinscan.ai/api/v1/analysis \
  -H "Authorization: Bearer odin_sk_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "repositoryUrl": "https://github.com/username/repo",
    "branch": "main",
    "framework": "cosmwasm",
    "analysisType": "full",
    "webhookUrl": "https://optional-webhook-endpoint.com"
  }'

Example response (201 Created):

{
  "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "createdAt": "2025-01-15T10:30:00Z"
}

List Analyses

GET /api/v1/analysis

Returns a list of analyses belonging to the authenticated user.

Auth required: Yes

Example request:

curl https://api.odinscan.ai/api/v1/analysis \
  -H "Authorization: Bearer odin_sk_abc123..."

Example response (200 OK):

[
  {
    "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "repositoryUrl": "https://github.com/username/repo",
    "branch": "main",
    "framework": "cosmwasm",
    "status": "completed",
    "createdAt": "2025-01-15T10:30:00Z",
    "completedAt": "2025-01-15T10:31:15Z"
  }
]

Get Analysis Status

GET /api/v1/analysis/:id/status

Returns the current status and progress of a specific analysis.

ParameterTypeRequiredDescription
idpathYesAnalysis UUID

Auth required: Yes

Example request:

curl https://api.odinscan.ai/api/v1/analysis/a1b2c3d4-e5f6-7890-abcd-ef1234567890/status \
  -H "Authorization: Bearer odin_sk_abc123..."

Example response (200 OK):

{
  "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "running",
  "progress": 65,
  "currentStage": "ai_analysis"
}

Possible statuses: pending, running, completed, failed


Get Analysis Result

GET /api/v1/analysis/:id/result

Returns the full results of a completed analysis, including all findings and the markdown report.

ParameterTypeRequiredDescription
idpathYesAnalysis UUID

Auth required: Yes

Example request:

curl https://api.odinscan.ai/api/v1/analysis/a1b2c3d4-e5f6-7890-abcd-ef1234567890/result \
  -H "Authorization: Bearer odin_sk_abc123..."

Example response (200 OK):

{
  "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "completed",
  "repository": {
    "url": "https://github.com/username/repo",
    "branch": "main",
    "framework": "cosmwasm"
  },
  "summary": {
    "totalFindings": 12,
    "criticalFindings": 2,
    "highFindings": 3,
    "mediumFindings": 4,
    "lowFindings": 3,
    "analysisTime": 45000
  },
  "findings": [
    {
      "id": "finding-uuid",
      "title": "Unchecked Address Validation",
      "description": "The contract accepts addresses without validation...",
      "severity": "high",
      "confidence": "high",
      "category": "Input Validation",
      "location": {
        "file": "src/contract.rs",
        "lineStart": 142,
        "lineEnd": 147
      },
      "remediation": "Implement proper address validation..."
    }
  ],
  "markdownReport": "# Security Analysis Report\n..."
}

Note: The markdownReport field contains the full human-readable report. Use this for exports or display purposes.


Delete Analysis

DELETE /api/v1/analysis/:id

Permanently deletes an analysis and all associated results.

ParameterTypeRequiredDescription
idpathYesAnalysis UUID

Auth required: Yes

Example response (204 No Content): (empty body)


Retry Analysis

POST /api/v1/analysis/:id/retry

Retries a failed analysis. The original configuration (repository, branch, framework) is reused.

ParameterTypeRequiredDescription
idpathYesAnalysis UUID (must have failed status)

Auth required: Yes

Example response (200 OK):

{
  "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "retriedAt": "2025-01-15T11:00:00Z"
}

Repositories

Endpoints for managing GitHub repository connections.

List Repositories

GET /api/v1/repositories

Returns the authenticated user’s synced GitHub repositories.

Auth required: Yes

Example request:

curl https://api.odinscan.ai/api/v1/repositories \
  -H "Authorization: Bearer odin_sk_abc123..."

Example response (200 OK):

[
  {
    "id": "repo-uuid",
    "githubId": 123456789,
    "name": "my-smart-contracts",
    "fullName": "username/my-smart-contracts",
    "url": "https://github.com/username/my-smart-contracts",
    "defaultBranch": "main",
    "language": "Rust",
    "lastSyncedAt": "2025-01-15T08:00:00Z"
  }
]

Sync Repositories

POST /api/v1/repositories/sync

Performs a full synchronization of the user’s GitHub repositories. This fetches all accessible repositories from GitHub and updates the local database.

Auth required: Yes

Example request:

curl -X POST https://api.odinscan.ai/api/v1/repositories/sync \
  -H "Authorization: Bearer odin_sk_abc123..."

Example response (200 OK):

{
  "synced": 42,
  "added": 3,
  "updated": 39,
  "syncedAt": "2025-01-15T10:00:00Z"
}

Quick Sync Repositories

POST /api/v1/repositories/quick-sync

Performs an incremental sync, fetching only repositories updated since the last sync. Faster than a full sync.

Auth required: Yes


Get Repository

GET /api/v1/repositories/:id

Returns details for a specific repository.

ParameterTypeRequiredDescription
idpathYesRepository UUID

Auth required: Yes


Get Repository Statistics

GET /api/v1/repositories/stats

Returns aggregate statistics across all synced repositories.

Auth required: Yes


Subscriptions

Endpoints for managing billing and subscription plans.

List Plans

GET /api/subscriptions/plans

Returns all available subscription plans and their features.

Auth required: Yes

Example response (200 OK):

[
  {
    "id": "plan-basic",
    "name": "Basic",
    "monthlyAnalyses": 10,
    "features": ["AI scanning", "Markdown reports"]
  },
  {
    "id": "plan-pro",
    "name": "Pro",
    "monthlyAnalyses": 60,
    "features": ["Full scanning", "AI chat", "SARIF export", "Priority support"]
  }
]

Create Checkout Session

POST /api/subscriptions/checkout

Creates a checkout session for subscribing to a plan. Returns a URL to redirect the user to the payment page.

ParameterTypeRequiredDescription
planIdstringYesThe plan to subscribe to

Auth required: Yes

Example response (200 OK):

{
  "checkoutUrl": "https://polar.sh/checkout/..."
}

Get Subscription Status

GET /api/subscriptions/status

Returns the authenticated user’s current subscription status and tier.

Auth required: Yes

Example response (200 OK):

{
  "tier": "pro",
  "status": "active",
  "currentPeriodEnd": "2025-02-15T00:00:00Z",
  "monthlyAnalysesUsed": 12,
  "monthlyAnalysesLimit": 60
}

Create Customer Portal Session

POST /api/subscriptions/portal

Creates a session URL for the billing management portal where users can update payment methods, view invoices, or cancel their subscription.

Auth required: Yes

Example response (200 OK):

{
  "portalUrl": "https://polar.sh/portal/..."
}

Health

Public endpoints for monitoring API availability. These do not require authentication.

Basic Health Check

GET /health

Returns a simple status indicating the API is running.

Auth required: No

Example response (200 OK):

{
  "status": "ok"
}

Detailed Health Check

GET /health/detailed

Returns health status for the API and all dependencies (database, Redis, external services).

Auth required: No

Example response (200 OK):

{
  "status": "ok",
  "database": "connected",
  "redis": "connected",
  "uptime": 86400
}

Error Responses

All endpoints return errors in a consistent format:

{
  "error": {
    "code": "ANALYSIS_FAILED",
    "message": "Analysis failed due to compilation errors",
    "details": {
      "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "stage": "compilation"
    }
  },
  "timestamp": "2025-01-15T10:30:00Z",
  "requestId": "req-abc123"
}

Common status codes:

CodeMeaning
200Success
201Resource created
204Success, no content
400Bad request (validation error)
401Unauthorized (missing or invalid auth)
403Forbidden (insufficient permissions or subscription tier)
404Resource not found
429Rate limit exceeded (see Rate Limits)
500Internal server error
503Service unavailable

Next Steps

Rate Limits

Odin Scan enforces rate limits to ensure fair usage and maintain service reliability. Limits vary by subscription plan and endpoint.

Scan Quotas

PlanScan QuotaPeriod
Basic10 scansPer month
Pro60 scans per seatPer month

Pro scan quotas are pooled at the organization level. For example, a team with 2 Pro seats gets 120 scans per month shared across all members.

General API Requests

Standard read endpoints (listing analyses, checking status, fetching results) have higher limits to support polling workflows:

PlanLimitPeriod
Basic100 requestsPer hour
Pro1,000 requestsPer hour

Rate Limit Headers

Every API response includes rate limit information in the response headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1705312800
HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed in the current window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the rate limit window resets

Exceeding the Limit

When you exceed a rate limit, the API returns a 429 Too Many Requests response:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705316400
Retry-After: 3600
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again later."
  },
  "timestamp": "2025-01-15T10:30:00Z",
  "requestId": "req-abc123"
}

The Retry-After header indicates how many seconds to wait before making another request.

Best Practices

Poll with backoff. When checking analysis status, start with a 5-second interval and increase to 15-30 seconds as the analysis progresses. Avoid polling more frequently than once per second.

# Good: poll every 10 seconds
while true; do
  status=$(curl -s https://api.odinscan.ai/api/v1/analysis/$ID/status \
    -H "Authorization: Bearer $API_KEY" | jq -r '.status')
  if [ "$status" = "completed" ] || [ "$status" = "failed" ]; then
    break
  fi
  sleep 10
done

Use webhooks instead of polling. When creating an analysis, provide a webhookUrl to receive a notification when the analysis completes. This eliminates the need for status polling entirely.

{
  "repositoryUrl": "https://github.com/username/repo",
  "webhookUrl": "https://your-server.com/webhook/odinscan"
}

Cache results locally. Analysis results do not change after completion. Fetch the result once and store it locally rather than requesting it repeatedly.

Monitor your usage. Check the X-RateLimit-Remaining header in responses to track how close you are to the limit. If you are consistently approaching the limit, consider upgrading your plan.

Batch operations where possible. Instead of syncing repositories one by one, use the full sync endpoint (POST /api/v1/repositories/sync) which handles all repositories in a single request.

Upgrading Your Plan

If you consistently hit rate limits, consider upgrading your subscription. See Subscription Plans.

Next Steps

Dashboard Overview

The Odin Scan dashboard is the central interface for managing security analyses, reviewing findings, and configuring your account. This page walks through the main sections and how to navigate them.

Main Dashboard View

When you sign in, the dashboard displays a summary of your security posture across all repositories:

  • Total Scans – the number of analyses you have run.
  • Findings by Severity – a breakdown of findings across Critical, High, Medium, Low, and Informational severity levels.
  • Recent Activity – a timeline of your most recent analyses and their outcomes.

The main view also shows a list of your synced repositories with quick-access links to trigger new scans or view past results.

The dashboard sidebar provides access to all major sections:

SectionDescription
DashboardSummary view with key metrics and recent activity
ReportsList of all analysis reports with filtering options
RepositoriesManage synced GitHub repositories
SettingsAccount settings, API keys, and preferences
Audit LogsActivity log for security and compliance tracking (under Reports)

Key Metrics

The dashboard header displays aggregate metrics that update after each completed analysis:

  • Total Scans – cumulative number of analyses across all repositories.
  • Critical / High Findings – count of unresolved critical and high-severity findings, prominently displayed for immediate attention.
  • Recent Scans – the last 5-10 analyses with status indicators (completed, failed, pending).

Quick Actions

From the main dashboard, you can:

  • Start a new analysis – select a repository and branch, then launch a scan.
  • Sync repositories – refresh the list of repositories from GitHub.
  • View a report – click any completed analysis to see the full findings.

Subscription Status

Your current subscription tier and usage are visible on the dashboard. This includes:

  • Current plan (Basic or Pro).
  • Number of analyses used in the current billing period.
  • Number of analyses remaining.

For details on plans and billing, see the Subscriptions section.

Next Steps

  • Reports – understand analysis reports and findings
  • Repositories – manage your GitHub repositories
  • Filters – filter reports by status, date, and severity

Reports

Reports are the primary output of Odin Scan analyses. Each report contains a detailed breakdown of security findings discovered in your smart contract code.

Report Contents

A completed analysis report includes:

  • Summary – total number of findings grouped by severity level.
  • Findings list – individual security issues discovered during the scan.
  • Markdown report – a formatted, human-readable version of the full report.

Findings

Each finding in a report includes the following details:

FieldDescription
TitleShort description of the security issue
DescriptionDetailed explanation of the vulnerability and its impact
SeverityCritical, High, Medium, Low, or Informational
ConfidenceHow certain the analyzer is about the finding: High, Medium, or Low
CategoryClassification of the issue (e.g., Input Validation, Access Control, Reentrancy)
FileSource file where the issue was found
Line numbersStart and end line of the affected code
RemediationSuggested fix or mitigation strategy

Some findings also include:

  • Proof of Concept (PoC) – example code or steps demonstrating how the vulnerability could be exploited.
  • References – links to relevant security advisories, documentation, or standards.

Severity Levels

SeverityDescription
CriticalImmediate risk of fund loss or contract takeover. Requires urgent remediation.
HighSignificant security risk that could lead to loss of funds or unauthorized access under certain conditions.
MediumModerate risk that could cause unintended behavior or partial loss of functionality.
LowMinor issue with limited security impact. Should be addressed but is not urgent.
InformationalBest practice suggestion or code quality observation. No direct security impact.

Report Statuses

Each analysis (and its associated report) has a status indicating where it is in the lifecycle:

StatusMeaning
PendingThe analysis is queued and waiting to start
RunningThe analysis is currently in progress
CompletedThe analysis finished successfully and results are available
FailedThe analysis encountered an error (e.g., compilation failure)

Failed analyses can be retried from the report view or via the API.

Viewing a Report

  1. Navigate to Reports from the sidebar.
  2. Click on any completed analysis to open the full report.
  3. The report view shows the summary at the top, followed by individual findings.
  4. Click on a finding to expand its details, including the affected code location and remediation guidance.

Markdown Report View

Each report includes a rendered Markdown view that presents the findings in a readable document format. This is the same content available through the markdownReport field in the API response.

The Markdown view is useful for:

  • Sharing reports with team members who do not have dashboard access.
  • Copying findings into issue trackers or documentation.
  • Quick review without navigating individual findings.

Next Steps

  • Filters – narrow down reports by status, date, or severity
  • Exports – download reports in JSON, Markdown, or SARIF format
  • Audit Logs – track who viewed or acted on reports

Report Filters

The Reports page includes a filtering system that lets you narrow down the list of analysis reports. Filters help you focus on the reports that matter most, whether you are triaging critical findings or reviewing historical trends.

Available Filters

Status Filter

Filter reports by their analysis status:

  • Completed – analyses that finished successfully with results available.
  • Failed – analyses that encountered errors during processing.
  • Pending – analyses that are queued or currently running.

You can select multiple statuses at once. For example, selecting both “Completed” and “Failed” shows all finished analyses regardless of outcome.

Date Range Filter

Narrow reports to a specific time period by setting a start date, end date, or both:

  • Start date – only show reports created on or after this date.
  • End date – only show reports created on or before this date.

Date range filtering is useful for:

  • Reviewing analyses from a specific sprint or release cycle.
  • Tracking remediation progress over a defined period.
  • Generating compliance reports for a particular timeframe.

Severity Filter

Filter reports based on the severity of findings they contain:

SeverityShows reports containing at least one finding at this level
CriticalReports with critical-severity findings
HighReports with high-severity findings
MediumReports with medium-severity findings
LowReports with low-severity findings
InformationalReports with informational findings only

You can select multiple severity levels simultaneously. For example, selecting “Critical” and “High” shows all reports that contain at least one critical or high-severity finding.

Combining Filters

All filters can be combined to create precise views. For example:

  • Status: Completed + Severity: Critical, High – show only completed reports with critical or high findings. Useful for triage.
  • Status: Completed + Date range: last 30 days – show recently completed reports for a progress review.
  • Status: Failed + Date range: this week – identify recent analysis failures that may need retry.

Filters are applied with AND logic: a report must match all active filters to appear in the results.

Filter Persistence

Filters persist during your current session. If you navigate away from the Reports page and return, your filter selections remain active. Filters reset when you sign out or close the browser.

Clearing Filters

To remove all active filters and return to the full report list, click the Clear Filters button at the top of the filter panel.

Next Steps

  • Reports – understanding report contents and findings
  • Exports – export filtered results
  • Audit Logs – track report activity

Repository Management

Odin Scan integrates with GitHub to manage the repositories available for analysis. This page covers how to add, sync, and manage repositories from the dashboard.

Adding Repositories

Odin Scan accesses your repositories through GitHub. To make repositories available for scanning:

  1. Navigate to Repositories from the sidebar.
  2. Click Sync Repositories.
  3. Odin Scan fetches your accessible GitHub repositories and adds them to the dashboard.

Note: You must have a GitHub token configured. Go to Settings and connect your GitHub account or provide a personal access token with repository read access.

Repository List View

The Repositories page displays all synced repositories in a list with the following information:

ColumnDescription
NameRepository name and owner (e.g., username/my-contracts)
LanguagePrimary programming language detected by GitHub
Default BranchThe repository’s default branch (e.g., main)
Last SyncedWhen the repository metadata was last updated

Click on any repository to view its details and scan history.

Repository Details

The detail view for a repository shows:

  • Repository metadata – name, URL, default branch, and language.
  • Scan history – a chronological list of all analyses run on this repository, with status and summary for each.
  • Quick actions – start a new analysis directly from the repository detail page.

Syncing Repositories

Odin Scan provides two sync modes:

Full Sync

POST /api/v1/repositories/sync

A full sync fetches all accessible repositories from GitHub and updates the local database. Use this when:

  • You have added new repositories to your GitHub account.
  • You want to ensure the dashboard reflects your complete repository list.
  • Repository metadata (name, default branch) has changed.

Quick Sync

POST /api/v1/repositories/quick-sync

A quick sync performs an incremental update, fetching only repositories that have changed since the last sync. This is faster than a full sync and is suitable for regular use.

Note: Repository sync is rate-limited to 10 requests per hour across all subscription tiers. See Rate Limits for details.

Repository Statistics

The Stats view provides aggregate data across all synced repositories:

  • Total number of repositories synced.
  • Number of repositories that have been scanned.
  • Breakdown of scan results across repositories.

Access stats via the Repositories page or the API (GET /api/v1/repositories/stats).

Troubleshooting

Repositories not appearing after sync:

  • Verify your GitHub token has the required permissions (repo scope for private repositories, or public_repo for public only).
  • Check that the repository is accessible with your GitHub account.
  • Try a full sync instead of a quick sync.

Stale repository data:

  • Repository metadata (name, branches) is updated during sync. Run a new sync to refresh.

Next Steps

Audit Logs

Audit logs provide a record of significant actions taken within Odin Scan. They support security monitoring, compliance tracking, and team accountability by recording who did what, when, and on which resources.

Accessing Audit Logs

Audit logs are accessible from the dashboard sidebar under Reports > Audit Logs.

What Gets Logged

The following events are recorded in the audit log:

EventDescription
Scan triggeredA user initiated a security analysis on a repository
Report viewedA user opened and viewed an analysis report
Settings changedA user modified account or project settings
Finding resolvedA user marked a finding as resolved
Finding suppressedA user suppressed a finding (marked as accepted risk or false positive)
Repository syncedA user triggered a repository synchronization
API key createdA user generated a new API key
API key revokedA user revoked an existing API key

Log Entry Details

Each audit log entry contains:

FieldDescription
DateTimestamp of when the action occurred
UserThe user who performed the action
ActionThe type of event (e.g., “Scan triggered”, “Finding resolved”)
RepositoryThe repository associated with the action (if applicable)
BranchThe branch involved (if applicable)
DetailsAdditional context about the action

Example Log Entries

2025-01-15 10:30:00  alice@company.com  Scan triggered     username/contracts  main
2025-01-15 10:45:00  bob@company.com    Report viewed      username/contracts  main
2025-01-15 11:00:00  alice@company.com  Finding resolved   username/contracts  main
2025-01-15 14:20:00  alice@company.com  Settings changed   --                  --

Filtering and Searching

The audit log view supports filtering to help you find specific events:

  • Filter by action type – show only certain event types (e.g., only “Scan triggered” events).
  • Filter by user – view actions performed by a specific team member.
  • Filter by repository – narrow logs to a specific repository.
  • Filter by date range – view events within a specific time period.
  • Search – free-text search across log entries.

Retention

Audit log entries are retained according to your subscription tier. Pro plans include extended retention.

Use Cases

Security monitoring – Review logs for unexpected actions, such as scans triggered by unfamiliar users or API keys created outside of normal workflows.

Compliance reporting – Generate audit trails showing when repositories were scanned, who reviewed the results, and how findings were handled.

Team accountability – Track which team members are actively reviewing and resolving findings.

Incident investigation – Trace the sequence of actions leading up to a specific event or configuration change.

Next Steps

Exports

Odin Scan supports exporting analysis reports in multiple formats for integration with external tools, team sharing, and compliance documentation.

Supported Formats

FormatBest For
JSONProgrammatic access, custom integrations, data processing
MarkdownHuman-readable reports, sharing with stakeholders, documentation
SARIFGitHub Code Scanning, IDE integrations, SARIF-compatible security tools

Exporting from the Dashboard

  1. Navigate to Reports and open a completed analysis.
  2. Click the Export button at the top of the report view.
  3. Select the desired format (JSON, Markdown, or SARIF).
  4. The file downloads to your browser.

Export Formats

JSON

The JSON export contains the full structured analysis result, identical to the response from the GET /api/v1/analysis/:id/result endpoint.

{
  "analysisId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "completed",
  "repository": {
    "url": "https://github.com/username/repo",
    "branch": "main",
    "framework": "cosmwasm"
  },
  "summary": {
    "totalFindings": 12,
    "criticalFindings": 2,
    "highFindings": 3,
    "mediumFindings": 4,
    "lowFindings": 3,
    "analysisTime": 45000
  },
  "findings": [
    {
      "id": "finding-uuid",
      "title": "Unchecked Address Validation",
      "severity": "high",
      "confidence": "high",
      "category": "Input Validation",
      "location": {
        "file": "src/contract.rs",
        "lineStart": 142,
        "lineEnd": 147
      },
      "remediation": "Implement proper address validation..."
    }
  ]
}

Use JSON exports for:

  • Feeding results into custom dashboards or reporting tools.
  • Automated processing in CI/CD pipelines.
  • Archiving results in a structured, machine-readable format.

Markdown

The Markdown export produces a formatted, human-readable report. This is the same content available in the markdownReport field of the API response.

# Security Analysis Report

**Repository:** username/repo
**Branch:** main
**Framework:** CosmWasm
**Date:** 2025-01-15

## Summary

| Severity | Count |
|----------|-------|
| Critical | 2     |
| High     | 3     |
| Medium   | 4     |
| Low      | 3     |

## Findings

### [HIGH] Unchecked Address Validation

**File:** src/contract.rs (lines 142-147)
**Category:** Input Validation

The contract accepts addresses without validation...

**Remediation:** Implement proper address validation...

Use Markdown exports for:

  • Sharing results with team members or stakeholders via email or chat.
  • Including in pull request descriptions or issue trackers.
  • Generating printable reports.

SARIF

The SARIF (Static Analysis Results Interchange Format) export produces a standard format recognized by GitHub Code Scanning, Visual Studio Code, and other SARIF-compatible tools.

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "Odin Scan",
          "version": "1.0.0"
        }
      },
      "results": [
        {
          "ruleId": "input-validation/unchecked-address",
          "level": "error",
          "message": {
            "text": "Unchecked Address Validation"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "src/contract.rs"
                },
                "region": {
                  "startLine": 142,
                  "endLine": 147
                }
              }
            }
          ]
        }
      ]
    }
  ]
}

Use SARIF exports for:

  • Uploading to GitHub Code Scanning to surface findings directly in pull requests.
  • Importing into IDE extensions that support SARIF (e.g., the SARIF Viewer for VS Code).
  • Aggregating results from multiple security tools in a unified format.

API-Based Exports

You can retrieve analysis results programmatically via the API, which is useful for automation and CI/CD workflows:

# Fetch the full result (JSON format)
curl https://api.odinscan.ai/api/v1/analysis/ANALYSIS_ID/result \
  -H "Authorization: Bearer odin_sk_abc123..." \
  -o report.json

The API response includes all fields needed to construct any export format. The markdownReport field contains the pre-rendered Markdown version.

See the REST API Reference for full endpoint documentation.

Next Steps

Plans and Pricing

Odin Scan offers a simple two-tier pricing model: Basic and Pro. Whether you are an individual developer or a security team, the same Pro plan scales with your needs.

Plans

Basic

The Basic plan gives you access to Odin Scan’s core scanning capabilities.

  • Price: $99/month (monthly billing)
  • Yearly option: $79/month (billed annually)
  • Users: 1
  • Scan quota: 10 scans per month
  • Platforms: CosmWasm, Solana, EVM

Pro

The Pro plan increases your scan quota and unlocks team features with multi-model AI analysis.

  • Users: 1 seat minimum, no maximum
  • Scan quota: 60 scans per seat per month (pooled across team)
  • Organization support: Included with all Pro subscriptions

Pro Pricing Tiers

Volume discounts apply automatically based on seat count:

SeatsPrice per Seat (monthly)
1–5$499/month
6–10$399/month
11+$299/month

Pricing Examples

SeatsPer SeatMonthly Total
1$499$499
5$499$2,495
6$399$2,394
10$399$3,990
15$299$4,485

Scan Quota Pooling

Pro scan quotas are pooled at the organization level. Every Pro seat adds 60 scans to the shared pool for the billing period.

SeatsTotal Scans per Month
160
2120
5300
10600

All organization members draw from the same pool. Any member with the Member role or above can initiate scans.

Feature Comparison

FeatureBasicPro
Supported platformsAllAll
AI analysisSingle modelMulti-model (bleeding-edge)
Static analysisYesYes
Verification pipelineYesYes
GitHub Action integrationNoYes
SARIF / Code ScanningNoYes
PR comments and annotationsNoYes
Scan quota10/month60/seat/month (pooled)
Seats11+
Organization and teamsNoYes
Dashboard accessBasicFull
Priority supportNoYes

Upgrading

To upgrade from Basic to Pro, navigate to Settings > Subscription in the Odin Scan dashboard and select the Pro plan. Upgrading unlocks the GitHub Action, SARIF integration, multi-model AI analysis, and increases your scan quota to 60 per seat per month. See Checkout for the full purchase flow.

Cancellation

You can cancel your Pro subscription at any time through the Subscription Portal. Access continues until the end of your current billing period.

Checkout

Odin Scan uses Polar.sh for payment processing. This page describes the steps to purchase a Pro subscription.

Purchase Flow

  1. Select plan – Navigate to Settings > Subscription in the Odin Scan dashboard, or visit the pricing page directly.
  2. Choose seats – Select the number of seats your team needs. A single seat is sufficient for individual use.
  3. Review pricing – Volume discounts apply automatically based on seat count (see Plans and Pricing).
  4. Choose billing cycle – Select monthly or yearly billing.
  5. Enter payment details – Provide your payment information through the Polar.sh checkout form.
  6. Confirm purchase – Review the total and complete the transaction.

Accepted Payment Methods

  • Credit cards (Visa, Mastercard, American Express)
  • Debit cards

After Payment

  • Immediate access: Your Pro subscription activates instantly. There is no provisioning delay.
  • Confirmation email: Polar.sh sends a receipt to the email address associated with your account.
  • Invoice: Invoices are available in the Subscription Portal and are generated automatically for each billing cycle.

Organization Creation

When you purchase a Pro subscription, an organization is created automatically. The purchasing user becomes the organization Owner. You can then invite team members by adding seats through the Teams settings.

Billing Questions

For billing-related inquiries, visit the Subscription Portal or contact support@odinscan.ai.

Seat Management

A seat represents one active user on your Odin Scan Pro subscription. This page explains how seats work and how to manage them.

What Is a Seat?

Each seat corresponds to one user who can authenticate with Odin Scan, run scans, and access the dashboard. Every member of your organization occupies one seat. Each seat also contributes 60 scans per month to your organization’s shared pool.

Adding Seats

To add seats to your subscription:

  1. Navigate to Settings > Subscription > Manage in the Odin Scan dashboard.
  2. Update the seat quantity through the Polar.sh subscription portal.
  3. The additional seats become available immediately.
  4. Your next invoice reflects the updated quantity, prorated for the remainder of the current billing cycle.

Note: Volume discounts are applied automatically based on your total seat count. See Plans and Pricing for the tier breakdown.

Removing Seats

To reduce your seat count:

  1. Navigate to Settings > Subscription > Manage.
  2. Decrease the seat quantity through the Polar.sh portal.
  3. The change takes effect at the start of your next billing cycle. Current members retain access until then.
  4. Before reducing seats, ensure your active member count does not exceed the new seat limit. Remove members first if necessary.

Volume Pricing

The per-seat price decreases as your team grows:

SeatsPer Seat (monthly)
1–5$499
6–10$399
11+$299

The pricing tier applies to all seats on the subscription based on the total count.

Viewing Seat Utilization

Organization Owners and Admins can view current seat usage in Settings > Organization > Members. This page shows:

  • Total seats purchased
  • Seats currently occupied
  • Remaining available seats

Seat Limits

You cannot invite new members when all seats are occupied. To add more members, first increase your seat count through the subscription portal, then send the invitation.

Subscription Portal

The subscription portal provides self-service management for your Odin Scan billing and payment details. It is powered by Polar.sh.

Accessing the Portal

  1. Sign in to the Odin Scan dashboard.
  2. Navigate to Settings > Subscription.
  3. Click Manage Subscription.

This opens the Polar.sh customer portal where you can manage all aspects of your subscription.

Available Actions

Update Payment Method

Change the credit or debit card on file for your subscription. The new payment method is used for all future charges.

View Invoices

Browse and download invoices for all past billing cycles. Each invoice includes a breakdown of seats, discounts applied, and the total charged.

Change Plan

  • Switch billing cycle: Move between monthly and yearly billing. Yearly billing saves 20% compared to monthly.
  • Adjust seat count: Increase or decrease the number of seats. See Seat Management for details on how changes are applied.

Cancel Subscription

Cancelling your subscription stops future charges. Your Pro access and all team member access continues until the end of the current billing period. After that:

  • Your account reverts to the Basic plan.
  • Organization members lose access to the organization.
  • Scan quotas revert to Basic plan limits (10 scans per month, single user).
  • Existing analysis results and reports remain accessible.

Note: Cancellation does not delete your account or historical data. You can resubscribe at any time to restore Pro access.

Billing Cycle

  • Monthly subscriptions are billed on the same date each month (the date of your original purchase).
  • Yearly subscriptions are billed on the anniversary of your original purchase date.

Seat changes mid-cycle are prorated on your next invoice.

Support

If you encounter issues with billing or the subscription portal, contact support@odinscan.ai.

Creating an Organization

An organization is a shared workspace where team members collaborate on smart contract security scanning. Organizations provide centralized billing, shared scan quotas, and role-based access control.

Prerequisites

To create an organization, you need a Pro subscription. Any Pro user can create an organization, even with a single seat. See Plans and Pricing for details.

How Organizations Are Created

When you purchase a Pro subscription, an organization is created automatically during checkout. The purchasing user becomes the Owner of the organization. A single-seat Pro subscription creates a one-person organization that you can grow later by adding seats.

Organization Settings

After creation, configure your organization in Settings > Organization:

  • Name: A display name for your organization (e.g., “Acme Security Team”).
  • Slug: A URL-friendly identifier used in API calls and dashboard URLs (e.g., acme-security). This is auto-generated from your organization name and can be customized.

What Organizations Provide

CapabilityDescription
BillingCentralized billing with a single invoice
Users1 or more members depending on seat count
Scan quotasPooled across all members (60 per seat/month)
RolesOwner, Admin, Member, Viewer
ManagementInvite and remove members, manage roles

Next Steps

Roles and Permissions

Odin Scan organizations use role-based access control to manage what each team member can do. Every organization member is assigned exactly one role.

Roles

Owner

The Owner has full control over the organization, including billing, membership, and all scanning capabilities. The user who creates the organization (by purchasing the subscription) is automatically assigned this role.

There must always be at least one Owner in an organization.

Admin

Admins can manage team membership and perform all scanning and reporting operations. They cannot access billing settings or delete the organization.

Member

Members can run scans, view reports, and manage their own account settings. They cannot invite or remove other users.

Viewer

Viewers have read-only access to scan reports and the dashboard. They cannot initiate scans or modify any settings.

Permission Matrix

PermissionOwnerAdminMemberViewer
Run scansYesYesYesNo
View reports and findingsYesYesYesYes
Manage own account settingsYesYesYesYes
Invite membersYesYesNoNo
Remove membersYesYesNoNo
Change member rolesYesYesNoNo
Access organization settingsYesYesNoNo
Manage billing and subscriptionYesNoNoNo
Delete organizationYesNoNoNo
Transfer ownershipYesNoNoNo

Assigning Roles

When inviting a new member, the inviter selects the role for the invited user. The default role for new invitations is Member.

Changing Roles

Owners and Admins can change a member’s role at any time:

  1. Navigate to Settings > Organization > Members.
  2. Find the member in the list.
  3. Select a new role from the dropdown.
  4. The change takes effect immediately.

Note: Only Owners can promote a member to Owner or demote another Owner. An organization must always have at least one Owner.

Inviting Members

Organization Owners and Admins can invite new members to join the team. This page covers the invitation process and management of pending invites.

Sending an Invitation

  1. Navigate to Settings > Organization > Members.
  2. Click Invite Member.
  3. Enter the invitee’s email address.
  4. Select a role for the new member (default: Member).
  5. Click Send Invite.

Before the invitation is sent, Odin Scan checks that your organization has available seats. If all seats are occupied, you must first add seats to the subscription.

What the Invitee Receives

The invited user receives an email with a link to join the organization. When they click the link:

  • Existing Odin Scan users: The invitation links their existing account to the organization. They gain access immediately.
  • New users: They are prompted to create an Odin Scan account. After registration, they are automatically added to the organization.

Managing Pending Invitations

Pending invitations are visible in Settings > Organization > Members under the Pending tab. From there, Owners and Admins can:

  • View the email address and role of each pending invite.
  • Resend the invitation email if the original was missed.
  • Revoke a pending invitation to free up the reserved seat.

Pending invitations expire after 7 days. Expired invitations can be resent.

Seat Capacity

Each pending invitation reserves one seat. The organization must have enough available seats to cover both active members and pending invitations. If you need to invite more members than your current seat count allows, increase your seats through the Subscription Portal first.

Removing Members

Owners and Admins can remove existing members from the organization:

  1. Navigate to Settings > Organization > Members.
  2. Find the member to remove.
  3. Click Remove and confirm.

The removed member loses access to the organization immediately. Their seat becomes available for a new invitation. The seat reduction does not affect your subscription – you continue to pay for the purchased seat count until you adjust it.

Scan Quotas

Scan quotas determine how many security analyses your account or organization can run within a billing period. Quotas vary by plan.

Basic Plan

  • 10 scans per month per user.
  • Quotas are per-user and do not pool across accounts.
  • The quota resets at the start of each billing period.

Pro Plan

  • 60 scans per seat per month, pooled at the organization level.
  • Every Pro seat adds 60 scans to the shared pool (e.g., 2 seats = 120 scans/month).
  • All organization members draw from the same pooled allocation.
  • Any member with the Member role or above can initiate scans that count against the shared pool.
  • Viewers cannot initiate scans and do not consume quota.

Tracking Usage

Organization Owners and Admins can view scan usage in the Odin Scan dashboard:

  1. Navigate to Dashboard > Overview for aggregate scan counts.
  2. Navigate to Settings > Organization for a per-member breakdown of scan activity.

The dashboard shows:

  • Total scans run in the current billing period.
  • Scans per member (for visibility into team activity).
  • Historical usage trends.

Exceeding Quotas

When you reach your plan’s scan limit, additional scan requests are rejected until the next billing period. The API returns a 429 Too Many Requests response with details on when you can scan again.

To increase your scan quota, upgrade to the Pro plan or add more seats to your existing Pro subscription.

Data Handling

This page describes what data Odin Scan accesses, how it is processed, and how long it is retained.

Data Accessed

When you run a scan, Odin Scan accesses the following information:

DataSourcePurpose
Repository URLGitHub workflow environmentIdentify the repository under analysis
Source codeCloned from your repositorySecurity analysis by AI and static analyzers. Deleted immediately after analysis.
Branch nameGitHub workflow environmentScope the analysis to the correct branch
Commit SHAGitHub workflow environmentPin the analysis to a specific commit
Analysis configurationAction inputs or API parametersConfigure platform, severity threshold, and output options

Data Sent to the API

The Odin Scan GitHub Action sends the following to the Odin Scan API (api.odinscan.ai) over HTTPS:

  • Repository URL, name, branch, and commit SHA
  • Source code (for analysis only – cloned, analyzed, and deleted immediately after the scan completes)
  • Analysis configuration (platform, severity threshold)
  • Your API key (for authentication)

Important: GitHub tokens provided via the github-token input are never sent to the Odin Scan API. They are used only within the GitHub Actions runner for posting PR comments and uploading SARIF results.

Data Processed Locally

The following operations occur entirely on the GitHub Actions runner and are never transmitted to Odin Scan:

  • SARIF report generation from API results
  • PR comment formatting
  • Workflow annotation creation
  • Artifact packaging and upload

No data from these local operations is sent to third parties.

Source Code Handling

Odin Scan does not store your source code. When a scan runs:

  1. Your repository is cloned to a temporary environment.
  2. The code is analyzed by AI models and static analysis.
  3. The cloned repository is deleted immediately after the analysis completes.

Only the analysis results (findings, severity, code locations, remediation guidance) are retained – never the source code itself.

Data Retention

Analysis results, findings, and repository metadata are stored for as long as your account is active. Historical scan results remain accessible in the Odin Scan dashboard.

Data Deletion

You can request deletion of your analysis data at any time:

  • Self-service: Navigate to Settings > Account > Data Management in the Odin Scan dashboard.
  • Support: Contact support@odinscan.ai for bulk deletion requests or account-level data removal.

Deletion requests are processed in accordance with GDPR and CCPA requirements. See Compliance for details.

Credentials

Odin Scan does not store your GitHub credentials or tokens. API keys are:

  • Transmitted over HTTPS only
  • Stored encrypted at rest using AES-256-GCM (see Encryption)
  • Automatically masked in GitHub Actions logs

The GitHub Action itself is stateless – it retains no data between workflow runs.

Encryption

Odin Scan employs encryption at every layer to protect your data in transit and at rest.

Data in Transit

All communication between clients and the Odin Scan API uses TLS 1.2 or higher. This applies to:

  • API requests from the GitHub Action to api.odinscan.ai
  • Dashboard access via odinscan.ai
  • Webhook deliveries from Polar.sh to the Odin Scan API

Plaintext HTTP connections are not accepted. All HTTP requests are redirected to HTTPS.

Data at Rest

Sensitive data stored by Odin Scan is encrypted using AES-256-GCM. This includes:

  • API keys
  • GitHub tokens (if temporarily held during analysis)
  • Subscription and billing identifiers

Non-sensitive data such as analysis results and finding metadata is stored in PostgreSQL and protected by database-level access controls and TLS-encrypted connections.

Webhook Verification

Incoming webhooks from Polar.sh (for subscription events) are verified using HMAC-SHA256 signature validation. Each webhook request includes a signature header that is checked against a shared secret before the payload is processed. Requests with invalid or missing signatures are rejected.

Database Connections

  • PostgreSQL: All connections use TLS encryption. The database is not accessible from the public internet.
  • Redis: Used for session caching and rate limiting. Connections are authenticated and encrypted.

Logging

Sensitive data is excluded from application logs and error responses. API keys, tokens, and encrypted fields are never logged in plaintext. The GitHub Action uses core.setSecret() to mask API keys in workflow logs.

Compliance

Odin Scan is committed to protecting user data and operating in compliance with applicable privacy regulations and platform agreements.

GDPR

Odin Scan complies with the General Data Protection Regulation (GDPR) for users in the European Economic Area:

  • Data minimization: Odin Scan collects only the data necessary to perform security analysis. Source code is processed for analysis purposes and retained according to your subscription plan.
  • Right to access: You can request a copy of all personal data Odin Scan holds about you through Settings > Account > Data Management or by contacting support.
  • Right to deletion: You can request deletion of your account and all associated data. Deletion requests are processed within 30 days.
  • Data portability: Analysis results and findings can be exported in standard formats (JSON, SARIF) from the dashboard.
  • Legal basis: Data processing is performed under the legal basis of contract performance (providing the scanning service you subscribed to).

CCPA

Odin Scan complies with the California Consumer Privacy Act (CCPA) for California residents:

  • Right to know: You can request disclosure of the categories and specific pieces of personal information collected about you.
  • Right to delete: You can request deletion of your personal information, subject to applicable exceptions.
  • Right to opt-out: Odin Scan does not sell personal information to third parties.
  • Non-discrimination: Exercising your CCPA rights does not result in different pricing or service levels.

GitHub Marketplace

Odin Scan complies with the GitHub Marketplace Developer Agreement, including:

  • Accurate representation of the application’s functionality
  • Transparent data handling practices
  • Adherence to GitHub’s API terms of service
  • Proper use of GitHub tokens and permissions

Data Processing

Odin Scan processes source code solely for the purpose of security analysis. Code is not used for:

  • Training AI models
  • Sharing with third parties beyond the AI model providers required to perform the scan
  • Marketing or advertising purposes

Contact

For compliance inquiries, data access requests, or privacy concerns:

  • Email: support@odinscan.ai
  • Response time: Requests are acknowledged within 5 business days and fulfilled within 30 days.

Troubleshooting

This page covers common issues when using Odin Scan and the GitHub Action, along with solutions.

“Invalid API key”

Cause: The ODIN_SCAN_API_KEY secret is missing, empty, or incorrect.

Solution:

  1. Verify the secret is set in your repository: Settings > Secrets and variables > Actions.
  2. Confirm the key starts with odin_sk_.
  3. Regenerate the key from Odin Scan Settings > API Keys if necessary.
  4. Ensure the secret name in your workflow matches exactly: ${{ secrets.ODIN_SCAN_API_KEY }}.

“Analysis timed out”

Cause: The analysis took longer than the configured timeout (default: 1800 seconds / 30 minutes).

Solution:

  • Increase the timeout input in your workflow:
    - uses: odin-scan/odin-scan-action@v1
      with:
        api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
        timeout: 3600
    
  • Large repositories with many contract files take longer to analyze. Consider scanning specific subdirectories or branches with fewer files.

“Failed to upload SARIF”

Cause: The workflow lacks the required permission, or GitHub Advanced Security is not enabled.

Solution:

  1. Ensure your workflow includes the security-events: write permission:
    permissions:
      security-events: write
    
  2. On private repositories, GitHub Code Scanning requires GitHub Advanced Security to be enabled. This is not required for public repositories.

“Failed to post PR comment”

Cause: The workflow is missing the PR comment permission or is not running on a pull request event.

Solution:

  1. Ensure the workflow includes the pull-requests: write permission:
    permissions:
      pull-requests: write
    
  2. Confirm the workflow is triggered by a pull_request event. PR comments cannot be posted on push events.

Analysis Fails Immediately

Cause: The repository does not contain recognized smart contract files.

Solution: Verify your repository includes supported contract files:

  • EVM: .sol files with a Foundry (foundry.toml) or Hardhat (hardhat.config.js/hardhat.config.ts) configuration.
  • CosmWasm: Rust files with cosmwasm-std as a dependency in Cargo.toml.
  • Solana: Rust files with Anchor framework or native Solana program structure.

If your contracts are in a subdirectory, ensure the checkout step clones the full repository.

Build Fails but No Findings

Cause: The severity-threshold is set to a level that triggers failure even when no findings meet that threshold, or the fail-on-findings input is misconfigured.

Solution:

  • Review the severity-threshold input. The default is high, meaning the workflow fails if any finding is High or Critical severity.
  • Set fail-on-findings: false to prevent the workflow from failing regardless of findings:
    - uses: odin-scan/odin-scan-action@v1
      with:
        api-key: ${{ secrets.ODIN_SCAN_API_KEY }}
        fail-on-findings: false
    

SARIF Not Appearing in Security Tab

Cause: Permissions are insufficient, or GitHub Advanced Security is not enabled for private repositories.

Solution:

  1. Confirm the workflow has security-events: write permission.
  2. For private repositories, enable GitHub Advanced Security in Settings > Security > Code security and analysis.
  3. After a successful SARIF upload, results may take a few minutes to appear in the Security > Code scanning alerts tab.
  4. Check the workflow logs for the SARIF upload step – a 202 Accepted response confirms successful upload.

Rate Limited (429 Too Many Requests)

Cause: You exceeded the scan quota for your plan.

Solution:

  • Basic plan: The limit is 10 scans per month. Wait for the next billing period or upgrade to Pro.
  • Pro plan: Pro subscriptions include 60 scans per seat per month (pooled across your team). If you need more, add seats to your subscription or contact support@odinscan.ai.

Getting Help

If your issue is not listed here:

FAQ

Frequently asked questions about Odin Scan.


What platforms does Odin Scan support?

Odin Scan supports three blockchain platforms:

  • CosmWasm – Rust-based smart contracts on Cosmos SDK chains (Osmosis, Neutron, Terra, etc.)
  • Solana (SVM) – Rust-based programs using Anchor or native Solana program structure
  • EVM – Solidity and Vyper contracts on Ethereum, Arbitrum, Base, Polygon, BSC, and all EVM-compatible chains

Platform detection is automatic based on your project structure, or you can specify it explicitly.


Is my source code stored?

No. Your repository is cloned, analyzed, and deleted immediately after the scan completes. Odin Scan does not store your source code. Only the analysis results (findings, severity, code locations, remediation guidance) are retained. You can delete your analysis data at any time through the dashboard or by contacting support. See Data Handling for full details.


Can I use Odin Scan on private repositories?

Yes. The GitHub Action works with both public and private repositories. For private repositories, the action uses the GitHub token provided in the workflow to clone the repository. No additional configuration is required beyond the standard actions/checkout step.


How accurate is the AI analysis?

Odin Scan uses a multi-layered approach to maximize accuracy:

  1. Multi-agent consensus: Multiple independent AI models analyze your code in parallel. When multiple models flag the same issue, confidence is boosted.
  2. Verification pipeline: Every AI-generated finding is cross-verified against the source code to confirm the vulnerability is present and reachable.
  3. Severity adjustment: Repository context (audit history, compiler version, trust model) is factored into final severity ratings.
  4. Static analysis: Deterministic lint rules complement AI findings with zero-ambiguity pattern matching.

No automated tool is a replacement for a manual audit, but Odin Scan is designed to surface real issues while minimizing noise.


Can I self-host Odin Scan?

Self-hosting is not currently available. Odin Scan operates as a cloud service. An enterprise self-hosted option is planned for a future release. Contact support@odinscan.ai if you are interested in early access.


How do I report a false positive?

You can report false positives in two ways:

  1. Dashboard: Open the finding in the Odin Scan dashboard and mark it as a false positive. This feedback improves future scans.
  2. Email: Contact support@odinscan.ai with the analysis ID and finding details.

What AI models are used?

Odin Scan uses multiple state-of-the-art large language models for multi-agent consensus. The specific models are continuously updated to incorporate the latest advances in AI reasoning. Each model analyzes the code independently, and consensus across models increases finding confidence.


How do I cancel my subscription?

  1. Navigate to Settings > Subscription in the Odin Scan dashboard.
  2. Click Manage Subscription to open the Polar.sh customer portal.
  3. Select Cancel Subscription.

Your access continues until the end of the current billing period. See Subscription Portal for details.

Changelog

All notable changes to Odin Scan are documented on this page.

The format follows Keep a Changelog. Each release is listed with the version number and date, organized into the following categories where applicable: Added, Changed, Fixed, Removed.


[Unreleased]


[1.0.0] - 2026-02-18

Initial public release of Odin Scan.

Added

  • Multi-agent AI analysis with multiple state-of-the-art models
  • Support for CosmWasm, Solana (SVM), and EVM platforms
  • Deterministic static analysis rules
  • Verification pipeline with cross-verification and severity adjustment
  • GitHub Action with SARIF upload, PR comments, and inline annotations
  • Findings visibility modes (full, counts, private) for public repository security
  • Basic and Pro subscription plans with team support
  • Organization management with role-based access control
  • Scan quota pooling for team organizations
  • REST API with JWT authentication
  • Dashboard with reports, filters, and exports