Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

Safely Extract Archive

file.safe_extract_archive

ProductionBounded custom (Class B)Deterministicverifiablemoderatev1.0.0
File inputFile outputNo networkTemp storage

Overview

You pass a managed ZIP reference and we extract entries into tenant-isolated managed storage with mandatory safety checks: we reject path traversal, absolute or drive-letter paths, NUL bytes, symlink entries (unless you opt in), entry-count caps, total uncompressed size caps, and per-entry compression-ratio limits. Each extracted file gets a new fileRef and SHA-256. Do not use this to write to arbitrary filesystem paths on your servers. Archive members cost 1 execution credit per 10 members, rounded up, minimum 1, capped at 10000 members (1000 credits).

Archive extraction is dangerous — we enforce the standard defenses by default so you do not reimplement them in every workflow.

Reliability

The same archive always extracts the same bytes, but the call is not idempotent: every run mints new file references, so a retry leaves you with a second copy to clean up or ignore. Safety checks abort the whole extraction rather than skipping an entry, and none of the typed failures improve on retry. ARCHIVE_MALFORMED means the bytes do not start with the PK signature or the ZIP could not be opened, so re-upload the file or reject it as corrupt. ARCHIVE_ENTRY_LIMIT_EXCEEDED means the archive holds more entries than maxEntries (10,000 by default, up to 1,000,000) — raise the cap if you trust the archive. ARCHIVE_UNCOMPRESSED_LIMIT_EXCEEDED means the extracted bytes passed maxTotalUncompressedBytes (500 MiB by default and as a hard platform maximum), or one file passed the 50 MiB managed-object maximum, so lower the archive size or split the bundle; caller values cannot raise either platform limit. ARCHIVE_COMPRESSION_RATIO_EXCEEDED means one entry expands by more than maxCompressionRatio (100 by default and as a hard platform maximum), measured from the bytes we actually expand rather than the ZIP's claimed size — treat the archive as hostile. ARCHIVE_UNSAFE_ENTRY_PATH means an entry path was empty, absolute, backslashed, carried .. or a drive letter, or contained a NUL byte, all of which would escape the destination, so reject the archive. ARCHIVE_SYMLINK_REJECTED means a symlink entry was present while allowSymlinks is false — opt in deliberately or drop the archive. Separately, an expired or foreign fileRef, an archive over 200 MiB, and an archiveType outside zip and auto come back as validation errors, and the fix is to re-upload or correct the field.

Context footprint

Returns per-file references, SHA-256 digests, and extraction summary statistics. Archive members cost 1 execution credit per 10 members, rounded up, minimum 1, capped at 10000 members (1000 credits). The archive reference does not name member count, so we reserve that ceiling, or a lower maxEntries when you supply one, until settlement reports the members actually extracted.

When to use it

To unpack an untrusted archive into isolated managed storage.

When you only need a manifest (use file.extract_zip_manifest).

Scope

Note
Extracts a ZIP into managed storage with zip-slip and zip-bomb defenses enabled.

Non-goals

  • Does not extract to caller-controlled filesystem paths
  • Does not follow symlinks by default
  • Does not decrypt password-protected archives

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

compression

Cost & billing

1 execution credit per 10 archive members, rounded up, reserved from the request and capped at 10000 members (1000 credits).

MetermembersBillable onsuccessCost per member1 credit

File handling

Accepts file_refProduces file_refMax input200 MBMax file size200 MB

File limits

Constraints this skill applies to your input and generated files. The “Limited by” column shows the static source of each cap; none of these can be raised by upgrading your plan.

LimitValueLimited by
Maximum size per input file50 MiBPlatform maximum
Max archive entries1,000,000Skill content limit

How we handle your data

Protected temp storage
What this means

This skill may temporarily store files or intermediate data only to complete execution. Temporary data is protected and automatically deleted.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Temporary execution only storage
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • This skill does not target sensitive data.
  • The response may contain submitted or transformed content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
fileRefstringYesManaged ZIP reference resolved inside the current tenant, read up to 200 MiB.
archiveTypestringNoArchive kind; omit it for auto.
destinationPolicystringNoExtracted-file lifetime; omit it for managed_storage.
maxEntriesintegerNoHow many entries are walked before failing; omit it for 10000.
maxTotalUncompressedBytesintegerNoCeiling on extracted bytes; omit it for 524288000, and larger values are clamped to that platform ceiling.
maxCompressionRationumberNoLargest allowed uncompressed-to-compressed ratio; omit it for 100.
allowSymlinksbooleanNoWhether symlink entries are stored as ordinary files; omit it for false.

Output schema

FieldTypeRequiredDescription
okbooleanYesAlways true on successful extraction.
filesarrayYesBounded array of 0 through 1000000 closed extracted files in archive order.
summaryobjectYesClosed extraction totals including destination policy, extracted file count and skipped count.
metadataobjectNoClosed extraction metadata naming the entry cap, symlink detection, and engine.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"file.safe_extract_archive","input":{"fileRef":"squillify://files/f-1"}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("file.safe_extract_archive", {"fileRef":"squillify://files/f-1"});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
ARCHIVE_MALFORMED400NoThe request payload failed this skill's input validation.
ARCHIVE_ENTRY_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
ARCHIVE_UNCOMPRESSED_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
ARCHIVE_COMPRESSION_RATIO_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
ARCHIVE_UNSAFE_ENTRY_PATH422NoThe input was rejected as unsafe.
ARCHIVE_SYMLINK_REJECTED422NoThe input was rejected as unsafe.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not extract to caller-controlled filesystem paths
  • Does not follow symlinks by default
  • Does not decrypt password-protected archives
  • Inspect-only archive listing (use file.extract_zip_manifest)
  • Writing extracted files to your local disk paths

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "file.safe_extract_archive",
  "input": {
    "fileRef": "squillify://files/f-1"
  }
}

Examples

Extract a small text file from a ZIP

Inputjson
{
  "fileRef": "squillify://files/f-1"
}
Expected outputjson
{
  "ok": true,
  "summary": {
    "totalUncompressedBytes": 5,
    "extractedCount": 1,
    "destinationPolicy": "managed_storage",
    "directories": 0
  },
  "files": [
    {
      "expiresAt": "2026-07-13T00:10:00Z",
      "sha256": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8",
      "path": "a.txt",
      "fileRef": "squillify://files/f-out-1",
      "sizeBytes": 5
    }
  ],
  "metadata": {
    "engine": "commons-compress",
    "symlinkDetection": "Unix external-attribute mode",
    "maxEntries": 10000
  }
}

Short-lived temp storage for one-off processing

Inputjson
{
  "fileRef": "squillify://files/f-1",
  "destinationPolicy": "managed_temp"
}
Expected outputjson
{
  "ok": true,
  "summary": {
    "totalUncompressedBytes": 5,
    "extractedCount": 1,
    "destinationPolicy": "managed_temp",
    "directories": 0
  },
  "files": [
    {
      "expiresAt": "2026-07-13T00:10:00Z",
      "sha256": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8",
      "path": "a.txt",
      "fileRef": "squillify://files/f-out-1",
      "sizeBytes": 5
    }
  ],
  "metadata": {
    "engine": "commons-compress",
    "symlinkDetection": "Unix external-attribute mode",
    "maxEntries": 10000
  }
}
  • Ingest uploaded archives safely before downstream processing
  • Unpack bundles into isolated managed file references
  • Get per-file SHA-256 after controlled extraction

Avoid for

  • Inspect-only archive listing (use file.extract_zip_manifest)
  • Writing extracted files to your local disk paths

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

ziparchivefile