[{"data":1,"prerenderedAt":990},["ShallowReactive",2],{"/de-de/blog/categories/engineering/page/5":3,"navigation-de-de":20,"banner-de-de":456,"footer-de-de":463,"engineering-category-page-total-items-de-de":720,"engineering-category-page-featured-de-de":721,"engineering-category-page-5-de-de":967},{"id":4,"title":5,"body":6,"category":6,"config":7,"content":11,"description":6,"extension":12,"meta":13,"navigation":14,"path":15,"seo":16,"slug":6,"stem":18,"testContent":6,"type":6,"__hash__":19},"blogCategories/de-de/blog/categories/engineering.yml","Engineering",null,{"template":8,"slug":9,"hide":10},"BlogCategory","engineering",false,{"name":5},"yml",{},true,"/de-de/blog/categories/engineering",{"title":5,"description":17},"Browse articles related to Engineering on the GitLab Blog","de-de/blog/categories/engineering","2aDT2ddISb3_jPr0pKFELw8NlkxcUsQZ7Dd93XB3ya8",{"logo":21,"freeTrial":26,"sales":31,"login":36,"items":41,"search":372,"minimal":407,"duo":426,"switchNav":435,"pricingDeployment":446},{"config":22},{"href":23,"dataGaName":24,"dataGaLocation":25},"/de-de/","gitlab logo","header",{"text":27,"config":28},"Kostenlose Testversion anfordern",{"href":29,"dataGaName":30,"dataGaLocation":25},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de&glm_content=default-saas-trial/","free trial",{"text":32,"config":33},"Demo anfordern",{"href":34,"dataGaName":35,"dataGaLocation":25},"/request-a-demo/","sales",{"text":37,"config":38},"Anmelden",{"href":39,"dataGaName":40,"dataGaLocation":25},"https://gitlab.com/users/sign_in/","sign in",[42,128,216,221,296,350],{"text":43,"left":14,"config":44,"menu":46},"Plattform",{"dataNavLevelOne":45},"platform",{"type":47,"link":48,"columns":52,"feature":117},"lists",{"text":49,"config":50},"Die Plattform erkunden",{"href":51,"dataGaName":45,"dataGaLocation":25},"/de-de/platform/",[53,76,99],{"title":54,"items":55},"Ausführung und Workflows",[56,61,66,71],{"text":57,"config":58},"CI/CD",{"href":59,"dataGaLocation":25,"dataGaName":60},"/de-de/solutions/continuous-integration/","ci/cd",{"text":62,"config":63},"Quellcodeverwaltung",{"href":64,"dataGaLocation":25,"dataGaName":65},"/de-de/solutions/source-code-management/","source code management",{"text":67,"config":68},"Agile Delivery",{"href":69,"dataGaLocation":25,"dataGaName":70},"/de-de/solutions/agile-delivery/","agile delivery",{"text":72,"config":73},"Artefaktverwaltung",{"href":74,"dataGaLocation":25,"dataGaName":75},"/de-de/artifact-central/","artifact management",{"title":77,"items":78},"Sicherheit und Governance",[79,84,89,94],{"text":80,"config":81},"Anwendungssicherheitstests",{"href":82,"dataGaLocation":25,"dataGaName":83},"/de-de/solutions/application-security-testing/","application security testing",{"text":85,"config":86},"Governance und Compliance",{"href":87,"dataGaLocation":25,"dataGaName":88},"/de-de/solutions/software-compliance/","governance and compliance",{"text":90,"config":91},"Secrets-Management",{"href":92,"dataGaLocation":25,"dataGaName":93},"/de-de/gitlab-secrets-manager/","secrets management",{"text":95,"config":96},"Lieferkettensicherheit",{"href":97,"dataGaLocation":25,"dataGaName":98},"/de-de/solutions/supply-chain/","supply chain security",{"title":100,"items":101},"Kontext und KI",[102,107,112],{"text":103,"config":104},"Agentische Orchestrierung",{"href":105,"dataGaLocation":25,"dataGaName":106},"/de-de/gitlab-duo-agent-platform/","agentic orchestration",{"text":108,"config":109},"Kontextgraph",{"href":110,"dataGaLocation":25,"dataGaName":111},"/de-de/gitlab-orbit/","context graph",{"text":113,"config":114},"Sichtbarkeit und Messung",{"href":115,"dataGaLocation":25,"dataGaName":116},"/de-de/solutions/visibility-measurement/","visibility and measurement",{"config":118,"title":121,"text":122,"link":123},{"background":119,"textColor":120},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1790185102/o7dn32anqcb6z8dgd3as.jpg')","#000","Warum GitLab","Eine Plattform für Schnelligkeit und Kontrolle im gesamten Software-Lebenszyklus.",{"text":124,"config":125},"Mehr erfahren",{"href":126,"dataGaName":127,"dataGaLocation":25},"/de-de/why-gitlab/","why gitlab",{"text":129,"left":14,"config":130,"menu":132},"Lösungen",{"dataNavLevelOne":131},"solutions",{"type":47,"link":133,"columns":137,"feature":207},{"text":134,"config":135},"Alle Lösungen anzeigen",{"href":136,"dataGaName":131,"dataGaLocation":25},"/de-de/solutions/",[138,156,174],{"title":139,"items":140},"Ergebnisse",[141,146,151],{"text":142,"config":143},"DevOps-Modernisierung",{"href":144,"dataGaLocation":25,"dataGaName":145},"/de-de/assessments/devops-modernization-assessment/","devops modernization",{"text":147,"config":148},"Sicherheitsmodernisierung",{"href":149,"dataGaLocation":25,"dataGaName":150},"/de-de/assessments/security-modernization-assessment/","security modernization",{"text":152,"config":153},"KI-Modernisierung",{"href":154,"dataGaLocation":25,"dataGaName":155},"/de-de/assessments/ai-modernization-assessment/","ai modernization",{"title":157,"items":158},"Nach Größe",[159,164,169],{"text":160,"config":161},"Große Unternehmen",{"href":162,"dataGaLocation":25,"dataGaName":163},"/de-de/enterprise/","enterprise",{"text":165,"config":166},"Kleine Unternehmen",{"href":167,"dataGaLocation":25,"dataGaName":168},"/de-de/small-business/","small business",{"text":170,"config":171},"Start-ups",{"href":172,"dataGaLocation":25,"dataGaName":173},"/de-de/solutions/startups/","startups",{"title":175,"items":176},"Branchen",[177,182,187,192,197,202],{"text":178,"config":179},"Finanzdienstleistungen",{"href":180,"dataGaLocation":25,"dataGaName":181},"/de-de/solutions/finance/","financial services",{"text":183,"config":184},"Öffentlicher Sektor",{"href":185,"dataGaLocation":25,"dataGaName":186},"/de-de/solutions/public-sector/","public sector",{"text":188,"config":189},"Telekommunikation",{"href":190,"dataGaLocation":25,"dataGaName":191},"/de-de/solutions/telecommunications/","telecommunications",{"text":193,"config":194},"Automobilindustrie",{"href":195,"dataGaLocation":25,"dataGaName":196},"/de-de/solutions/automotive/","automotive",{"text":198,"config":199},"Bildungswesen",{"href":200,"dataGaLocation":25,"dataGaName":201},"/de-de/solutions/education/","education",{"text":203,"config":204},"Luft- und Raumfahrt",{"href":205,"dataGaLocation":25,"dataGaName":206},"/de-de/solutions/aerospace/","aerospace",{"config":208,"title":209,"text":210,"link":211},{"background":119,"textColor":120},"GitLab-Sicherheitsstandard","Mehr dazu, wie du deine Software Factory stärkst und KI-Agenten Autonomie gewinnen lässt, ohne an Sicherheit einzubüßen.",{"text":212,"config":213},"Standard entdecken",{"href":214,"dataGaName":215,"dataGaLocation":25},"/gitlab-security-standard/","gitlab security standard",{"text":217,"config":218},"Preise",{"href":219,"dataGaName":220,"dataGaLocation":25,"dataNavLevelOne":220},"/de-de/pricing/","pricing",{"text":222,"config":223,"menu":225},"Ressourcen",{"dataNavLevelOne":224},"resources",{"type":47,"link":226,"columns":230,"feature":287},{"text":227,"config":228},"Alle Ressourcen anzeigen",{"href":229,"dataGaName":224,"dataGaLocation":25},"/de-de/resources/",[231,259],{"title":232,"items":233},"Entdecken",[234,239,244,249,254],{"text":235,"config":236},"Dokumentation",{"href":237,"dataGaName":238,"dataGaLocation":25},"https://docs.gitlab.com/","docs",{"text":240,"config":241},"GitLab University",{"href":242,"dataGaName":243,"dataGaLocation":25},"https://university.gitlab.com/","university",{"text":245,"config":246},"Demo-Reihe",{"href":247,"dataGaName":248,"dataGaLocation":25},"/de-de/gitlab-technical-demo-series/","demo series",{"text":250,"config":251},"Demo-Hub",{"href":252,"dataGaName":253,"dataGaLocation":25},"/de-de/demo-hub/","demo hub",{"text":255,"config":256},"Dienste",{"href":257,"dataGaName":258,"dataGaLocation":25},"/de-de/services/","services",{"title":260,"items":261},"Vernetzen",[262,267,272,277,282],{"text":263,"config":264},"Blog",{"href":265,"dataGaName":266,"dataGaLocation":25},"/de-de/blog/","blog",{"text":268,"config":269},"Community",{"href":270,"dataGaName":271,"dataGaLocation":25},"/community/","community",{"text":273,"config":274},"Kunden",{"href":275,"dataGaName":276,"dataGaLocation":25},"/de-de/customers/","customers",{"text":278,"config":279},"Partner",{"href":280,"dataGaName":281,"dataGaLocation":25},"/de-de/partners/","partners",{"text":283,"config":284},"Veranstaltungen",{"href":285,"dataGaName":286,"dataGaLocation":25},"/events/","events",{"config":288,"title":289,"text":290,"link":291},{"background":119,"textColor":120},"Neues bei GitLab","Über die neuesten Funktionen und Verbesserungen auf dem Laufenden bleiben.",{"text":292,"config":293},"Aktuelle Nachrichten",{"href":294,"dataGaName":295,"dataGaLocation":25},"/de-de/whats-new/","whats new",{"text":297,"config":298,"menu":300},"Unternehmen",{"dataNavLevelOne":299},"company",{"type":47,"columns":301},[302],{"items":303},[304,309,315,320,325,330,335,340,345],{"text":305,"config":306},"Über",{"href":307,"dataGaName":308,"dataGaLocation":25},"/de-de/company/","about",{"text":310,"config":311,"footerGa":314},"Karriere",{"href":312,"dataGaName":313,"dataGaLocation":25},"/jobs/","jobs",{"dataGaName":313},{"text":316,"config":317},"Presse",{"href":318,"dataGaName":319,"dataGaLocation":25},"/press/","press",{"text":321,"config":322},"Handbuch",{"href":323,"dataGaName":324,"dataGaLocation":25},"https://handbook.gitlab.com/","handbook",{"text":326,"config":327},"Geschäftsführung",{"href":328,"dataGaName":329,"dataGaLocation":25},"/company/team/e-group/","leadership",{"text":331,"config":332},"Investor Relations",{"href":333,"dataGaName":334,"dataGaLocation":25},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":336,"config":337},"Trust Center",{"href":338,"dataGaName":339,"dataGaLocation":25},"/de-de/security/","trust center",{"text":341,"config":342},"AI Transparency Center",{"href":343,"dataGaName":344,"dataGaLocation":25},"/de-de/ai-transparency-center/","ai transparency center",{"text":346,"config":347},"Newsletter",{"href":348,"dataGaName":349,"dataGaLocation":25},"/company/contact/#contact-forms","newsletter",{"text":351,"config":352,"menu":353},"Kontakt",{"dataNavLevelOne":299},{"type":47,"columns":354},[355],{"items":356},[357,362,367],{"text":358,"config":359},"Vertrieb kontaktieren",{"href":360,"dataGaName":361,"dataGaLocation":25},"/de-de/sales/","talk to sales",{"text":363,"config":364},"Support-Portal",{"href":365,"dataGaName":366,"dataGaLocation":25},"https://support.gitlab.com/hc/en-us","support portal",{"text":368,"config":369},"Kundenportal",{"href":370,"dataGaName":371,"dataGaLocation":25},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":373,"login":374,"suggestions":381},"Schließen",{"text":375,"link":376},"Um Repositorys und Projekte zu durchsuchen, melde dich an bei",{"text":377,"config":378},"gitlab.com",{"href":39,"dataGaName":379,"dataGaLocation":380},"search login","search",{"text":382,"default":383},"Vorschläge",[384,387,391,393,398,403],{"text":385,"config":386},"GitLab Duo Agent Platform",{"href":105,"dataGaName":385,"dataGaLocation":380},{"text":388,"config":389},"Codevorschläge (KI)",{"href":105,"dataGaName":390,"dataGaLocation":380},"Code Suggestions (AI)",{"text":57,"config":392},{"href":59,"dataGaName":57,"dataGaLocation":380},{"text":394,"config":395},"GitLab auf AWS",{"href":396,"dataGaName":397,"dataGaLocation":380},"/de-de/partners/technology-partners/aws/","GitLab on AWS",{"text":399,"config":400},"GitLab auf Google Cloud",{"href":401,"dataGaName":402,"dataGaLocation":380},"/de-de/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":404,"config":405},"Warum GitLab?",{"href":126,"dataGaName":406,"dataGaLocation":380},"Why GitLab?",{"freeTrial":408,"mobileIcon":413,"desktopIcon":418,"secondaryButton":421},{"text":409,"config":410},"Kostenlos testen",{"href":411,"dataGaName":30,"dataGaLocation":412},"https://gitlab.com/-/trials/new/","nav",{"altText":414,"config":415},"GitLab-Symbol",{"src":416,"dataGaName":417,"dataGaLocation":412},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":414,"config":419},{"src":420,"dataGaName":417,"dataGaLocation":412},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":422,"config":423},"Erste Schritte",{"href":424,"dataGaName":425,"dataGaLocation":412},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de/get-started/","get started",{"freeTrial":427,"mobileIcon":431,"desktopIcon":433},{"text":428,"config":429},"Mehr über GitLab Duo erfahren",{"href":105,"dataGaName":430,"dataGaLocation":412},"gitlab duo",{"altText":414,"config":432},{"src":416,"dataGaName":417,"dataGaLocation":412},{"altText":414,"config":434},{"src":420,"dataGaName":417,"dataGaLocation":412},{"button":436,"mobileIcon":441,"desktopIcon":443},{"text":437,"config":438},"/Option",{"href":439,"dataGaName":440,"dataGaLocation":412},"#contact","switch",{"altText":414,"config":442},{"src":416,"dataGaName":417,"dataGaLocation":412},{"altText":414,"config":444},{"src":445,"dataGaName":417,"dataGaLocation":412},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":447,"mobileIcon":452,"desktopIcon":454},{"text":448,"config":449},"Zurück zur Preisübersicht",{"href":219,"dataGaName":450,"dataGaLocation":412,"icon":451},"back to pricing","GoBack",{"altText":414,"config":453},{"src":416,"dataGaName":417,"dataGaLocation":412},{"altText":414,"config":455},{"src":420,"dataGaName":417,"dataGaLocation":412},{"title":457,"button":458,"config":461},"GitLab Orbit ist da: die Kontextebene für KI-Agenten",{"text":124,"config":459},{"href":110,"dataGaName":460,"dataGaLocation":25},"orbit",{"layout":462,"disabled":10},"release",{"data":464},{"text":465,"source":466,"edit":472,"contribute":477,"config":482,"items":487,"minimal":709},"Git ist eine Marke von Software Freedom Conservancy und unsere Verwendung von „GitLab“ erfolgt unter Lizenz.",{"text":467,"config":468},"Quelltext der Seite anzeigen",{"href":469,"dataGaName":470,"dataGaLocation":471},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":473,"config":474},"Diese Seite bearbeiten",{"href":475,"dataGaName":476,"dataGaLocation":471},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":478,"config":479},"Beteilige dich",{"href":480,"dataGaName":481,"dataGaLocation":471},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":483,"facebook":484,"youtube":485,"linkedin":486},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[488,533,591,634,676],{"title":217,"links":489,"subMenu":504},[490,494,499],{"text":491,"config":492},"Tarife anzeigen",{"href":219,"dataGaName":493,"dataGaLocation":471},"view plans",{"text":495,"config":496},"Vorteile von Premium",{"href":497,"dataGaName":498,"dataGaLocation":471},"/de-de/pricing/premium/","why premium",{"text":500,"config":501},"Vorteile von Ultimate",{"href":502,"dataGaName":503,"dataGaLocation":471},"/de-de/pricing/ultimate/","why ultimate",[505],{"title":351,"links":506},[507,509,511,513,518,523,528],{"text":358,"config":508},{"href":360,"dataGaName":35,"dataGaLocation":471},{"text":363,"config":510},{"href":365,"dataGaName":366,"dataGaLocation":471},{"text":368,"config":512},{"href":370,"dataGaName":371,"dataGaLocation":471},{"text":514,"config":515},"Status",{"href":516,"dataGaName":517,"dataGaLocation":471},"https://status.gitlab.com/","status",{"text":519,"config":520},"Nutzungsbedingungen",{"href":521,"dataGaName":522,"dataGaLocation":471},"/terms/","terms of use",{"text":524,"config":525},"Datenschutzerklärung",{"href":526,"dataGaName":527,"dataGaLocation":471},"/de-de/privacy/","privacy statement",{"text":529,"config":530},"Cookie-Einstellungen",{"dataGaName":531,"dataGaLocation":471,"id":532,"isOneTrustButton":14},"cookie preferences","ot-sdk-btn",{"title":43,"links":534,"subMenu":548},[535,538,540,542,544,546],{"text":536,"config":537},"Plattform entdecken",{"href":51,"dataGaName":45,"dataGaLocation":471},{"text":103,"config":539},{"href":105,"dataGaName":106,"dataGaLocation":471},{"text":57,"config":541},{"href":59,"dataGaName":60,"dataGaLocation":471},{"text":108,"config":543},{"href":110,"dataGaName":111,"dataGaLocation":471},{"text":90,"config":545},{"href":92,"dataGaName":93,"dataGaLocation":471},{"text":121,"config":547},{"href":126,"dataGaName":127,"dataGaLocation":471},[549],{"title":550,"links":551},"Themen",[552,556,561,566,571,576,581,586],{"text":57,"config":553},{"href":554,"dataGaName":555,"dataGaLocation":471},"/de-de/topics/ci-cd/","cicd",{"text":557,"config":558},"GitOps",{"href":559,"dataGaName":560,"dataGaLocation":471},"/de-de/topics/gitops/","gitops",{"text":562,"config":563},"DevOps",{"href":564,"dataGaName":565,"dataGaLocation":471},"/de-de/topics/devops/","devops",{"text":567,"config":568},"Versionskontrolle",{"href":569,"dataGaName":570,"dataGaLocation":471},"/de-de/topics/version-control/","version control",{"text":572,"config":573},"DevSecOps",{"href":574,"dataGaName":575,"dataGaLocation":471},"/de-de/topics/devsecops/","devsecops",{"text":577,"config":578},"Cloud-nativ",{"href":579,"dataGaName":580,"dataGaLocation":471},"/de-de/topics/cloud-native/","cloud native",{"text":582,"config":583},"KI für das Programmieren",{"href":584,"dataGaName":585,"dataGaLocation":471},"/de-de/topics/devops/ai-for-coding/","ai for coding",{"text":587,"config":588},"Agentische KI",{"href":589,"dataGaName":590,"dataGaLocation":471},"/de-de/topics/agentic-ai/","agentic ai",{"title":129,"links":592},[593,595,597,599,601,603,605,607,609,611,614,617,619,622,626,630],{"text":142,"config":594},{"href":144,"dataGaName":145,"dataGaLocation":471},{"text":147,"config":596},{"href":149,"dataGaName":150,"dataGaLocation":471},{"text":152,"config":598},{"href":154,"dataGaName":155,"dataGaLocation":471},{"text":178,"config":600},{"href":180,"dataGaName":181,"dataGaLocation":471},{"text":183,"config":602},{"href":185,"dataGaName":186,"dataGaLocation":471},{"text":188,"config":604},{"href":190,"dataGaName":191,"dataGaLocation":471},{"text":193,"config":606},{"href":195,"dataGaName":196,"dataGaLocation":471},{"text":198,"config":608},{"href":200,"dataGaName":201,"dataGaLocation":471},{"text":203,"config":610},{"href":205,"dataGaName":206,"dataGaLocation":471},{"text":612,"config":613},"Enterprise",{"href":162,"dataGaName":163,"dataGaLocation":471},{"text":615,"config":616},"Kleinunternehmen",{"href":167,"dataGaName":168,"dataGaLocation":471},{"text":170,"config":618},{"href":172,"dataGaName":173,"dataGaLocation":471},{"text":557,"config":620},{"href":621,"dataGaName":560,"dataGaLocation":471},"/de-de/solutions/gitops/",{"text":623,"config":624},"Analyse der Softwarezusammensetzung (SCA)",{"href":97,"dataGaName":625,"dataGaLocation":471},"software composition analysis",{"text":627,"config":628},"Wertstrommanagement",{"href":115,"dataGaName":629,"dataGaLocation":471},"value stream management",{"text":631,"config":632},"Alle Lösungen",{"href":136,"dataGaName":633,"dataGaLocation":471},"all solutions",{"title":222,"links":635},[636,641,646,648,650,652,654,656,658,660,663,665,667,669,672],{"text":637,"config":638},"Installieren",{"href":639,"dataGaName":640,"dataGaLocation":471},"/de-de/install/","install",{"text":642,"config":643},"Kurzanleitungen",{"href":644,"dataGaName":645,"dataGaLocation":471},"/de-de/get-started/","quick setup checklists",{"text":235,"config":647},{"href":237,"dataGaName":238,"dataGaLocation":471},{"text":240,"config":649},{"href":242,"dataGaName":243,"dataGaLocation":471},{"text":245,"config":651},{"href":247,"dataGaName":248,"dataGaLocation":471},{"text":250,"config":653},{"href":252,"dataGaName":253,"dataGaLocation":471},{"text":255,"config":655},{"href":257,"dataGaName":258,"dataGaLocation":471},{"text":263,"config":657},{"href":265,"dataGaName":266,"dataGaLocation":471},{"text":268,"config":659},{"href":270,"dataGaName":271,"dataGaLocation":471},{"text":661,"config":662},"Kund(inn)en",{"href":275,"dataGaName":276,"dataGaLocation":471},{"text":278,"config":664},{"href":280,"dataGaName":281,"dataGaLocation":471},{"text":283,"config":666},{"href":285,"dataGaName":286,"dataGaLocation":471},{"text":346,"config":668},{"href":348,"dataGaName":349,"dataGaLocation":471},{"text":670,"config":671},"Neuerungen",{"href":294,"dataGaName":295,"dataGaLocation":471},{"text":673,"config":674},"Alle Ressourcen",{"href":229,"dataGaName":675,"dataGaLocation":471},"all resources",{"title":297,"links":677},[678,680,682,684,686,688,690,692,694,699,704],{"text":305,"config":679},{"href":307,"dataGaName":299,"dataGaLocation":471},{"text":310,"config":681},{"href":312,"dataGaName":313,"dataGaLocation":471},{"text":316,"config":683},{"href":318,"dataGaName":319,"dataGaLocation":471},{"text":321,"config":685},{"href":323,"dataGaName":324,"dataGaLocation":471},{"text":326,"config":687},{"href":328,"dataGaName":329,"dataGaLocation":471},{"text":331,"config":689},{"href":333,"dataGaName":334,"dataGaLocation":471},{"text":336,"config":691},{"href":338,"dataGaName":339,"dataGaLocation":471},{"text":341,"config":693},{"href":343,"dataGaName":344,"dataGaLocation":471},{"text":695,"config":696},"Nachhaltigkeit",{"href":697,"dataGaName":698,"dataGaLocation":471},"/sustainability/","Sustainability",{"text":700,"config":701},"Vielfalt, Inklusion und Zugehörigkeit",{"href":702,"dataGaName":703,"dataGaLocation":471},"/de-de/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":705,"config":706},"Transparenzerklärung zu moderner Sklaverei",{"href":707,"dataGaName":708,"dataGaLocation":471},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":710},[711,714,717],{"text":712,"config":713},"Terms",{"href":521,"dataGaName":522,"dataGaLocation":471},{"text":715,"config":716},"Cookies",{"dataGaName":531,"dataGaLocation":471,"id":532,"isOneTrustButton":14},{"text":718,"config":719},"Datenschutz",{"href":526,"dataGaName":527,"dataGaLocation":471},40,{"id":722,"title":723,"authors":724,"body":726,"category":9,"date":952,"description":953,"extension":954,"externalUrl":6,"faq":6,"featured":10,"heroImage":955,"meta":956,"navigation":14,"path":957,"seo":958,"slug":962,"stem":963,"tags":964,"template":965,"updatedDate":6,"__hash__":966},"blogPosts/de-de/blog/module-level-access-in-a-django-grc-app.md","Zwei Eingangstüren: Zugriffskontrolle auf Modulebene in Django",[725],"Donovan Felton",{"type":727,"value":728,"toc":942},"minimark",[729,746,749,754,762,767,770,773,777,780,783,786,790,799,808,812,823,829,848,853,868,871,875,878,881,884,910,914],[730,731,732,733,739,740,745],"p",{},"Das Engineering-Team von GitLab entwickelt viele interne Werkzeuge selbst. Bei einer Plattform mussten wir jedoch grundlegend neu überlegen, wie wir Autorisierung umsetzen: bei unserem internen ",[734,735,738],"a",{"href":736,"rel":737},"https://about.gitlab.com/de-de/blog/compliance-management/",[],"GRC-Tool (Governance, Risk and Compliance)",". Es bedient unter einem Dach zwei sehr unterschiedliche Zielgruppen, das ",[734,741,744],{"href":742,"rel":743},"https://about.gitlab.com/de-de/blog/how-gitlab-built-a-security-control-framework-from-scratch/",[],"Security-Compliance-Team"," und das Internal-Audit-Team.",[730,747,748],{},"Dieser Beitrag richtet sich an alle, die ein internes Django-Tool bauen oder pflegen, das nach und nach mehr als eine Zielgruppe bedient: verschiedene Teams, verschiedene Datenklassifizierungen, Daten, die sich nicht vermischen dürfen. Er beschreibt das Problem, auf das wir gestoßen sind, wie wir es gelöst haben und wie sich das Muster auf die eigene App übertragen lässt.",[750,751,753],"h2",{"id":752},"die-herausforderung","Die Herausforderung",[730,755,756,757,761],{},"Unser ursprüngliches Tool war eine einzelne Django-App für das Security-Compliance-Team, mit ",[758,759,760],"code",{},"login_required"," in jeder View. Damit lagen wir richtig, bis Internal Audit einen neuen Anwendungsfall für das Tool fand: einen komplett eigenen Workflow mit eigenen Daten, eigenen Models und eigenen sensiblen Informationen, die Security Compliance nicht sehen sollte.",[730,763,764,766],{},[758,765,760],{}," beantwortet genau eine Frage: Ist die Person angemeldet? Die Frage, auf die es in einem internen Tool für mehrere Teams eigentlich ankommt, beantwortet es nicht: Darf die Person das hier sehen? Eine angemeldete Person aus Security Compliance, die eine URL von Internal Audit aufrief, spazierte einfach an der Login-Prüfung vorbei und landete bei Daten, die sie nie hätte sehen dürfen.",[730,768,769],{},"Wenn eine App nachträglich eine zweite Zielgruppe bekommen hat, klingt das vermutlich vertraut. Eine einfache Gegenprobe: Prüft jede View der App, wer die Person ist, oder nur, ob sie angemeldet ist? Trifft Letzteres zu, klafft wahrscheinlich dieselbe Lücke wie bei uns.",[730,771,772],{},"Wir brauchten eine saubere Trennung. Nicht \"diesen Button bitte einfach ignorieren\", sondern eine verbindliche Grenze, die hält, egal welche URL jemand eintippt.",[750,774,776],{"id":775},"die-architekturentscheidung","Die Architekturentscheidung",[730,778,779],{},"Als der Anwendungsfall von Internal Audit auf unserer Roadmap landete, standen wir vor der klassischen Wahl: an die bestehende App anbauen oder umstrukturieren? Wir haben umstrukturiert.",[730,781,782],{},"Das Ergebnis ist ein zentrales Django-Projekt (Core) mit gemeinsamer Authentifizierung, Nutzerverwaltung, Audit-Logging und grundlegenden UI-Komponenten. Darauf setzen zwei unabhängige Modul-Apps auf, eine für Security Compliance und eine für Internal Audit. Jedes Modul besitzt eigene Models, Views und eigene API-Endpunkte.",[730,784,785],{},"Den Kern bildet eine selbst auferlegte Regel: Core weiß nichts von den Daten aus Compliance oder Internal Audit. Beide Module dürfen von Core abhängen. Keines der Module darf vom anderen abhängen. Diese Regel verhindert, dass am Ende zwei Apps herauskommen, die nur mit Klebeband und Sekundenkleber zusammenhalten.",[750,787,789],{"id":788},"die-zugriffskontrolle","Die Zugriffskontrolle",[730,791,792,793,798],{},"Als Compliance-Engineering-Team bauen wir ein Tool, in dem sensible Compliance- und Risikodaten liegen. Nachlässige ",[734,794,797],{"href":795,"rel":796},"https://about.gitlab.com/de-de/blog/automating-role-based-access-control-rbac-at-scale/",[],"Zugriffskontrolle"," wäre hier nicht nur ein Bug, sondern ein ernstes Glaubwürdigkeitsproblem.",[730,800,801,802,807],{},"Unsere Entscheidung fiel auf etwas, das Django bereits mitbringt: das eingebaute Auth-System. Jedes Modul entspricht genau einer Gruppe. Eine Person kann einer Gruppe angehören, beiden oder keiner, und das System setzt die passende ",[734,803,806],{"href":804,"rel":805},"https://about.gitlab.com/de-de/blog/finserv-how-to-implement-gitlabs-separation-of-duties-features/",[],"Funktionstrennung"," auf jeder Ebene durch, ganz gleich, welche Kombination zutrifft. Navigation, Django-Views und REST-API prüfen die Gruppenzugehörigkeit jeweils unabhängig voneinander.",[750,809,811],{"id":810},"die-umsetzung","Die Umsetzung",[730,813,814,815,818,819,822],{},"In Core gibt es eine einzige wiederverwendbare Klasse, von der beide Module erben: ",[758,816,817],{},"GroupRequiredMixin",". Die Klasse prüft die Gruppenzugehörigkeit und wirft ",[758,820,821],{},"PermissionDenied",", wenn die Person nicht zur geforderten Gruppe gehört.",[730,824,825],{},[826,827,828],"strong",{},"Unterklassen auf Modulebene",[730,830,831,832,835,836,839,840,843,844,847],{},"Jedes Modul erhält eine dreizeilige Unterklasse, die ",[758,833,834],{},"required_group_name"," setzt: ein ",[758,837,838],{},"GasGroupRequiredMixin"," und ein ",[758,841,842],{},"IsGasGroupMember"," für Security Compliance (",[758,845,846],{},"Gas"," ist ein interner Gruppenname aus unserem Code), nach demselben Muster auch für Internal Audit. Mehr kostet die Durchsetzungsschicht eines Moduls nicht: eine neue Datei, ein neues Attribut. Die eigentliche Prüflogik liegt in Core und muss nie wieder angefasst werden.",[730,849,850],{},[826,851,852],{},"Die UI-Schicht",[730,854,855,856,859,860,863,864,867],{},"Schließlich gibt es den Template-Filter ",[758,857,858],{},"user_in_group",", damit die Navigation nur anzeigt, was eine Person tatsächlich sehen darf. Jeder Navigationsblock, der nur für Mitglieder einer bestimmten Gruppe erscheinen soll, wird dafür in eine Prüfung wie ",[758,861,862],{},"user|user_in_group:'erm'"," eingebettet. Auch ",[758,865,866],{},"erm"," ist dabei ein interner Gruppenname.",[730,869,870],{},"Das dient der Benutzerführung und ist keine Sicherheitsgrenze. Ein ausgeblendeter Navigationslink hindert niemanden daran, die URL direkt einzugeben. Dafür sind die Mixins und die Permission-Klasse für Django REST Framework da. Der Template-Filter sorgt lediglich dafür, dass die Oberfläche nur anbietet, was eine Person auch sehen und tun darf.",[750,872,874],{"id":873},"ausblick-und-erste-schritte","Ausblick und erste Schritte",[730,876,877],{},"Auf Plattformebene zahlt sich aus, dass sich dieses Muster wiederholen lässt, unabhängig von Modul und Team. Ein hypothetisches drittes Modul, etwa ein Workflow für Lieferantenrisiken oder ein Modul für Audit-Management, übernimmt dieselbe Struktur der Zugriffskontrolle, denselben Audit-Trail und dieselbe gemeinsame Authentifizierung, ohne eine einzige neue Zeile Durchsetzungslogik. Der Aufwand für ein neues Modul ergibt sich damit fast vollständig aus den fachlichen Anforderungen und nicht aus dem technischen Gerüst.",[730,879,880],{},"Darauf haben wir gesetzt: das Fundament einmal bauen und jedes künftige Modul darauf aufbauen lassen, statt die Zugriffskontrolle jedes Mal neu zu erfinden.",[730,882,883],{},"Für die Umsetzung in der eigenen App empfehlen wir etwa diese Reihenfolge:",[885,886,887,898,901,907],"ol",{},[888,889,890,891,893,894,897],"li",{},"Die Views auf die Lücke zwischen Login und Autorisierung prüfen. Nach ",[758,892,760],{}," und ",[758,895,896],{},"LoginRequiredMixin"," suchen und bei jedem Treffer fragen, ob er sensible Daten tatsächlich vor anderen angemeldeten Personen schützt und nicht nur vor anonymen.",[888,899,900],{},"Die Modulgrenze ziehen, bevor Code entsteht. Festlegen, was wirklich gemeinsam genutzt wird (Authentifizierung, grundlegende UI, Logging) und was nur einer Zielgruppe gehört.",[888,902,903,904,906],{},"Ein einziges Mixin schreiben, nicht eines pro View. Ein ",[758,905,817],{}," in der Core-App, pro Modul abgeleitet, bedeutet: Die Durchsetzungslogik muss an genau einer Stelle geprüft werden und kann nur an genau einer Stelle fehlerhaft sein.",[888,908,909],{},"Auf jeder Ebene unabhängig durchsetzen, also in Views, API und Navigation, damit ein ausgeblendeter Link nie die einzige Verteidigungslinie ist.",[750,911,913],{"id":912},"referenzen","Referenzen",[915,916,917,924,935],"ul",{},[888,918,919],{},[734,920,923],{"href":921,"rel":922},"https://docs.djangoproject.com/en/stable/topics/auth/default/",[],"Django authentication system – Using the Django authentication system",[888,925,926],{},[734,927,930,931,934],{"href":928,"rel":929},"https://docs.djangoproject.com/en/stable/topics/auth/default/#the-loginrequired-mixin",[],"Django class-based views – Using ",[758,932,933],{},"UserPassesTestMixin"," / permission mixins",[888,936,937],{},[734,938,941],{"href":939,"rel":940},"https://www.django-rest-framework.org/api-guide/permissions/",[],"Django REST Framework – Permissions",{"title":943,"searchDepth":944,"depth":944,"links":945},"",2,[946,947,948,949,950,951],{"id":752,"depth":944,"text":753},{"id":775,"depth":944,"text":776},{"id":788,"depth":944,"text":789},{"id":810,"depth":944,"text":811},{"id":873,"depth":944,"text":874},{"id":912,"depth":944,"text":913},"2026-10-05","Angemeldet heißt nicht berechtigt – wie sich Zugriffsrechte in einer Django-App pro Modul durchsetzen lassen, statt nur den Login zu prüfen.","md","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097663/Blog/Hero%20Images/Blog/Hero%20Images/Workflow%201800x945_2gQoQIbY9NvjLFpXtsxtXy_1750097663612.png",{},"/de-de/blog/module-level-access-in-a-django-grc-app",{"config":959,"title":960,"description":961},{"noIndex":10},"Django-GRC-App: Zugriffskontrolle auf Modulebene","GitLab hat ein internes Django-Tool für zwei Teams umgebaut. Gruppenrechte, Mixins und Prüfungen auf jeder Ebene trennen die Daten zuverlässig.","module-level-access-in-a-django-grc-app","de-de/blog/module-level-access-in-a-django-grc-app",[271],"BlogPost","QSz6nNTOsHVEObwHEwIqjIrOzUhqPGLDoJmPalfV_Tc",[968,976,983],{"title":969,"heroImage":970,"category":9,"description":971,"authors":972,"slug":975,"externalUrl":6},"Konfigurationsmanagement mit GitLab und Ansible","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665322/Blog/Hero%20Images/gitlab-ansible-cover.png","Entdecke die beeindruckende Leistungsfähigkeit von GitLab CI, wenn es darum geht, Ansible-Playbooks im Rahmen von Infrastructure as Code umzusetzen.",[973,974],"Brad Downey","Sara Kassabian","using-ansible-and-gitlab-as-infrastructure-for-code",{"title":977,"heroImage":978,"category":9,"description":979,"authors":980,"slug":982,"externalUrl":6},"4 Situationen, in denen sich eine aufgeräumte Git-Commit-Historie lohnt ","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659457/Blog/Hero%20Images/keep-git-commit-history-clean.jpg","Erfahre, warum eine saubere Git-Commit-Historie die Nachvollziehbarkeit verbessert, Fehler behebt und die Codequalität steigert.",[981],"Kushal Pandya","keeping-git-commit-history-clean",{"title":984,"heroImage":985,"category":9,"description":986,"authors":987,"slug":989,"externalUrl":6},"Was ist das Gitlab Container Registry?","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665223/Blog/Hero%20Images/containers.jpg"," Die auf Open Source basierende GitLab Container Registry ist nicht nur eine eigenständige Registry, sondern vollständig in GitLab integriert.",[988],"Mark Pundsack","gitlab-container-registry",1791952307865]