Onder Instellingen → DevOps koppel je je CI/CD-providers aan FixControl. Eenmaal gekoppeld ontvangt FixControl de deploy- en pipeline-events van die host, controleert de handtekening, beoordeelt elk event op risico via de policy-engine en schrijft een hash-geketend, append-only logboek weg (in de database beschermd tegen wijzigingen).
Standaard observeren-en-governen. Voor de meeste providers beoordeelt en logt FixControl je deployments — het triggert of rolt niets uit op eigen houtje. Waar geconfigureerd — elk standaard uit, per organisatie — bestaan er drie uitvoeringspaden, en elk ervan draait pas na een vastgelegde menselijke beslissing: Argo Rollouts-promotie (een goedgekeurde poort promoot een gepauzeerde rollout), CI/CD-deployment-poorten (pilot — een goedgekeurde poort geeft een deployment vrij die je pipeline zelf pauzeerde; een afwijzing houdt hem vast) en een bestuurde workload-herstart (een monitoring- of deploy-event dat beleid als goedkeuring-vereist beoordeelt, opent een goedkeuring gebonden aan precies één workload; goedkeuren herstart die workload, en zonder die goedkeuring gebeurt er niets). Er is geen autonome deploy: FixControl start nooit een pipeline of deployment, via FixControl wordt niets vrijgegeven zonder een vastgelegde menselijke beslissing, en elk uitgevoerd verdict wordt geaudit.
Alleen admins van je organisatie kunnen deze pagina beheren, en alles erop geldt alleen voor je organisatie.
Hoe een koppeling werkt
Een koppeling is de binding tussen één CI/CD-host en jouw tenant. Elke koppeling heeft een soort die bepaalt hoe hij inlogt en hoe zijn webhooks geverifieerd worden:
| Soort | Voorbeeld | Hoe je koppelt |
|---|---|---|
| GitHub App | GitHub Actions | Installeer de FixControl GitHub App — verifieert via een App-niveau geheim, geen per-tenant geheim te kopiëren. |
| OAuth-app | GitLab CI | Koppel via OAuth (hergebruikt je bestaande GitLab-koppeling) + project-ID. |
| Handmatig | Jenkins, Azure DevOps, Argo CD, Vercel, Terraform Cloud, Kubernetes | FixControl maakt een webhook-geheim aan dat één keer wordt getoond; dat zet je op de webhook van de host. |
Alle acht providers zijn beschikbaar voor observeren-en-governen. Elke koppeling toont z'n live status:
niet gekoppeld → koppelen → gekoppeld → verminderd → ongeldige inloggegevens → ingetrokken
- Verminderd — gekoppeld, maar het laatste event gaf een (tijdelijke) fout.
- Ongeldige inloggegevens — een permanente auth-fout (token ingetrokken / app verwijderd).
- Ingetrokken — je hebt zelf ontkoppeld; webhooks worden geweigerd en opgeslagen inloggegevens gewist.
De providers
| Provider | Soort | Webhook-verificatie | Koppelen |
|---|---|---|---|
| GitHub Actions | GitHub App | HMAC-SHA256, App-niveau geheim | Installeer de GitHub App |
| GitLab CI | OAuth | Gedeeld token (X-Gitlab-Token) | Koppel GitLab (OAuth) + project-ID |
| Jenkins | Handmatig (legacy) | HMAC-SHA256 (X-FixControl-Signature) | Handmatig + Notification-webhook |
| Azure DevOps | Handmatig | HTTP Basic-auth (wachtwoord = geheim) | Handmatig + Service Hook |
| Argo CD | Handmatig | Bearer-token (Authorization: Bearer) | Handmatig + notifications-webhook |
| Vercel | Handmatig | HMAC-SHA1 (x-vercel-signature) | Handmatig + Vercel-webhook |
| Terraform Cloud | Handmatig | HMAC-SHA512 (X-TFE-Notification-Signature) | Handmatig + Run notification |
| Kubernetes | Handmatig | HMAC-SHA256 + X-FixControl-Account (cluster-ID) | Handmatig + rollout-forwarder |
Een provider koppelen
De grote lijn is voor elke provider hetzelfde:
- Open Instellingen → DevOps en kies de provider.
- GitHub: klik GitHub App installeren. GitLab: klik GitLab koppelen en vul het numerieke project-ID in. Handmatig: vul de instance-/job-identifier in (en optioneel een API-token).
- Bij een handmatige (of GitLab-) koppeling toont FixControl een webhook-geheim — kopieer het meteen, het wordt maar één keer getoond.
- Plak de webhook-URL (die de kaart toont) in de webhook-instellingen van de host, en zet het geheim in het juiste veld/de juiste header (de kaart geeft per provider de exacte hint).
- Draai een echte pipeline of deploy. De koppeling toont recente gegoverneerde runs zodra de eerste binnenkomt.
Toont de kaart geen webhook-URL, vraag het dan je FixControl-contactpersoon. Zonder webhook-URL kan een host FixControl niet bereiken.
Voorbeeld: GitLab CI
- In FixControl → Instellingen → DevOps → GitLab koppelen, voer het project-ID in. Kopieer het getoonde geheim.
- In het GitLab-project → Settings → Webhooks: voeg de webhook-URL toe, plak het geheim als Secret token, en zet Pipeline events, Deployment events en Merge request events aan. Merge request events houden de afleverstatus van de merge requests van FixControl actueel (zie Git-providers); er is geen tweede webhook nodig.
Uitgaande webhooks — FixControl dat zijn eigen gebeurtenissen naar jouw systemen stuurt — zijn een ander oppervlak en staan onder Instellingen → Kanalen → Webhooks & API → Uitgaande webhooks. Zie Webhooks.
Voorbeeld: Jenkins (legacy)
Jenkins heeft geen standaard voor ondertekende webhooks. FixControl verifieert daarom een HMAC die je zelf op een Notification-webhook instelt. Gebruik bij voorkeur GitHub of GitLab. Wil je toch Jenkins: vul de Jenkins-form in, kopieer het geheim, en laat Jenkins de build-JSON POSTen met de header X-FixControl-Signature: sha256=<HMAC van de body>.
De exacte stappen per provider (Azure DevOps, Argo CD, Vercel, Terraform Cloud, Kubernetes) volgen hetzelfde patroon: koppel handmatig, kopieer het eenmalige geheim, en wire de webhook van de host naar de getoonde URL met de header uit de kaart-hint. Heb je diepere hulp nodig bij een specifieke host, vraag het dan je FixControl-contactpersoon.
CI/CD-deployment-poorten (pilot)
Waar geconfigureerd opent een pauze die je pipeline al vasthoudt een FixControl-deployment-poort. Wat een poort mag doen, stelt een admin van je organisatie in onder Instellingen → AI & goedkeuring → Goedkeuringen → Deployment-bevoegdheden. Elke bevoegdheid daar staat standaard uit:
- Gates openen voor je eigen deployments — open een poort voor een deploy waar geen door FixControl geschreven wijziging achter zit. Dit legt alleen een besluit vast; het schrijft niets.
- Het oordeel terugkoppelen naar de CI/CD-host — laat een goedkeuring of afwijzing de pipeline bereiken die de pauze vasthoudt (GitHub Actions, GitLab CI of Jenkins).
- Een gepauzeerde Argo Rollout promoveren — laat een goedkeuring de volgende stap van een gepauzeerde rollout promoveren.
- Het oordeel overdragen aan een fc-agent in je cluster — publiceer het oordeel zodat je eigen agent het ophaalt, in plaats van dat FixControl je netwerk inbelt.
Staan poorten open maar is er niets aangezet om te schrijven, dan kijkt FixControl alleen mee: besluiten worden vastgelegd en geen oordeel verlaat FixControl. Bij het aanzetten van een bevoegdheid vraagt FixControl om een reden, die in de audittrail wordt vastgelegd.
Eenmaal aangezet wordt de pauze van elke host dit:
| Host | De pauze | Goedkeuren voert uit | Afwijzen |
|---|---|---|---|
| GitHub Actions | Een environment met verplichte reviewers | De environment review wordt als approved beantwoord | De review wordt als rejected beantwoord; de run blijft vastgehouden |
| GitLab CI | Een deployment-approval, of een when: manual-deploy-job | De approval wordt verleend, of de handmatige job wordt gespeeld | Een deployment-approval wordt als rejected beantwoord; bij een handmatige job wordt niets geschreven — de ongespeelde job is de afgedwongen weigering (zie Eerlijke grenzen) |
| Jenkins | Een input-stap | De input wordt doorgezet | De input wordt afgebroken; de build eindigt zichtbaar |
De werking, in gewone taal:
- Je pipeline bereikt de pauze die hij al had. FixControl startte de pipeline niet en kan er geen starten.
- Het webhook-event van de host bereikt FixControl, dat een deployment-poort opent — een goedkeuring met de run, de omgeving en de risicocontext eraan.
- Iemand van je team beslist. De beslissing wordt vastgelegd met actor, rol, kanaal en bewijs.
- Het verdict wordt uitgevoerd via het eigen primitief van de host (de tabel hierboven) — nooit via een zijkanaal. Bij falen wordt het opnieuw geprobeerd vanuit de leveringswachtrij en verschijnt het op de tijdlijn; het faalt niet onzichtbaar.
- Poorten openen alleen op een pauze die de host meldt. Providers zonder pauze-primitief blijven observe-only.
Self-hosted en private hosts. Een self-hosted GitLab of Jenkins die vanaf FixControl bereikbaar is koppelt met zijn base_url. Een host die niet publiek bereikbaar is koppelt via de [FC Agent](/docs/nl/admin/fc-agent): het verdict reist dan als een getekende, aflopende, single-use operatie die de agent uitgaand ophaalt en van binnenuit je netwerk uitvoert. De agent draagt het verdict terug; het pipeline-event bereikt FixControl nog steeds via de eigen signed webhook van de host, dus de CI-host zelf heeft uitgaand HTTPS naar FixControl nodig (of een proxy die dat levert). Kubernetes, Argo, Jenkins en GitLab hoeven niet publiek te worden blootgesteld aan FixControl.
Eerlijke grenzen. Een GitLab-deployment die door een handmatige job wordt vastgehouden heeft geen weigerprimitief — de splitsing zit in de lane, niet in de GitLab-editie. Een afwijzing schrijft niets naar GitLab: de job blijft ongespeeld, en die ongespeelde job is de weigering. FixControl legt de beslissing vast met precies die uitleg. Deployment-approvals, waar je GitLab-tier ze biedt, dragen wél een echte afwijzing. Uitvoering van GitHub Actions-poorten vereist een aan een gebruiker toegeschreven GitHub-credential (een GitHub App kan geen reviewer zijn).
Wat jouw pijplijn zei over de geleverde commit
Een goedkeuringspoort in FixControl draagt al het sandbox-oordeel. Wat hij niet droeg is het oordeel van je eigen pijplijn over diezelfde commit — en die twee mogen best van elkaar verschillen. FixControls sandbox bewijst de wijziging in een geïsoleerde omgeving; jouw pijplijn draait hem onder de build van je eigen organisatie, met je eigen stappen.
Dus zodra een CI-run voor een commit die FixControl heeft geleverd klaar is, legt FixControl vast wat die run deed en bevriest dat naast het sandbox-oordeel op de goedkeuring.
Wat wordt vastgelegd, binnen vaste plafonds en niets daarbuiten:
- de run zelf — provider, id, link, uitkomst, de commit waar hij over ging, en wanneer de vastlegging is gedaan;
- de jobs (maximaal 20, gefaalde eerst): naam, uitkomst, het eigen woord van de host voor die uitkomst, tijden, link;
- een korte logstaart alleen voor gefaalde jobs — de laatste paar kilobytes, gemaskeerd op geheimen vóór opslag, voor maximaal drie jobs;
- een testsamenvatting waar de provider er een heeft (GitLabs testrapport, of JUnit-XML). GitHub Actions parseert geen testresultaten, en FixControl downloadt geen artifacts om ze te zoeken, dus een GitHub-vastlegging heeft géén testsamenvatting in plaats van een geraden;
- alleen artifact-metadata — naam, grootte, digest, vervaldatum. Artifacts worden nooit gedownload.
Alles is begrensd en de vastlegging zegt wanneer er is afgekapt: hoeveel jobs, artifacts, gefaalde tests en logs zijn weggelaten. Een begrensd verslag dat zijn grenzen toegeeft is bewijs; een dat er compleet uitziet niet.
Hoe het wordt vastgelegd. Er wordt niet gepold. Een afgeronde run komt binnen op de webhook die je al hebt ingesteld, en een job doet de vastlegging één keer per commit en run — hooguit één keer, ook als de webhook twee keer wordt afgeleverd. Een mislukte vastlegging maakt een webhook nooit non-2xx en verandert nooit een oordeel.
Wat er niet gebeurt:
- Een geannuleerde run levert helemaal geen bewijs op. "Geannuleerd" is geen oordeel over de code, en het als zodanig vastleggen zou uitnodigen om een annulering als groen te lezen.
- Het verandert niets. Geen poort leest het, geen oordeel verschuift erdoor, en een goedkeuring wordt er niet door verleend of geblokkeerd. Het wordt vastgelegd, bevroren in het beslisverslag, en is daarna raadpleegbaar.
- Twee providers doen het. GitHub Actions en GitLab CI. Jenkins, Azure DevOps, Argo CD, Vercel, Terraform Cloud en de Kubernetes-koppeling leggen hier vandaag niets vast — gekoppeld, maar stil op dit punt.
Vandaag is de vastlegging te lezen via de CI-status van de patch en wordt ze bevroren in het beslisverslag; ze heeft nog geen eigen paneel op het goedkeuringsscherm.
Pauzes van Terraform Cloud worden geen poort
Terraform Cloud kondigt een pauze voor menselijke goedkeuring aan, net als GitHub Actions, GitLab CI, Jenkins en Argo Rollouts — maar anders dan bij die vier heeft FixControl geen manier om hem te beantwoorden. De koppeling is alleen inkomend: hij draagt een geheim om handtekeningen te verifiëren, geen API-credential, dus er valt niets te bellen en niets terug te melden.
FixControl opent daarom bewust geen goedkeuringspoort op een pauze van Terraform Cloud. Een poort zou iemand een terraform apply hebben laten goedkeuren, die goedkeuring hebben vastgelegd, en de run hebben laten wachten op een bevestiging die nooit verstuurd werd. Een goedkeuring die niets doet maar eruitziet alsof ze iets deed, is erger dan geen goedkeuring. Events van Terraform Cloud worden nog steeds opgenomen, op risico gescoord en gelogd zoals bij elke andere provider; ze leveren alleen geen besluit op dat FixControl niet kan waarmaken.
Komt er later wél een manier om een oordeel terug te dragen naar Terraform Cloud, dan gaan de poorten vanzelf open — de regel is geschreven tegen "is er een pad om dit te beantwoorden?", niet tegen de naam van de provider.
Wat zie je na het koppelen?
- Op de koppelingskaart: het gekoppelde account, de scopes, de webhook-gezondheid (laatste event, aantal, laatste fout) en de knoppen Geheim roteren en Ontkoppelen.
- Onder Operaties (AI-operaties-governance): de gegoverneerde CI/CD-activiteit, de risicoverdeling, de infrastructuur-risicokaart en de goedkeuringswachtrij. Elk event krijgt een uitkomst: Automatisch, Alleen concept, Goedkeuring vereist of Geblokkeerd — volgens je beleid.
Beveiliging
- Versleuteld opgeslagen — tokens en webhook-geheimen liggen versleuteld op (per-tenant sleutel-envelop). De API geeft alleen booleans terug (heeft geheim ja/nee); een vers geheim wordt exact één keer getoond.
- Handtekening eerst — de webhook-route weigert elke payload die niet verifieert (
401), en logt die als afgewezen event. - Tenant-isolatie — alle tabellen zijn fail-closed RLS; binnenkomende webhooks resolven de tenant veilig vóór er iets geschreven wordt.
- Alleen beheerders — koppelen, ontkoppelen en geheim roteren vereisen
settings.edit. - Audit trail — koppelen, ontkoppelen, geheim roteren, elk geaccepteerd én elk geweigerd event zijn hash-geketend en append-only vastgelegd, en worden bewaard binnen het audit-retentievenster (365 dagen op de hosted dienst, nooit minder dan 90 — dat venster is platformbreed, niet per organisatie).
- Geen autonome uitvoering — ingestie op zichzelf triggert nooit een uitgaande actie; wat ze wél kan is een poort openen die een mens vervolgens beslist. De drie uitvoeringspaden — Argo Rollouts-promotie, CI/CD-deployment-poorten en de bestuurde workload-herstart, elk waar geconfigureerd en elk standaard uit — draaien uitsluitend na die beslissing, en elk uitgevoerd verdict wordt hash-chained in de audittrail vastgelegd.
Roadmap
Door een mens goedgekeurde Argo Rollouts-promotie en CI/CD-deployment-poorten (GitHub Actions, GitLab, Jenkins — pilot) zijn live waar geconfigureerd. Voor de roadmap geldt: deployment-uitvoering voorbij een verdict op een bestaande pauze bestaat niet en is ook niet als autonoom gedrag gepland — FixControl start, creëert of rolt geen deployments terug. Een bestuurde workload-herstart is op dezelfde manier beschikbaar, standaard uit, en vereist een Argo Rollouts-capability op de Kubernetes-koppeling plus de projectpermissie infrastructure.workload.restart. Draait je organisatie CI/CD zonder FixControl-missies achter de deployments, zet dan Gates openen voor je eigen deployments aan onder Deployment-bevoegdheden — anders wordt elke poort overgeslagen bij gebrek aan een missie om aan te hangen. Bredere poort-dekking over providers en rijkere rollout-controles volgen het pilotprogramma. Zie Governance & beleid voor hoe events op risico beoordeeld worden.
Zie ook: Integraties — overzicht · Governance & beleid · Security & audit.