cdrop

Short-lived publication of cnet artifacts, public PEM material and SSH keys. Publish once, share a short link or QR, fetch up to three times.

3 fetchesTTL 1–168 hcnet · pem · ssh

Publish an artifact →Full manual

Overview

cdrop is transport only. It does not verify signatures or certificate chains: it checks the text format and total size, stores the text for a limited time, and returns it over a short link. Receivers must verify the artifact themselves with their own tools.

Base URLhttps://lab917.ftp.sh
Artifact typescnet armor, public PEM, SSH public keys and certificates
Object IDshort opaque identifier, case-insensitive
AuthAuthorization: Bearer <token> for publish and delete

The scope is derived from the artifact class: cnet, pem or ssh. A scoped token is limited to the scopes listed in its configuration.

Artifact types

cnetArmored cnet artifacts: CNET INVITATION, CNET REQUEST, CNET PASS. The armor is checked, the signature, network and time window are not.
pemX.509 certificates (including chains), CSRs, CRLs, public keys and PKCS#7 bundles. Chains are not verified; only the format and the total size are checked.
sshOpenSSH public keys and SSH certificates in authorized_keys form, one per line. Private keys are rejected.

Allowed PEM blocks

BlockContent
CERTIFICATE, TRUSTED CERTIFICATEX.509 certificate
CERTIFICATE REQUEST, NEW CERTIFICATE REQUESTPKCS#10 CSR
X509 CRLrevocation list
PUBLIC KEY, RSA PUBLIC KEYpublic key
PKCS7public certificate bundle

Allowed SSH types: ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256/384/521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com and their -cert-v01@openssh.com certificate forms; GOST 2012 keys ssh-gost2012-256 and ssh-gost2012-512 (no certificate forms).

