# ArtifactGuard — Signed AI Deliverable QA (`analytical_gratefulness/artifactguard`) Actor

Validate AI-generated ZIP, PDF, DOCX, and JSON deliverables before client delivery. Checks archive safety, file contracts, JSON Schema, page limits, required text, secret patterns, and returns an independently verifiable Ed25519-signed PASS/WARN/FAIL receipt via REST or MCP.

- **URL**: https://apify.com/analytical\_gratefulness/artifactguard.md
- **Developed by:** [black cow](https://apify.com/analytical_gratefulness) (community)
- **Categories:** AI, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 artifact validation receipts

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## ArtifactGuard

ArtifactGuard validates AI-generated JSON, ZIP, PDF, and DOCX deliveries and returns an Ed25519-signed `PASS`, `WARN`, or `FAIL` receipt. It is built for agent-to-agent handoffs where the buyer needs deterministic evidence that a delivery matched a contract.

`validate_manifest` checks declared names, sizes, MIME types, SHA-256 values, and required archive paths for USD 0.01. `validate_artifact` inspects Base64 file bytes up to 10 MiB for USD 0.05. A malformed request is rejected before billing. A completed inspection whose result is `FAIL` is a valid paid result.

### What it checks

- JSON parsing and optional JSON Schema Draft 2020-12
- ZIP path traversal, duplicate paths, excessive expansion, compression ratios, encryption, symlinks, executables, and macro payloads
- PDF parsing, encryption, and page-count contracts
- DOCX container structure, parsing, text, executable, and macro checks
- Declared size and SHA-256
- Required and forbidden paths, required text, forbidden literal patterns
- Common private-key, API-key, local-user-path, and `file://` leakage patterns

ArtifactGuard never downloads arbitrary URLs. Artifact bytes are sent to a resource-limited parser process, are not written to the revenue ledger, and are released after the request. Logs and revenue events contain hashes, format/event metadata, payer hashes, and payment references—not document bytes or wallet private keys.

### REST example

Generate the fixed examples, start the local server, and post any request file:

```sh
python -m pip install -e '.[test]'
python scripts/generate_release_assets.py
artifactguard
curl -X POST http://127.0.0.1:8000/v1/validate/artifact \
  -H 'content-type: application/json' \
  --data-binary @samples/requests/json.json
```

Free endpoints are `/health`, `/capabilities`, and `/v1/keys/{key_id}`. Interactive OpenAPI is at `/docs`. Apify deployments also expose streamable HTTP MCP at `/mcp` with `validate_manifest` and `validate_artifact`.

Every successful response is wrapped as:

```json
{
  "data": {
    "artifact_sha256": "...",
    "contract_sha256": "...",
    "status": "PASS",
    "checks": [],
    "validator_version": "0.1.0",
    "generated_at": "2026-07-28T00:00:00+00:00",
    "receipt_sha256": "...",
    "key_id": "ed25519-...",
    "signature": "..."
  },
  "error": null,
  "meta": {}
}
```

Fetch the public Ed25519 key from `/v1/keys/{key_id}`. Verify the signature over the canonical JSON receipt after removing only the `signature` field. The same idempotency key and request returns the exact cached receipt; binding that key to different bytes returns `409`.

### Run modes

- `local`: no charge, loopback bind, ephemeral signing key allowed.
- `apify`: Pay-per-event standard runs plus Standby REST/OpenAPI and `/mcp`.
- `x402`: FastAPI x402 v2 middleware with Bazaar and required Payment Identifier extensions. MCP is consumed through Bazaar discovery rather than mounted directly on this instance.

In the Apify Input tab, choose `validate-manifest` or `validate-artifact` to
receive the signed receipt in the run dataset and `OUTPUT` record. Automated
Store tests are forced to the free readiness check and do not trigger a paid
event.

Production refuses to start without `ARTIFACTGUARD_ED25519_PRIVATE_KEY_B64`. The x402 mode additionally requires `X402_PAY_TO`; the service never needs the receiving wallet's private key. Use the CDP facilitator for Bazaar indexing. The first successful mainnet settlement is automatically excluded as `bazaar_indexing`; testnet, owner, and local calls are also excluded from external revenue.

`scripts/generate_signing_key.py` stores a newly generated signing key in a
mode-0600 file under `.secrets/` and prints only its path and public metadata.
Move the private value into the platform Secret and delete the local file after
the public-key endpoint is verified.

Production x402 also requires measured `ARTIFACTGUARD_ESTIMATED_MANIFEST_COST_USD` and `ARTIFACTGUARD_ESTIMATED_ARTIFACT_COST_USD`. Startup is blocked if either estimated hosting cost reaches its configured call price.

See `sales/APIFY_RELEASE.md` and `sales/X402_RELEASE.md` for account-side launch gates. Prices must be configured in the Apify Console with exact event names `manifest-validation` and `artifact-validation`.

### Verification

```sh
pytest
python scripts/release_check.py
python scripts/revenue_status.py
docker build -t artifactguard:local .
```

The release suite covers normal and damaged files, path traversal, compression bombs, macros and executables, encrypted PDF, sensitive patterns, oversize preflight, receipt tampering, concurrent duplicates, parser failure retries without a second application charge, x402 preflight, `402`, and revenue classification.

### 한국어 안내

ArtifactGuard는 다른 AI가 만든 JSON·ZIP·PDF·DOCX 납품물을 계약 기준으로 검사하고, 독립 검증 가능한 Ed25519 서명 `PASS/WARN/FAIL` 영수증을 반환합니다. 잘못된 요청은 과금 전에 거절하고, 정상 파일을 실제로 검사한 뒤 나온 `FAIL`은 유료 결과로 처리합니다.

원본 문서는 매출 원장이나 로그에 저장하지 않습니다. Apify에서는 PPE 이벤트 가격과 플랫폼 사용비 사용자 부담을 설정하고, x402에서는 Base Sepolia 검증 후 Base USDC 메인넷으로 전환합니다. 테스트넷·자기결제·첫 Bazaar 색인 정산은 실제 매출에서 자동 제외합니다.

### Operational limits

The local SQLite ledger and idempotency store protect concurrency and retries inside one running service instance. x402 replay protection additionally uses the required Payment Identifier extension. A multi-replica deployment must place idempotency state in a transactional shared store before horizontal scaling; keep the initial Standby deployment at one active service instance.

ArtifactGuard is a delivery-contract validator, not antivirus software, legal certification, or a guarantee that document contents are true.

# Actor input Schema

## `mode` (type: `string`):

validate-manifest costs $0.01; validate-artifact costs $0.05; readiness-check is free.

## `artifact` (type: `object`):

Manifest metadata for validate-manifest, or metadata plus content\_base64 for validate-artifact.

## `validation_contract` (type: `object`):

Allowed formats, size limits, required or forbidden content, and format-specific rules.

## `idempotency_key` (type: `string`):

Unique request key, 8–128 characters. Reuse only when retrying the same input.

## Actor input object example

```json
{
  "mode": "validate-manifest",
  "artifact": {
    "name": "sample.json",
    "mime_type": "application/json",
    "size_bytes": 31,
    "sha256": "368e9cedfb85b8fd10ff45e37e3440379fa6c53d6cd109cb0de2b8dcb1a1a5c8",
    "entries": []
  },
  "validation_contract": {
    "allowed_mime_types": [
      "application/json"
    ],
    "max_bytes": 10485760
  },
  "idempotency_key": "store-manifest-example-0001"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "validate-manifest",
    "artifact": {
        "name": "sample.json",
        "mime_type": "application/json",
        "size_bytes": 31,
        "sha256": "368e9cedfb85b8fd10ff45e37e3440379fa6c53d6cd109cb0de2b8dcb1a1a5c8",
        "entries": []
    },
    "validation_contract": {
        "allowed_mime_types": [
            "application/json"
        ],
        "max_bytes": 10485760
    },
    "idempotency_key": "store-manifest-example-0001"
};

// Run the Actor and wait for it to finish
const run = await client.actor("analytical_gratefulness/artifactguard").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "validate-manifest",
    "artifact": {
        "name": "sample.json",
        "mime_type": "application/json",
        "size_bytes": 31,
        "sha256": "368e9cedfb85b8fd10ff45e37e3440379fa6c53d6cd109cb0de2b8dcb1a1a5c8",
        "entries": [],
    },
    "validation_contract": {
        "allowed_mime_types": ["application/json"],
        "max_bytes": 10485760,
    },
    "idempotency_key": "store-manifest-example-0001",
}

# Run the Actor and wait for it to finish
run = client.actor("analytical_gratefulness/artifactguard").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "validate-manifest",
  "artifact": {
    "name": "sample.json",
    "mime_type": "application/json",
    "size_bytes": 31,
    "sha256": "368e9cedfb85b8fd10ff45e37e3440379fa6c53d6cd109cb0de2b8dcb1a1a5c8",
    "entries": []
  },
  "validation_contract": {
    "allowed_mime_types": [
      "application/json"
    ],
    "max_bytes": 10485760
  },
  "idempotency_key": "store-manifest-example-0001"
}' |
apify call analytical_gratefulness/artifactguard --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=analytical_gratefulness/artifactguard",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/5ClfxBvJG9j7arI9u/builds/Eo3PcP1WIcoCx9u6N/openapi.json
