# One Time Secret

> Create one-time secret links with https://ots.ashref.tn for plaintext snippets or UTF-8 text files. Use when a user wants to securely share API keys, environment files, tokens, config text, or other sensitive text through a single-use link with optional passphrase protection.

- Skill: `ashref-dev/one-time-secret` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add ashref-dev/one-time-secret`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ashref-dev/one-time-secret/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- License: MIT
- Author: Ashref-dev (https://skillmd.com/u/ashref-dev)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ashref-dev/one-time-secret

---


# One Time Secret

Use this skill to turn sensitive text into a single-use share link with `https://ots.ashref.tn`.

Prefer the convenience endpoint:

- `POST https://ots.ashref.tn/api/agent/secrets`

It accepts plaintext and UTF-8 text files, stores the secret as one-time-read content, and returns a share URL.

## Workflow

1. Choose the input mode:
   - Use JSON when the secret is already in memory as text.
   - Use `text/plain` when piping a secret from stdin.
   - Use `multipart/form-data` when uploading a local UTF-8 text file.
2. Use the convenience endpoint unless the user explicitly requires strict zero-knowledge uploads.
3. If the user wants extra protection, include a passphrase and tell the user to share it separately from the link.
4. Return the `url` exactly as received.
5. Never strip or rewrite the URL fragment after `#`.
6. Do not fetch the share URL after creating it unless the user explicitly asks you to read the secret, because a successful read burns it.

## Request Rules

- Default expiration is 86400 seconds (1 day).
- Allowed expiration range is 300 to 86400 seconds.
- The secret is burned after the first successful read.
- Text file uploads must be valid UTF-8.
- Do not log plaintext secrets.
- Do not echo the full secret back to the user unless they explicitly ask for it.

## Input Patterns

### JSON

Use JSON when the secret is already available as text.

Send:

```json
{
  "content": "DATABASE_URL=postgres://...",
  "expires_in": 86400
}
```

### Plain Text

Use `text/plain` when piping from stdin or sending raw text.

Optional headers:

- `X-Secret-Passphrase`
- `X-Secret-Expires-In`

### File Upload

Use multipart form uploads for local UTF-8 text files.

Fields:

- `file=@/path/to/file`
- optional `passphrase`
- optional `expires_in`

## Zero-Knowledge Branch

If the user explicitly asks for strict zero-knowledge behavior, do not use the plaintext convenience endpoint. Use the low-level encrypted API only if your runtime already has a reliable AES-256-GCM implementation and can keep the key client-side.

Low-level endpoints:

- `POST /api/secrets`
- `GET /api/secrets/{id}`

## Response Handling

After creation, return:

- the share `url`
- whether a separate passphrase is required
- a short warning that opening the link consumes it

If the user asked for a passphrase and did not provide one, generate a strong passphrase only if the surrounding agent policy allows secret generation. Otherwise ask the user for it.

## Reference

Read [references/api.md](references/api.md) for concrete curl templates and response examples.