Blocked: private keys and private-key containers — RSA PRIVATE KEY (PKCS#1), PRIVATE KEY (PKCS#8), ENCRYPTED PRIVATE KEY, EC PRIVATE KEY, DSA PRIVATE KEY, OPENSSH PRIVATE KEY — as well as arbitrary text. Binary PKCS#12/PFX containers are not accepted. One publication may contain at most 16 blocks or SSH lines and is limited by the total body size.

cdrop is not a secret-sharing service. Never publish private keys, passwords or other secrets; use an end-to-end encrypted tool for that.

Publish an artifact

POST/api/v1/objects

Request body is the artifact text as text/plain; charset=utf-8. The class is recognized from the armor or from the SSH line.

HeaderValue
AuthorizationBearer <token> (required)
Content-Typetext/plain; charset=utf-8
X-CDROP-TTLOptional lifetime, for example 24h. Range 1h–168h.
X-CDROP-GRANTOptional: issue a limited grant, for example request=3. Works only with a publish token.
curl -X POST https://lab917.ftp.sh/api/v1/objects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: text/plain; charset=utf-8" \
  -H "X-CDROP-GRANT: request=3" \
  -H "X-CDROP-TTL: 24h" \
  --data-binary @invite.txt

Response 201 Created:

{
  "id": "7Q2M9K4TABCD",
  "url": "https://lab917.ftp.sh/o/7Q2M9K4TABCD",
  "expires_at": "2026-11-05T12:00:00Z",
  "remaining": 3,
  "sha256": "9f2c...",
  "grant": {
    "kind": "request",
    "url": "https://lab917.ftp.sh/p/cdg_...",
    "remaining": 3,
    "expires_at": "2026-11-05T12:00:00Z"
  }
}

remaining is fixed at publication (1–3, server default 3). sha256 is the digest of the stored text. grant is present only when a grant was requested or the request used a grant token.

A no-token web form with captcha is available at /publish.

Limited publication grants

A publish token may issue a grant: a full link to this same service, for example https://lab917.ftp.sh/p/cdg_.... The link lets the recipient publish the next artifact a limited number of times without a publish token. The full link is embedded into the published artifact itself: as an X-CDROP-GRANT header in cnet armor or PEM, or as a # X-CDROP-GRANT: ... comment in SSH text.

Header / URLValue
X-CDROP-GRANT<kind> or <kind>=<uses>; kind must match the artifact scope
GET /p/<token>HTML form: publish without captcha or token
POST /p/<token>Publish the grant artifact type

Allowed kinds: request (and other cnet kinds) for cnet, pem for PEM, ssh-key/ssh-cert for SSH. Grants are not tied to cnet. A grant is bound to its parent publication row and disappears with it; it cannot be used for metadata, deletion, the admin panel, or to issue another grant. Expired or exhausted grants return 410 Gone.

The captcha form at /publish has an "issue a grant" checkbox; it uses the server default number of publications (grants.uses).

Fetch an artifact

GET/o/<ID>
GET/o/<ID>.txt

The HTML page shows the artifact with a copy button, a status line, and a link to the text version. The .txt endpoint returns the exact armored text as text/plain.

Page responses set Cache-Control: no-store, X-Robots-Tag: noindex, Referrer-Policy: no-referrer, and a restrictive Content-Security-Policy.

curl https://lab917.ftp.sh/o/7Q2M9K4TABCD.txt

Metadata

GET/api/v1/objects/<ID>

Returns publication metadata without consuming a fetch. Requires the publish token.

curl https://lab917.ftp.sh/api/v1/objects/7Q2M9K4TABCD \
  -H "Authorization: Bearer $TOKEN"
{
  "id": "7Q2M9K4TABCD",
  "kind": "invite",
  "scope": "cnet",
  "size": 1302,
  "sha256": "9f2c...",
  "created_at": "2026-11-04T12:00:00Z",
  "expires_at": "2026-11-05T12:00:00Z",
  "remaining": 2
}

kind is one of invite, request, passport, pem, ssh-key, ssh-cert; scope is cnet, pem or ssh. Expired, exhausted, or deleted objects return 410 Gone; unknown IDs return 404.

Delete an artifact

DELETE/api/v1/objects/<ID>

Requires the publish token. Deletion is immediate but soft: the remaining count is set to zero and the object returns 410 Gone until the cleanup cycle removes the row.

StatusMeaning
204Deleted.
401Missing or invalid token.
403Token is not allowed for the object's scope.
404Unknown ID.
410Already expired, exhausted, or deleted.
curl -X DELETE https://lab917.ftp.sh/api/v1/objects/7Q2M9K4TABCD \
  -H "Authorization: Bearer $TOKEN"

Utility endpoints

GET/healthz

200 ok when the database is reachable, 503 otherwise.

Operational metrics are available only to operators.

GET/cdrop

This page. The site root lab917 is a separate landing page.

Limits and defaults

SettingDefaultRange / notes
Artifact size16 KiBServer maximum 64 KiB; larger bodies return 413.
TTL24h1h–168h; above the server maximum returns 400.
Fetches31–3, fixed at publication.
Rate limitsper IP429 with Retry-After.
CleanupperiodicExpired rows are removed; afterwards the ID returns 404.

Errors

The API returns a compact JSON object:

{"error": "object not found"}
StatusWhen
400Not a supported artifact, empty body, or invalid X-CDROP-TTL.
401Missing or invalid publish token.
403Token is not allowed for this scope.
404Unknown object ID.
410Expired, exhausted, or deleted object.
413Artifact is larger than the server maximum.
422Private key, unsupported block type, mixed artifact classes, or too many blocks.
429Rate limit exceeded.
500Internal or database error.

CLI

The cdrop executable reads its configuration from the path given by -config (or CDROP_CONFIG) and the publish token from CDROP_TOKEN (or the publish_token field in the config).

# Publish and print the short URL
cdrop publish -config cdrop.yaml -file invite.txt

# Publish with a terminal QR and a PNG copy
cdrop publish -config cdrop.yaml -file invite.txt -qr -qr-out invite.png

# Fetch the text
cdrop get -config cdrop.yaml 7Q2M9K4TABCD

# Metadata
cdrop status -config cdrop.yaml 7Q2M9K4TABCD

# QR in the console, or as a PNG file
cdrop qr -config cdrop.yaml 7Q2M9K4TABCD
cdrop qr -config cdrop.yaml -out link.png 7Q2M9K4TABCD

In the examples above -qr prints the QR code to the console; -qr-out and -out write a PNG file.

Security notes

cdrop is not a CA and does not vouch for artifacts. Always verify signatures and certificate chains yourself before using an invitation, request, passport, certificate or key.