Beveilig je relays

Wanneer twee apparaten geen directe verbinding kunnen maken, transporteert een relay de verbinding zodat data toch blijft stromen. Als de relay iedereen accepteert, kan iedereen die de URL kent verkeer erdoorheen sturen. En ze zullen deze vinden: de URL wordt meegeleverd in elke client die je distribueert en is zichtbaar voor iedereen die het tot stand komen van een verbinding observeert.

Vanwege dit feit hebben we besloten dat managed relays op Iroh Services nu standaard geauthenticeerd zijn. Alleen endpoints die een token dragen dat is uitgegeven door de API-sleutel van je project, kunnen ze gebruiken.

Er hoeft niets te worden geactiveerd. Als je al verbinding maakt via het iroh_services preset, authenticeren je endpoints zichzelf automatisch.

Een kanttekening: dit is de standaard voor relays die vanaf juni 2026 worden uitgerold. Als je een relay vóór die tijd hebt uitgerold, blijft deze openstaan, zodat er niets breekt voor de endpoints die deze al gebruiken. Om authenticatie in te schakelen, ga je naar de authenticatie-instellingen van je relay onder Relays > Settings.

Het probleem: een relay-URL is een inloggegeven die je niet kunt intrekken

Iemand vindt je relay-URL in een publieke repo, een client-bundel of een screenshot en begint je infrastructuur te spammen totdat deze platligt.

Je hebt moeite gedaan om je eigen relay op te zetten, maar het verkeer van iemand anders concurreert nog steeds met dat van jou. Een relay heeft een beperkte bandbreedte en een beperkt aantal verbindingsslots, of het nu gaat om een gehuurde box, een VM onder je bureau of capaciteit waarvoor je ons betaalt; iedereen die de URL heeft gevonden, maakt er nu gebruik van.

Als je je eigen relays beheert, kun je je eigen authenticatieschema bouwen — iroh is daar niet dwingend in. Maar als je onze managed relays gebruikt, boden we je tot deze maand geen eenvoudige manier om de toegang te controleren. Nu hebben we het eerste deel van de authenticatiepuzzel geleverd: API-sleutels. Je kunt deze onbeperkt uitgeven, roteren en verwijderen. Dit zijn dezelfde API-sleutels die je al gebruikt om metrieken door te sturen, dus als je Iroh Services gebruikt, heb je er al een.

Hoe het werkt

Elke relay-verbinding begint met een HTTP-handshake, dezelfde handshake die wordt geüpgraded naar de websocket. De authenticatie vindt plaats via een standaard header:

Authorization: Bearer <token>

Het token is een ondertekend capability token. Het bevat vier zaken:

  • Wie het heeft uitgegeven: de API-sleutel van je project.
  • Voor wie het bestemd is: de publieke sleutel van het endpoint dat het token presenteert.
  • Wat het toestaat: toestemming om de relay te gebruiken, en niets anders.
  • Wanneer het verloopt: dit kan worden ingesteld op een kort tijdsbestek, zodat het bij een eventueel lek niet langdurig kan worden gebruikt.

Wanneer een endpoint verbinding maakt, bewijst de relay-handshake van iroh eerst dat het endpoint daadwerkelijk eigenaar is van zijn sleutel. Dit gebeurt bij elke verbinding, geauthenticeerd of niet.

Vervolgens controleert de relay het token: is de handtekening geldig, is het niet verlopen, verleent het toegang tot de relay, is het gericht aan exact dit endpoint en is het uitgegeven door een van de API-sleutels van je project? Als op alle vragen "ja" wordt geantwoord, wordt het endpoint toegelaten.

Hieruit vloeien twee eigenschappen voort die we waarderen:

  1. Een gelekte URL is ongevaarlijk. Zonder een token dat is uitgegeven door jouw API-sleutel, levert het aanroepen van de URL niets op.
  2. Een gelekt token maakt verbindingen mogelijk, maar geen impersonatie. Het token is gericht aan de publieke sleutel van één specifiek endpoint. Het presenteren ervan vanuit een ander endpoint mislukt: de handshake moet namelijk nog steeds bewijzen dat men eigenaar is van de geheime sleutel van dat endpoint, wat het token alleen niet mogelijk maakt.

Intrekking volgt hetzelfde pad. Je API-sleutel is de identiteit die de relay herkent; het roteren of verwijderen van een sleutel zorgt ervoor dat tokens die door deze zijn uitgegeven niet meer worden geaccepteerd, waarna verbindingen die op die tokens draaien worden verbroken.

Een endpoint verbinden

Je hoeft dit niet handmatig in elkaar te zetten. Het iroh_services preset genereert het token vanuit je API-secret en voegt het voor jou toe aan elke relay-verbinding. Het bouwen van een geauthenticeerd endpoint vereist dezelfde paar regels code die je sowieso zou schrijven:

use iroh::Endpoint;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let preset = iroh_services::preset()
        .relays(["https://us-east1.your-project.iroh.link"])?
        .api_secret_from_env()? // leest IROH_SERVICES_API_SECRET
        .build()?;

    // Het endpoint bereikt nu je managed relays, geauthenticeerd.
    let endpoint = Endpoint::bind(preset).await?;
    Ok(())
}

Je API-secret verlaat nooit je proces. Het preset gebruikt het om een relay-scoped token af te leiden, en dat afgeleide token is wat naar de relay wordt verzonden. Richt .relays(...) op de relay-URL's uit je projectdashboard, stel IROHSERVICESAPI_SECRET in, en dat is alles.

Wat volgt er nog meer?

Op dit moment krijgt elk endpoint dezelfde rechten. In de toekomst voegen we de mogelijkheid toe om tokens met verschillende scopes te genereren, zodat je sommige endpoints meer rechten kunt geven dan andere. Daarnaast zullen we het mogelijk maken om toegang voor individuele endpoints in te trekken en een API beschikbaar stellen om dit alles buiten het dashboard om te doen.

Als je momenteel relays draait, raden we aan om er minimaal twee in verschillende regio's uit te rollen, zodat het uitvallen van één regio je endpoints niet geïsoleerd achterlaat. De gids voor managed relays loopt door de volledige installatie heen.