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
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.
https://lab917.ftp.shAuthorization: Bearer <token> for publish and deleteThe scope is derived from the artifact class: cnet, pem or ssh. A scoped token is limited to the scopes listed in its configuration.
CNET INVITATION, CNET REQUEST, CNET PASS. The armor is checked, the signature, network and time window are not.authorized_keys form, one per line. Private keys are rejected.| Block | Content |
|---|---|
CERTIFICATE, TRUSTED CERTIFICATE | X.509 certificate |
CERTIFICATE REQUEST, NEW CERTIFICATE REQUEST | PKCS#10 CSR |
X509 CRL | revocation list |
PUBLIC KEY, RSA PUBLIC KEY | public key |
PKCS7 | public 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.
Request body is the artifact text as text/plain; charset=utf-8. The class is recognized from the armor or from the SSH line.
| Header | Value |
|---|---|
Authorization | Bearer <token> (required) |
Content-Type | text/plain; charset=utf-8 |
X-CDROP-TTL | Optional lifetime, for example 24h. Range 1h–168h. |
X-CDROP-GRANT | Optional: 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.
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 / URL | Value |
|---|---|
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).
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.
.txt) decrements remaining by one.HEAD does not decrement and does not count as a fetch.remaining reaches zero or the TTL expires, both endpoints return 410 Gone.404 Not Found.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
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.
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.
| Status | Meaning |
|---|---|
204 | Deleted. |
401 | Missing or invalid token. |
403 | Token is not allowed for the object's scope. |
404 | Unknown ID. |
410 | Already expired, exhausted, or deleted. |
curl -X DELETE https://lab917.ftp.sh/api/v1/objects/7Q2M9K4TABCD \ -H "Authorization: Bearer $TOKEN"
200 ok when the database is reachable, 503 otherwise.
Operational metrics are available only to operators.
This page. The site root lab917 is a separate landing page.
| Setting | Default | Range / notes |
|---|---|---|
| Artifact size | 16 KiB | Server maximum 64 KiB; larger bodies return 413. |
| TTL | 24h | 1h–168h; above the server maximum returns 400. |
| Fetches | 3 | 1–3, fixed at publication. |
| Rate limits | per IP | 429 with Retry-After. |
| Cleanup | periodic | Expired rows are removed; afterwards the ID returns 404. |
The API returns a compact JSON object:
{"error": "object not found"}
| Status | When |
|---|---|
400 | Not a supported artifact, empty body, or invalid X-CDROP-TTL. |
401 | Missing or invalid publish token. |
403 | Token is not allowed for this scope. |
404 | Unknown object ID. |
410 | Expired, exhausted, or deleted object. |
413 | Artifact is larger than the server maximum. |
422 | Private key, unsupported block type, mixed artifact classes, or too many blocks. |
429 | Rate limit exceeded. |
500 | Internal or database error. |
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.