Offboarding misslyckas vanligtvis inte för att folk inte bryr sig. Det misslyckas för att det är utspritt över flera verktyg, görs sent på dagen, och “vi tar det i morgon” blir till ett GitLab-konto som ligger kvar i veckor.
Den här automationen för Odoo GitLab-offboarding träffar IT Ops först, men HR och Security får ofta städa upp samma röra. Du får kontolåsning på avslutsdagen utan att jaga ärenden, kalkylark eller “tog vi bort dem från det där projektet också?”-uppföljningar.
Nedan ser du hur flödet körs dagligen, hämtar slutdatumsposter från Odoo, blockerar GitLab, städar upp Redmine-åtkomst och loggar allt till Google Sheets för revisioner.
Så fungerar automationen
Det fullständiga n8n-flödet, från trigger till slutresultat:
n8n Workflow Template: Odoo till GitLab: lås åtkomst vid slutdatum
flowchart LR
subgraph sg0["Step1: Schedule Flow"]
direction LR
n0@{ icon: "mdi:cog", form: "rounded", label: "END", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Step2: Handle get today"]
n2@{ icon: "mdi:swap-vertical", form: "rounded", label: "Step3: Set Variables", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step5: If total_count is not..", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Step6: Check if there is a v.."]
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step7: If hasRecords is empt..", pos: "b", h: 48 }
n6@{ icon: "mdi:play-circle", form: "rounded", label: "Step1: Schedule Trigger", pos: "b", h: 48 }
n7@{ icon: "mdi:swap-vertical", form: "rounded", label: "Step8: Loop Over Items", pos: "b", h: 48 }
n8@{ icon: "mdi:cog", form: "rounded", label: "END1", pos: "b", h: 48 }
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step11: Get user info in RM6"]
n10@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step12: Check if there is a..", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step13: Update the user's st.."]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step14: Remove the user from.."]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step15: Get membership list .."]
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Step16: Get memberships_id"]
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Step17: Loop Over membership..", pos: "b", h: 48 }
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step18: Delete membership in.."]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step19: Get user information.."]
n18@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step20: Check if there is a..", pos: "b", h: 48 }
n19@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step21: Check if the user is..", pos: "b", h: 48 }
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step22: Check if the user is..", pos: "b", h: 48 }
n21["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step23: Block a user in Gitlab"]
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step24: Get user information.."]
n23@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step25: Check if there is a..", pos: "b", h: 48 }
n24@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step26: Check if the user is..", pos: "b", h: 48 }
n25@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Step27: Check if the user is..", pos: "b", h: 48 }
n26["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step28: Block a user in Gitlab"]
n27["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code"]
n28["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step9: Get employee informat.."]
n29["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Step4: Get Employee Resignat.."]
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Step10: Handle work_email"]
n27 --> n17
n2 --> n29
n7 --> n28
n6 --> n1
n1 --> n2
n30 --> n9
n14 --> n15
n9 --> n10
n21 --> n7
n26 --> n7
n15 --> n27
n15 --> n16
n5 --> n8
n5 --> n7
n17 --> n18
n22 --> n23
n4 --> n5
n18 --> n19
n18 --> n7
n23 --> n24
n23 --> n7
n29 --> n3
n28 --> n30
n10 --> n11
n10 --> n22
n13 --> n14
n16 --> n15
n3 --> n4
n3 --> n0
n12 --> n13
n19 --> n20
n19 --> n7
n24 --> n25
n24 --> n7
n20 --> n21
n20 --> n7
n25 --> n26
n25 --> n7
n11 --> n12
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n6 trigger
class n3,n5,n10,n18,n19,n20,n23,n24,n25 decision
class n9,n11,n12,n13,n16,n17,n21,n22,n26,n28,n29 api
class n1,n4,n14,n27,n30 code
classDef customIcon fill:none,stroke:none
class n1,n4,n9,n11,n12,n13,n14,n16,n17,n21,n22,n26,n27,n28,n29,n30 customIcon
Problemet: offboarding sker sent, och åtkomst blir kvar
Någon har sin sista dag och HR uppdaterar Odoo. Sedan börjar det riktiga jobbet. IT måste hitta rätt användare i GitLab, ta reda på vilka grupper och projekt personen varit inne i, låsa åtkomst och göra samma procedur i Redmine (och vad annat ni nu kör). Det är inte svårt arbete. Det är avbrottsdrivet arbete. Ett missat steg kan lämna ett konto aktivt långt efter att personen slutat, vilket är exakt så “liten risk” blir en säkerhetsincident du senare behöver förklara.
Friktionen byggs på. Några små förseningar i några system är så offboarding glider.
- HR och IT jobbar ofta utifrån olika “sanningar”, så slutdatum dubbelkollas och skrivs in på nytt.
- Borttag av GitLab-åtkomst är lätt att skjuta upp eftersom det ser “snabbt” ut, och sedan blir det inte gjort.
- Redmine-medlemskap och grupper är pilliga, så man stänger av kontot men glömmer resten.
- När en revisor ber om bevis får du återskapa åtgärder från minnet och ofullständiga loggar.
Lösningen: dagliga Odoo-kontroller som låser GitLab och loggar bevisen
Det här flödet körs schemalagt (tänk: vardagar kl. 17), hämtar posterna som “slutar idag” från Odoo 18 och filtrerar ner till faktiska offboarding-mål med giltig anställningsinformation. För varje person hämtar det jobbmejlen, slår upp motsvarande Redmine-användare, låser kontot, rensar Redmine-grupper och tar bort projektmedlemskap så att de inte behåller åtkomst via kvarvarande kopplingar. Sedan söker det i GitLab efter samma person, bekräftar att kontot finns, kontrollerar att det inte redan är blockerat eller bannat och blockerar det. Till sist skriver det resultatet till Google Sheets så att du har ett strukturerat revisionsspår även när något misslyckas och behöver köras om.
Flödet börjar med Odoo-data för kontrakt/uppsägning och slutar med låsta konton plus en logg du kan lämna till Security eller Compliance. Det gör också “ingenting” på ett snyggt sätt när det inte finns några som ska avslutas, så teamet slipper spammas med tomma larm.
Det du får: automation kontra resultat
| Vad det här flödet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut i praktiken
Säg att du offboardar 4 personer en vanlig månad. Manuellt tar en noggrann körning ofta 20 minuter per person i GitLab (hitta användare, bekräfta identitet, blockera, dubbelkolla) plus ytterligare 20 minuter i Redmine (låsa, rensa grupper, ta bort medlemskap), så totalt ungefär 3 timmar per månad. Med det här flödet är “arbetet” i princip noll: du lägger kanske 10 minuter en gång i månaden på att snabbt kika i Google Sheet och följa upp endast på fel. Offboardingen sker enligt schema, även när teamet är fullt upp.
Det här behöver du
- n8n-instans (testa n8n Cloud gratis)
- Self-hosting-alternativ om du föredrar det (Hostinger fungerar bra)
- Odoo 18 för slutdatum och status på medarbetare.
- GitLab för att blockera användare via admin-token.
- Redmine API-nyckel (hämtas i Redmine admininställningar för API).
Kunskapsnivå: Medel. Du klistrar in API-tokens, bekräftar några endpoints och testar med en medarbetarpost.
Vill du inte sätta upp detta själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
En schemalagd kontroll körs automatiskt. Flödet triggas på ett tidsschema (oftast vardagar sent på eftermiddagen) och räknar sedan ut dagens datum så att “slutar idag” alltid bedöms korrekt.
Odoo frågas efter uppsägnings-/kontraktsslut. Det hämtar relevanta medarbetare, filtrerar bort tomma resultat och behåller bara giltiga poster så att du inte lägger tid på ofullständiga eller inaktuella uppgifter.
Kontohantering sker per medarbetare. n8n itererar genom listan, hämtar Odoo-information, plockar ut jobbmejlen och använder den för att hitta användaren i Redmine och GitLab. Redmine låses, grupper rensas och medlemskap tas bort; GitLab-konton kontrolleras för status och blockeras bara när det är lämpligt.
Allt registreras för uppföljning. Resultaten loggas till Google Sheets, vilket gör att du snabbt kan se vem som behandlats, vad som blockerats och vad som kräver manuell insats om ett API-anrop misslyckades.
Du kan enkelt ändra schematiden så att den matchar er policy för avslutsdagen. Se hela implementationsguiden nedan för anpassningsalternativ.
Steg-för-steg-guide för implementering
Steg 1: konfigurera schematriggern
Det här arbetsflödet startar enligt ett veckoschema och beräknar aktuellt datum innan några API-anrop görs.
- Lägg till noden Timed Schedule Starter och ställ in schemaregeln till vardagar med Trigger at hour
{{ 17 }}och Trigger at minute{{ 0 }}. - Koppla Timed Schedule Starter till Compute Current Date.
- I Compute Current Date behåller ni den angivna JavaScript-koden som returnerar
dateochdayOfWeek. - Koppla Compute Current Date till Assign Base Settings.
Steg 2: anslut basinställningar och API-endpoints
Definiera centrala URL:er och gränser som används av alla efterföljande HTTP-anrop.
- I Assign Base Settings ställer ni JSON Output till det råa objektet och uppdaterar värden för
redmine6_Url,odooUrl,web_search_read_api,web_read_apiochgitlab_Url. - Sätt limit till
100(eller ändra vid behov för er Odoo-paginering). - Bekräfta kopplingsflödet: Assign Base Settings → Retrieve Resignation Records.
redmine6_Url eller gitlab_Url om inte ert API förväntar sig dem; noderna lägger till sina egna sökvägar.Steg 3: hämta och filtrera uppsägningsposter
Det här avsnittet hämtar uppsägningsposter från Odoo och filtrerar fram förväntade avslöjandedatum som matchar idag.
- Konfigurera Retrieve Resignation Records med angiven POST-body och säkerställ att JSON Body inkluderar
{{ $node['Assign Base Settings'].json.limit }}för gränsen. - Inloggningsuppgifter krävs: Anslut era httpHeaderAuth-uppgifter till Retrieve Resignation Records.
- I Check Nonzero Results behåller ni villkoret
{{ $json.result.length }}är inte lika med{{ 0 }}. - I Filter Valid Records behåller ni JavaScript-koden som filtrerar bort tillstånden
draftochcanceloch mappar till medarbetar-id:n. - I Verify Records Present behåller ni kontrollen för tomt objekt på
{{ $json }}för att välja mellan Alternate Finish eller Iterate Employee List.
Steg 4: iterera medarbetare och extrahera arbetsmejl
Varje medarbetar-id expanderas till Odoo-detaljer, och därefter parsas e-postadressen för vidare användning.
- Använd Iterate Employee List för att loopa igenom varje medarbetar-id som returneras av Filter Valid Records.
- Konfigurera Fetch Odoo Employee Info med angiven POST-body och behåll uttrycket
{{ $json.id }}inuti args. - Inloggningsuppgifter krävs: Anslut era httpHeaderAuth-uppgifter till Fetch Odoo Employee Info.
- I Extract Work Email behåller ni JavaScript-koden som delar upp arbetsmejlen i
work_emailochusername. - Bekräfta flödet: Fetch Odoo Employee Info → Extract Work Email → Retrieve Redmine User.
Steg 5: lås och rensa Redmine-åtkomst
Det här avsnittet verifierar en matchande Redmine-användare, låser kontot, tar bort grupper och rensar projektmedlemskap.
- I Retrieve Redmine User behåller ni URL-uttrycket
{{ $node['Assign Base Settings'].json.redmine6_Url}}users.json?name={{ $node['Extract Work Email'].json.work_email }}. - Inloggningsuppgifter krävs: Anslut era httpHeaderAuth-uppgifter till alla Redmine HTTP-noder: Retrieve Redmine User, Lock Redmine Account, Clear Redmine Groups, Get Redmine Memberships och Remove Project Membership.
- I Confirm Redmine Match behåller ni villkoret
{{ $json.total_count }}är lika med{{ 1 }}. - I Lock Redmine Account behåller ni JSON Body som
{"user": {"status": 3}}. - I Clear Redmine Groups behåller ni JSON Body med tomma
group_idsoch kopplar den till Get Redmine Memberships. - I Map Membership IDs behåller ni JavaScript-koden som mappar medlemskaps-id:n, och använder sedan Iterate Membership IDs och Remove Project Membership för att ta bort varje medlemskap.
- Bekräfta att loopen stängs: Iterate Membership IDs → Continue Loop Signal → Lookup GitLab User.
Steg 6: blockera GitLab-användare när det är aktuellt
Arbetsflödet kontrollerar att GitLab-användaren finns och vilket tillstånd den har innan blockering. Två liknande GitLab-vägar körs för säkerhets skull.
- I Lookup GitLab User behåller ni URL-uttrycket
{{ $node['Assign Base Settings'].json.gitlab_Url}}api/v4/users?search={{ $node['Extract Work Email'].json.username }}. - I Validate GitLab Hit behåller ni kontrollen för ej tomt på
{{ $node['Lookup GitLab User'].json }}, och skickar sedan vidare till Ensure Not Blocked och Ensure Not Banned med villkoren=blockedoch=banned. - I Block GitLab User behåller ni URL-uttrycket
{{ $node['Assign Base Settings'].json.gitlab_Url}}api/v4/users/{{ $node['Validate GitLab Hit'].json.id}}/block. - Upprepa samma konfiguration för Lookup GitLab User 2, Validate GitLab Hit 2, Ensure Not Blocked 2, Ensure Not Banned 2 och Block GitLab User 2.
- Inloggningsuppgifter krävs: Anslut era httpHeaderAuth-uppgifter till alla GitLab HTTP-noder: Lookup GitLab User, Block GitLab User, Lookup GitLab User 2 och Block GitLab User 2.
blocked eller banned, vilket förhindrar onödiga API-anrop.Steg 7: testa och aktivera ert arbetsflöde
Validera hela offboarding-flödet och aktivera därefter schemat för produktion.
- Klicka på Execute Workflow för att köra arbetsflödet manuellt från Timed Schedule Starter.
- Verifiera att Retrieve Resignation Records returnerar resultat och att Filter Valid Records skickar ut medarbetar-id:n för idag.
- Bekräfta att Redmine-åtgärderna lyckas genom att kontrollera att Lock Redmine Account och Clear Redmine Groups slutförs utan fel, och att Remove Project Membership körs för varje medlemskap.
- Bekräfta GitLab-blockering via svaren från Block GitLab User och Block GitLab User 2.
- När testerna lyckas, växla arbetsflödet till Active så att Timed Schedule Starter kör enligt det definierade schemat.
Vanliga fallgropar
- Odoo-inloggning kan löpa ut eller kräva specifika behörigheter. Om det slutar fungera, kontrollera först åtkomsträttigheter för din Odoo API-användare och att token fortfarande är giltig.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om noder längre fram misslyckas på tomma svar.
- Standardprompter i AI-noder är generiska. Lägg in er tonalitet tidigt, annars kommer du att redigera utdata i all evighet.
Vanliga frågor
Cirka en timme om du redan har API-tokens.
Nej. Du kopplar mest konton och klistrar in inloggningsuppgifter i n8n. Du kan behöva justera ett par API-fält om er GitLab- eller Odoo-installation är anpassad.
Ja. n8n har ett gratis self-hosted-alternativ och en gratis provperiod i n8n Cloud. Cloud-planer börjar på $20/månad för högre volymer. Du behöver också räkna in API-åtkomst för Odoo, GitLab och Redmine (oftast ingår det i det du redan betalar för de verktygen).
Två alternativ: n8n Cloud (managerat, enklast att komma igång) eller self-hosting på en VPS. För self-hosting är Hostinger VPS prisvärd och hanterar n8n bra. Self-hosting ger dig obegränsade körningar men kräver grundläggande serverhantering.
Ja, och det är en vanlig uppgradering. Du duplicerar det befintliga mönstret för HTTP Request som används för “Slå upp GitLab-användare” och “Blockera GitLab-användare”, och byter sedan endpoints och inloggningsuppgifter till Jira eller Confluence. De flesta team anpassar också schemat (slutet av dagen vs. mitt på dagen), lägger till en “chefsgodkännande”-flagga från Odoo och byter loggning från Google Sheets till en databas.
Oftast är det ett problem med admin-token: utgången token, fel scope eller att token saknar behörighet att blockera användare. Det kan också fallera eftersom flödet söker på mejl/användarnamn och att dina GitLab-kontodata inte matchar det som finns lagrat i Odoo. Om du offboardar flera personer samtidigt kan även rate limiting dyka upp, vilket ser ut som slumpmässiga fel. Kontrollera exekveringsloggarna för specifik HTTP-statuskod och response body, och åtgärda det först innan du rör resten av flödet.
Några hundra per dag är realistiskt för de flesta upplägg, eftersom den hanterar medarbetare i batchar och hoppar över alla som redan är blockerade.
Ofta, ja, eftersom offboarding kräver förgreningslogik, omförsök och skydd som “kontrollera innan du blockerar”. n8n klarar det utan att bli en hög med separata Zaps eller scenarier, och self-hosting kan göra körningar med hög volym prisvärda. Zapier eller Make kan fungera för en enkel “skicka en avisering när slutdatum är idag”, men blir klumpiga när du lägger till avprovisionering i flera system. Om du är osäker, prata med en automationsexpert och beskriv era verktyg och er offboardingpolicy.
Offboarding är en av de där processerna du bara märker när något går fel. Sätt upp detta en gång, så slutar åtkomstkontroll på avslutsdagen att vara en återkommande brandövning.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.