RSL licensing
RSL 1.0 (Really Simple Licensing, rslstandard.org) is the open XML standard for machine-readable content licensing. The SDK renders your live policy as an RSL document, so the license you publish is the policy you actually enforce.
Generate the document
import { createRslDocument } from "@corri/sdk/server";
const xml = createRslDocument(policyDefinition, {
contentUrl: "https://your-site.example/api/protected-report", // default "/"
paymentUrl: "https://your-site.example/docs/payments", // where to acquire a license
// licenseServer: "https://…", // OLP license server endpoint, if any
// standardLicenseUrl: "https://…" // e.g. a Creative Commons URL
});
The policy-to-RSL mapping:
| Policy construct | RSL output |
|---|---|
deny rules on purposes | <prohibits type="usage"> |
allow rules on purposes | <permits type="usage"> |
charge rules | <payment type="use"> with <amount> and the acquisition URL |
| Attribution obligations | <payment type="attribution"> |
Obligations without an RSL token (e.g. prohibit-republication) | Carried as XML comments for human review |
Serve it
Serve the XML with content type application/rsl+xml (exported as RSL_MEDIA_TYPE). This site does exactly that at /license.xml, generated from the live demo policy:
import { createRslDocument } from "@corri/sdk/server";
import { DEMO_POLICY } from "@/lib/demo-world";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
const origin = new URL(request.url).origin;
const xml = createRslDocument(DEMO_POLICY, {
contentUrl: `${origin}/api/protected-report`,
paymentUrl: `${origin}/docs/payments`
});
return new Response(xml, {
headers: { "content-type": "application/rsl+xml; charset=utf-8" }
});
}
Advertise it
Pass rsl: { policyUrl } to createAgentAccess and protected responses advertise the license document, so agents can discover your terms before (or while) requesting content. The header helper is also exported directly:
import { rslHeaders } from "@corri/sdk";
rslHeaders("https://your-site.example/license.xml");
// → headers advertising the RSL license document (Link rel="license")
Parsing (agent side)
Agents can read a publisher's terms with the safe parser, DOCTYPE declarations are rejected and entities are never resolved, so XXE is structurally impossible:
import { parseRslDocument } from "@corri/sdk";
const doc = parseRslDocument(xml);
// doc.contents[0] → {
// url, server?,
// licenses: [{ permits, prohibits, payments }]
// }
Purpose mapping
SDK purposes and RSL usage tokens interconvert via two exported maps: PURPOSE_TO_RSL_USAGE (e.g. training → train-ai) and RSL_USAGE_TO_PURPOSES for the reverse direction.
PolicyDefinition the server enforces, your published license can't drift from your actual access behavior.