API Reference

The SourceSeal REST API provides endpoints for submitting and querying attestations. Base URL: http://localhost:8080 (development).

Authentication

All endpoints under /api/v1/ require an API key unless running in development mode. Provide the key via:

http
Authorization: Bearer <api-key>
# or
X-API-Key: <api-key>

Rate Limiting

  • Read endpoints (GET): 100 requests/minute per IP
  • Write endpoints (POST): 20 requests/minute per IP
GET/healthz

Check that the server is running and responsive. No authentication required.

Response

json
{
  "status": "ok"
}

Status Codes

CodeDescription
200 OKServer is healthy

Example

bash
curl http://localhost:8080/healthz
POST/api/v1/attestations

Submit a signed attestation for a software artifact. The server verifies the Ed25519 signature before accepting the attestation and anchoring it on the blockchain ledger.

Request Body

json
{
  "attestation": {
    "artifact_hash": "sha256-hex-digest-64-chars",
    "ecosystem": "npm",
    "package_name": "@scope/my-package",
    "package_version": "1.2.3",
    "sbom_hash": "sha256-hex-digest-64-chars",
    "signer_key_id": "hex-key-id",
    "signature": "hex-encoded-ed25519-signature",
    "slsa_level": 3,
    "timestamp": 1700000000
  },
  "sbom": "<base64-encoded-sbom-bytes>",
  "public_key": "-----BEGIN SOURCESEAL ED25519 PUBLIC KEY-----\n...\n-----END SOURCESEAL ED25519 PUBLIC KEY-----"
}

Request Fields

FieldTypeRequiredDescription
attestation.artifact_hashstringYesSHA-256 hex digest (64 chars) of the artifact
attestation.ecosystemstringYesPackage ecosystem identifier (npm, pip)
attestation.package_namestringYesFull package name
attestation.package_versionstringNoPackage version string
attestation.signer_key_idstringYesHex-encoded key ID (SHA-256 of public key, first 16 bytes)
attestation.signaturestringYesHex-encoded Ed25519 signature
attestation.timestampintegerYesUnix timestamp of attestation creation
public_keystringYesPEM-encoded Ed25519 public key for signature verification
sbombytesNoBase64-encoded SBOM document

Response (Success)

json
{
  "id": "hex-attestation-id",
  "tx_id": "fabric-transaction-id"
}

Status Codes

CodeDescription
201 CreatedAttestation accepted and anchored on the ledger
400 Bad RequestInvalid body, missing fields, or signature verification failed
401 UnauthorizedMissing or invalid API key
429 Too Many RequestsWrite rate limit exceeded
500 Internal Server ErrorStorage or ledger submission failure

Example

bash
curl -X POST http://localhost:8080/api/v1/attestations \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "attestation": {
      "artifact_hash": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
      "ecosystem": "npm",
      "package_name": "@myorg/my-package",
      "package_version": "1.0.0",
      "signer_key_id": "abcdef0123456789abcdef0123456789",
      "signature": "deadbeef...",
      "slsa_level": 3,
      "timestamp": 1700000000
    },
    "public_key": "-----BEGIN SOURCESEAL ED25519 PUBLIC KEY-----\nMCowBQYDK2VwAyEA...\n-----END SOURCESEAL ED25519 PUBLIC KEY-----"
  }'
GET/api/v1/verify/{hash}

Look up an attestation by the artifact's SHA-256 hash and verify it against the blockchain ledger.

Path Parameters

ParameterDescription
hashSHA-256 hex digest (exactly 64 lowercase hex characters)

Response (Verified)

json
{
  "verified": true,
  "attestation": {
    "id": "hex-attestation-id",
    "artifact_hash": "a1b2c3d4...",
    "ecosystem": "npm",
    "package_name": "@myorg/my-package",
    "package_version": "1.0.0",
    "signer_key_id": "abcdef01...",
    "signature": "deadbeef...",
    "slsa_level": 3,
    "timestamp": 1700000000
  },
  "tx_id": "fabric-tx-id",
  "timestamp": 1700000100
}

Status Codes

CodeDescription
200 OKAttestation found. Check the verified field for ledger confirmation.
400 Bad RequestInvalid hash format
401 UnauthorizedMissing or invalid API key
404 Not FoundNo attestation found for the given hash
429 Too Many RequestsRead rate limit exceeded

Example

bash
curl http://localhost:8080/api/v1/verify/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 \
  -H "Authorization: Bearer your-api-key"
GET/api/v1/attestations?package={name}

Retrieve all attestations associated with a given package name.

Query Parameters

ParameterRequiredDescription
packageYesThe package name to search for

Response

json
[
  {
    "id": "hex-attestation-id-1",
    "artifact_hash": "a1b2c3d4...",
    "ecosystem": "npm",
    "package_name": "@myorg/my-package",
    "package_version": "1.0.0",
    "signer_key_id": "abcdef01...",
    "signature": "deadbeef...",
    "slsa_level": 3,
    "timestamp": 1700000000
  }
]

Status Codes

CodeDescription
200 OKQuery successful (may return an empty array)
400 Bad RequestMissing package query parameter
401 UnauthorizedMissing or invalid API key
429 Too Many RequestsRead rate limit exceeded
500 Internal Server ErrorFailed to query the attestation store

Example

bash
curl "http://localhost:8080/api/v1/attestations?package=@myorg/my-package" \
  -H "Authorization: Bearer your-api-key"
GET/api/v1/attestations/{id}

Retrieve a single attestation by its server-generated ID.

Path Parameters

ParameterDescription
idAttestation ID (16-64 lowercase hex characters)

Response

json
{
  "id": "hex-attestation-id",
  "artifact_hash": "a1b2c3d4e5f6...",
  "ecosystem": "npm",
  "package_name": "@myorg/my-package",
  "package_version": "1.0.0",
  "sbom_hash": "f6e5d4c3b2a1...",
  "signer_key_id": "abcdef0123456789...",
  "signature": "deadbeefcafebabe...",
  "slsa_level": 3,
  "timestamp": 1700000000
}

Status Codes

CodeDescription
200 OKAttestation found and returned
400 Bad RequestInvalid ID format
401 UnauthorizedMissing or invalid API key
404 Not FoundNo attestation found with the given ID
429 Too Many RequestsRead rate limit exceeded

Example

bash
curl http://localhost:8080/api/v1/attestations/abcdef0123456789 \
  -H "Authorization: Bearer your-api-key"

Error Format

All error responses use a consistent JSON format:

json
{
  "error": "human-readable error message"
}

All responses are application/json with UTF-8 encoding. The attestation submission endpoint enforces a maximum request body size of 10 MB.