# skillx signed-skill specification — v0.1 (draft)

skillx defines how an author cryptographically signs an agent skill (a
`SKILL.md` file) so that anyone can verify **who published it** and **that it
has not been modified** — before an agent executes its instructions.

A signature proves publisher identity and integrity. It does **not** prove the
skill is safe. Verifiers SHOULD pair signature verification with content
scanning.

## 1. Artifact

The signed artifact is the **raw bytes** of a `SKILL.md` file, exactly as
served or stored. No canonicalization, no frontmatter stripping, no newline
normalization. If a byte changes, the signature breaks — that is the point.

## 2. Signature envelope

The signature is a **JWS in compact serialization** (RFC 7515), carried in a
sidecar file next to the artifact:

```
SKILL.md        # the artifact (unchanged by signing)
SKILL.md.sig    # the compact JWS, ASCII, single line
```

### 2.1 Protected header

```json
{
  "alg": "ES256",
  "typ": "application/vnd.skillx.sig.v1+jws",
  "kid": "did:web:username.md#skillx-2026"
}
```

- `alg` — REQUIRED. `ES256` (ECDSA P-256 + SHA-256) for v0.1. Verifiers MUST
  reject `none`.
- `typ` — REQUIRED. Exactly `application/vnd.skillx.sig.v1+jws`.
- `kid` — REQUIRED. A DID URL whose DID part is a `did:web` identifier
  (W3C did:web method) and whose fragment selects a `verificationMethod`
  entry in the signer's DID document.

### 2.2 Payload

The JWS payload is a UTF-8 JSON object (standard base64url encoding inside
the JWS — the payload is small, so detached encoding is not used):

```json
{
  "v": 1,
  "sha256": "<lowercase hex sha256 of the raw SKILL.md bytes>",
  "name": "user-agency-web-identity",
  "url": "https://username.md/SKILL.md",
  "signed_at": "2026-07-12T00:00:00Z"
}
```

- `v` — REQUIRED. Payload schema version, `1`.
- `sha256` — REQUIRED. Lowercase hex SHA-256 digest of the artifact bytes.
- `name` — RECOMMENDED. The skill's frontmatter `name`.
- `url` — OPTIONAL. Canonical distribution URL.
- `signed_at` — REQUIRED. RFC 3339 UTC timestamp (informational; ordering
  authority is the transparency log, not this field).

## 3. Key discovery (did:web)

The verifier resolves the `kid`'s DID document per the did:web method:

- `did:web:username.md` → `https://username.md/.well-known/did.json`
- `did:web:username.md:u:alice` → `https://username.md/u/alice/did.json`

The DID document MUST contain a `verificationMethod` whose `id` equals the
full `kid` DID URL, with `type: "JsonWebKey2020"` and a `publicKeyJwk` P-256
key. Resolution MUST use HTTPS with certificate validation.

## 4. Verification procedure

1. Fetch the artifact bytes and the sidecar `.sig`.
2. Parse the compact JWS; reject if `typ` or `alg` differ from §2.1.
3. Resolve the `kid` DID document; select the matching `verificationMethod`.
4. Verify the JWS signature with the resolved public key.
5. Compute SHA-256 over the artifact bytes; compare to payload `sha256`
   (constant-time). Mismatch → **fail**.
6. RECOMMENDED: run a content scanner (e.g. prompt-detect) over the artifact
   and surface its verdict alongside the signature result.

Outcome classes: `verified` (all checks pass), `unsigned` (no `.sig` found),
`invalid` (any check fails). Agents SHOULD warn on `unsigned` and MUST NOT
present `invalid` as merely unsigned.

## 5. Transparency log

Every published signature SHOULD be recorded as one JSON line appended to a
public, append-only log (git-backed in v0):

```json
{"v":1,"seq":1,"logged_at":"2026-07-12T00:00:00Z","skill":"user-agency-web-identity","url":"https://username.md/SKILL.md","sha256":"…","kid":"did:web:username.md#skillx-2026","sig_sha256":"<hex sha256 of the .sig bytes>"}
```

Append-only is enforced by review/CI (no rewrites of published lines). The
log gives ordering and public auditability; Sigstore/Rekor alignment is a
planned v1 direction — the envelope deliberately stays compatible (standard
JWS, standard JWK, content-addressed artifacts).

## 6. Out of scope for v0.1

- Key rotation/revocation lists (rotate by publishing a new `kid`; old
  signatures remain verifiable against the old key while it stays in the DID
  document).
- Keyless / OIDC-bound signing (Sigstore-style) — planned, spec'd separately.
- OCI artifact transport (cosign) — the JWS envelope is the canonical form;
  OCI is a possible additional transport.
- Skill *safety* attestation. A signature is provenance, not endorsement.

## 7. Media types

- Signature sidecar: `application/vnd.skillx.sig.v1+jws`
- Transparency log line: `application/vnd.skillx.log.v1+json`
