[{"data":1,"prerenderedAt":2234},["ShallowReactive",2],{"/de-de/blog/secure-and-publish-python-packages-a-guide-to-ci-integration":3,"navigation-de-de":1453,"banner-de-de":1882,"footer-de-de":1890,"blog-post-authors-de-de-Tim Rizzi":2131,"blog-related-posts-de-de-secure-and-publish-python-packages-a-guide-to-ci-integration":2146,"blog-promotions-de-de":2171,"next-steps-de-de":2224},{"id":4,"title":5,"authors":6,"body":8,"category":1427,"date":1428,"description":1429,"extension":1430,"externalUrl":1431,"faq":1431,"featured":1048,"heroImage":1432,"meta":1433,"navigation":1048,"path":1434,"seo":1435,"slug":1440,"stem":1441,"tags":1442,"template":1451,"updatedDate":1431,"__hash__":1452},"blogPosts/de-de/blog/secure-and-publish-python-packages-a-guide-to-ci-integration.md","Mit CI-Integration Python-Pakete sichern & publizieren",[7],"Tim Rizzi",{"type":9,"value":10,"toc":1410},"minimark",[11,15,18,94,98,101,122,125,128,131,159,162,165,169,172,175,180,191,194,219,222,348,351,373,377,380,383,388,391,530,533,550,554,557,560,711,714,727,731,734,849,852,861,865,868,958,961,970,974,977,1076,1079,1090,1094,1097,1341,1344,1349,1353,1356,1359,1373,1377,1396,1400,1403,1406],[12,13,14],"p",{},"Die Sicherheit der Software-Lieferkette ist ein zentrales Anliegen in der Softwareentwicklung. Unternehmen müssen die Authentizität und Integrität ihrer Software-Pakete nachweisen können. Diese Anleitung zeigt die Implementierung einer sicheren CI/CD-Pipeline für Python-Pakete mittels GitLab CI, einschließlich Paket-Signierung und Attestierung mit Sigstores Cosign.",[12,16,17],{},"In dieser Anleitung:",[19,20,21,52],"ul",{},[22,23,24,29,30,29,34,38],"li",{},[25,26,28],"a",{"href":27},"#warum-python-pakete-signieren-und-attestieren","Warum Python-Pakete signieren und attestieren?"," - ",[25,31,33],{"href":32},"#pipeline-%C3%BCbersicht","Pipeline-Übersicht",[25,35,37],{"href":36},"#vollst%C3%A4ndige-pipeline-implementierung-umgebung-einrichten","Vollständige Pipeline-Implementierung: Umgebung einrichten",[19,39,40,46],{},[22,41,42],{},[25,43,45],{"href":44},"#umgebungskonfiguration","Umgebungskonfiguration",[22,47,48],{},[25,49,51],{"href":50},"#konfigurations-aufschl%C3%BCsselung","Konfigurations-Aufschlüsselung",[22,53,54,55],{},"Die 6 Stufen\n",[56,57,58,64,70,76,82,88],"ol",{},[22,59,60],{},[25,61,63],{"href":62},"#build-das-paket-erstellen","Build",[22,65,66],{},[25,67,69],{"href":68},"#signierung-die-digitale-beglaubigung","Signierung",[22,71,72],{},[25,73,75],{"href":74},"#verifizierung-die-sicherheitskontrolle","Verifizierung",[22,77,78],{},[25,79,81],{"href":80},"#ver%C3%B6ffentlichung-die-kontrollierte-freigabe","Veröffentlichung",[22,83,84],{},[25,85,87],{"href":86},"#signaturen-ver%C3%B6ffentlichen-verifizierung-erm%C3%B6glichen","Signaturen veröffentlichen",[22,89,90],{},[25,91,93],{"href":92},"#nutzer-verifizierung-die-anwendererfahrung-testen","Nutzer-Verifizierung",[95,96,28],"h2",{"id":97},"warum-python-pakete-signieren-und-attestieren",[12,99,100],{},"Vier Gründe für Signierung und Attestierung der Python-Pakete:",[19,102,103],{},[22,104,105,109,110,113,114,117,118,121],{},[106,107,108],"strong",{},"Sicherheit der Lieferkette:"," Paket-Signierung stellt sicher, dass der Code zwischen Build und Deployment nicht manipuliert wurde und schützt vor Angriffen auf die Lieferkette. - ",[106,111,112],{},"Compliance-Anforderungen:"," Viele Unternehmen, insbesondere in regulierten Branchen, verlangen kryptographische Signaturen und Herkunftsnachweise für alle bereitgestellte Software. - ",[106,115,116],{},"Rückverfolgbarkeit:"," Attestierungen liefern einen verifizierbaren Nachweis der Build-Bedingungen, einschließlich wer das Paket unter welchen Umständen erstellt hat. - ",[106,119,120],{},"Vertrauens-Verifizierung:"," Nutzer des Pakets können dessen Authentizität vor der Installation kryptographisch überprüfen.",[95,123,33],{"id":124},"pipeline-übersicht",[12,126,127],{},"Die Gewährleistung der Code-Integrität und -Authentizität ist notwendig. Diese Pipeline erstellt nicht nur den Code, sondern erzeugt eine kryptographisch verifizierbare Dokumentation darüber, wie, wann und von wem das Paket erstellt wurde. Jede Stufe fungiert als Kontrollinstanz, die die Herkunft des Pakets prüft und dokumentiert.",[12,129,130],{},"Sechs Stufen einer GitLab-Pipeline, die die Sicherheit und Vertrauenswürdigkeit des Pakets gewährleisten:",[19,132,133],{},[22,134,135,138,139,142,143,146,147,150,151,154,155,158],{},[106,136,137],{},"Build:"," Erstellt ein sauberes, standardisiertes Paket, das einfach geteilt und installiert werden kann. - ",[106,140,141],{},"Signierung:"," Fügt eine digitale Signatur hinzu, die beweist, dass das Paket seit der Erstellung nicht manipuliert wurde. - ",[106,144,145],{},"Verifizierung:"," Überprüft, dass die Signatur gültig ist und das Paket alle Sicherheitsanforderungen erfüllt. - ",[106,148,149],{},"Veröffentlichung:"," Lädt das verifizierte Paket in die GitLab-Paket-Registry hoch und stellt es zur Nutzung bereit. - ",[106,152,153],{},"Signaturen veröffentlichen:"," Macht Signaturen zur Verifizierung verfügbar. - ",[106,156,157],{},"Nutzer-Verifizierung:"," Simuliert, wie Endnutzer die Paket-Authentizität verifizieren können.",[95,160,37],{"id":161},"vollständige-pipeline-implementierung-umgebung-einrichten",[12,163,164],{},"Vor dem Paket-Build muss eine konsistente und sichere Build-Umgebung eingerichtet werden. Diese Konfiguration stellt sicher, dass jedes Paket mit denselben Werkzeugen, Einstellungen und Sicherheitskontrollen erstellt wird.",[166,167,45],"h3",{"id":168},"umgebungskonfiguration",[12,170,171],{},"Die Pipeline benötigt spezifische Werkzeuge und Einstellungen.",[12,173,174],{},"Primäre Konfigurationen:",[19,176,177],{},[22,178,179],{},"Python 3.10 für konsistente Builds - Cosign 2.2.3 für Paket-Signierung - GitLab-Paket-Registry-Integration - Fest codierte Paket-Version für Reproduzierbarkeit",[12,181,182,185,186,190],{},[106,183,184],{},"Hinweis zur Versionierung:"," Dieses Beispiel nutzt eine fest codierte Version (",[187,188,189],"code",{},"\"1.0.0\"",") statt einer Ableitung aus Git-Tags oder Commits. Dieser Ansatz gewährleistet vollständige Reproduzierbarkeit und macht das Pipeline-Verhalten vorhersagbarer. In Produktivumgebungen lässt sich semantische Versionierung basierend auf Git-Tags oder eine andere Versionierungsstrategie einsetzen, die zum Release-Prozess passt.",[12,192,193],{},"Werkzeug-Anforderungen:",[19,195,196],{},[22,197,198,199,202,203,206,207,202,210,202,213,202,216],{},"Basis-Utilities: ",[187,200,201],{},"curl",", ",[187,204,205],{},"wget"," - Cosign für kryptographische Signierung - Python-Packaging-Tools: ",[187,208,209],{},"build",[187,211,212],{},"twine",[187,214,215],{},"setuptools",[187,217,218],{},"wheel",[166,220,51],{"id":221},"konfigurations-aufschlüsselung",[223,224,230],"pre",{"className":225,"code":226,"language":227,"meta":228,"style":229},"language-yaml shiki shiki-themes github-light","  PYTHON_VERSION: '3.10'\n  PACKAGE_NAME: ${CI_PROJECT_NAME}\n  PACKAGE_VERSION: \"1.0.0\"\n  FULCIO_URL: 'https://fulcio.sigstore.dev'\n  REKOR_URL: 'https://rekor.sigstore.dev'\n  CERTIFICATE_IDENTITY: 'https://gitlab.com/${CI_PROJECT_PATH}//.gitlab-ci.yml@refs/heads/${CI_DEFAULT_BRANCH}'\n  CERTIFICATE_OIDC_ISSUER: 'https://gitlab.com'\n  PIP_CACHE_DIR: \"$CI_PROJECT_DIR/.pip-cache\"\n  COSIGN_YES: \"true\"\n  GENERIC_PACKAGE_BASE_URL: \"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}\"\n","yaml","variables:","",[187,231,232,249,260,271,282,293,304,315,326,337],{"__ignoreMap":229},[233,234,237,241,245],"span",{"class":235,"line":236},"line",1,[233,238,240],{"class":239},"shJU0","  PYTHON_VERSION",[233,242,244],{"class":243},"sgsFI",": ",[233,246,248],{"class":247},"sYBdl","'3.10'\n",[233,250,252,255,257],{"class":235,"line":251},2,[233,253,254],{"class":239},"  PACKAGE_NAME",[233,256,244],{"class":243},[233,258,259],{"class":247},"${CI_PROJECT_NAME}\n",[233,261,263,266,268],{"class":235,"line":262},3,[233,264,265],{"class":239},"  PACKAGE_VERSION",[233,267,244],{"class":243},[233,269,270],{"class":247},"\"1.0.0\"\n",[233,272,274,277,279],{"class":235,"line":273},4,[233,275,276],{"class":239},"  FULCIO_URL",[233,278,244],{"class":243},[233,280,281],{"class":247},"'https://fulcio.sigstore.dev'\n",[233,283,285,288,290],{"class":235,"line":284},5,[233,286,287],{"class":239},"  REKOR_URL",[233,289,244],{"class":243},[233,291,292],{"class":247},"'https://rekor.sigstore.dev'\n",[233,294,296,299,301],{"class":235,"line":295},6,[233,297,298],{"class":239},"  CERTIFICATE_IDENTITY",[233,300,244],{"class":243},[233,302,303],{"class":247},"'https://gitlab.com/${CI_PROJECT_PATH}//.gitlab-ci.yml@refs/heads/${CI_DEFAULT_BRANCH}'\n",[233,305,307,310,312],{"class":235,"line":306},7,[233,308,309],{"class":239},"  CERTIFICATE_OIDC_ISSUER",[233,311,244],{"class":243},[233,313,314],{"class":247},"'https://gitlab.com'\n",[233,316,318,321,323],{"class":235,"line":317},8,[233,319,320],{"class":239},"  PIP_CACHE_DIR",[233,322,244],{"class":243},[233,324,325],{"class":247},"\"$CI_PROJECT_DIR/.pip-cache\"\n",[233,327,329,332,334],{"class":235,"line":328},9,[233,330,331],{"class":239},"  COSIGN_YES",[233,333,244],{"class":243},[233,335,336],{"class":247},"\"true\"\n",[233,338,340,343,345],{"class":235,"line":339},10,[233,341,342],{"class":239},"  GENERIC_PACKAGE_BASE_URL",[233,344,244],{"class":243},[233,346,347],{"class":247},"\"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}\"\n",[12,349,350],{},"Caching beschleunigt nachfolgende Builds:",[223,352,355],{"className":225,"code":353,"language":227,"meta":354,"style":229},"  paths:\n    - ${PIP_CACHE_DIR}\n","cache:",[187,356,357,365],{"__ignoreMap":229},[233,358,359,362],{"class":235,"line":236},[233,360,361],{"class":239},"  paths",[233,363,364],{"class":243},":\n",[233,366,367,370],{"class":235,"line":251},[233,368,369],{"class":243},"    - ",[233,371,372],{"class":247},"${PIP_CACHE_DIR}\n",[95,374,376],{"id":375},"build-das-paket-erstellen","Build: Das Paket erstellen",[12,378,379],{},"Jede Software-Entwicklung beginnt mit der Erstellung. In dieser Pipeline transformiert die Build-Stage Quellcode in ein verteilbares Paket, bereit für verschiedene Python-Umgebungen.",[12,381,382],{},"Der Build-Prozess erstellt zwei standardisierte Formate:",[19,384,385],{},[22,386,387],{},"Ein Wheel-Paket (.whl) für schnelle, effiziente Installation - Eine Quell-Distribution (.tar.gz) mit dem vollständigen Code",[12,389,390],{},"Implementierung der Build-Stage:",[223,392,395],{"className":225,"code":393,"language":227,"meta":394,"style":229},"  extends: .python-job\n  stage: build\n  script:\n    - git init\n    - git config --global init.defaultBranch main\n    - git config --global user.email \"ci@example.com\"\n    - git config --global user.name \"CI\"\n    - git add .\n    - git commit -m \"Initial commit\"\n    - export NORMALIZED_NAME=$(echo \"${CI_PROJECT_NAME}\" | tr '-' '_')\n    - sed -i \"s/name = \\\".*\\\"/name = \\\"${NORMALIZED_NAME}\\\"/\" pyproject.toml\n    - sed -i \"s|\\\"Homepage\\\" = \\\".*\\\"|\\\"Homepage\\\" = \\\"https://gitlab.com/${CI_PROJECT_PATH}\\\"|\" pyproject.toml\n    - python -m build\n  artifacts:\n    paths:\n      - dist/\n      - pyproject.toml\n","build:",[187,396,397,407,417,424,431,438,445,452,459,466,473,481,489,497,505,513,522],{"__ignoreMap":229},[233,398,399,402,404],{"class":235,"line":236},[233,400,401],{"class":239},"  extends",[233,403,244],{"class":243},[233,405,406],{"class":247},".python-job\n",[233,408,409,412,414],{"class":235,"line":251},[233,410,411],{"class":239},"  stage",[233,413,244],{"class":243},[233,415,416],{"class":247},"build\n",[233,418,419,422],{"class":235,"line":262},[233,420,421],{"class":239},"  script",[233,423,364],{"class":243},[233,425,426,428],{"class":235,"line":273},[233,427,369],{"class":243},[233,429,430],{"class":247},"git init\n",[233,432,433,435],{"class":235,"line":284},[233,434,369],{"class":243},[233,436,437],{"class":247},"git config --global init.defaultBranch main\n",[233,439,440,442],{"class":235,"line":295},[233,441,369],{"class":243},[233,443,444],{"class":247},"git config --global user.email \"ci@example.com\"\n",[233,446,447,449],{"class":235,"line":306},[233,448,369],{"class":243},[233,450,451],{"class":247},"git config --global user.name \"CI\"\n",[233,453,454,456],{"class":235,"line":317},[233,455,369],{"class":243},[233,457,458],{"class":247},"git add .\n",[233,460,461,463],{"class":235,"line":328},[233,462,369],{"class":243},[233,464,465],{"class":247},"git commit -m \"Initial commit\"\n",[233,467,468,470],{"class":235,"line":339},[233,469,369],{"class":243},[233,471,472],{"class":247},"export NORMALIZED_NAME=$(echo \"${CI_PROJECT_NAME}\" | tr '-' '_')\n",[233,474,476,478],{"class":235,"line":475},11,[233,477,369],{"class":243},[233,479,480],{"class":247},"sed -i \"s/name = \\\".*\\\"/name = \\\"${NORMALIZED_NAME}\\\"/\" pyproject.toml\n",[233,482,484,486],{"class":235,"line":483},12,[233,485,369],{"class":243},[233,487,488],{"class":247},"sed -i \"s|\\\"Homepage\\\" = \\\".*\\\"|\\\"Homepage\\\" = \\\"https://gitlab.com/${CI_PROJECT_PATH}\\\"|\" pyproject.toml\n",[233,490,492,494],{"class":235,"line":491},13,[233,493,369],{"class":243},[233,495,496],{"class":247},"python -m build\n",[233,498,500,503],{"class":235,"line":499},14,[233,501,502],{"class":239},"  artifacts",[233,504,364],{"class":243},[233,506,508,511],{"class":235,"line":507},15,[233,509,510],{"class":239},"    paths",[233,512,364],{"class":243},[233,514,516,519],{"class":235,"line":515},16,[233,517,518],{"class":243},"      - ",[233,520,521],{"class":247},"dist/\n",[233,523,525,527],{"class":235,"line":524},17,[233,526,518],{"class":243},[233,528,529],{"class":247},"pyproject.toml\n",[12,531,532],{},"Die Build-Stage führt folgende Schritte aus:",[56,534,535],{},[22,536,537,538,541,542,545,546,549],{},"Initialisiert ein Git-Repository (",[187,539,540],{},"git init",") und konfiguriert es mit Basis-Einstellungen 2. Normalisiert den Paketnamen durch Umwandlung von Bindestrichen in Unterstriche, was für Python-Packaging erforderlich ist 3. Aktualisiert die Paket-Metadaten in ",[187,543,544],{},"pyproject.toml"," entsprechend den Projekt-Einstellungen 4. Erstellt sowohl Wheel- als auch Quell-Distributions-Pakete mittels ",[187,547,548],{},"python -m build"," 5. Bewahrt die erstellten Pakete und Konfiguration als Artefakte für nachfolgende Stufen",[95,551,553],{"id":552},"signierung-die-digitale-beglaubigung","Signierung: Die digitale Beglaubigung",[12,555,556],{},"Ist die Attestierung die Biografie des Pakets, so ist die Signierung dessen kryptographisches Siegel der Authentizität. Hier wird das Paket von einer bloßen Datei-Sammlung in ein verifiziertes, manipulationssicheres Artefakt transformiert.",[12,558,559],{},"Die Signierung-Stage nutzt Cosign zur Anwendung einer digitalen Signatur als unzerbrechliches Siegel. Dies ist kein einfacher Stempel, sondern ein komplexer kryptographischer Handshake, der die Integrität und Herkunft des Pakets beweist.",[223,561,564],{"className":225,"code":562,"language":227,"meta":563,"style":229},"  extends: .python+cosign-job\n  stage: sign\n  id_tokens:\n    SIGSTORE_ID_TOKEN:\n      aud: sigstore\n  script:\n    - |\n      for file in dist/*.whl dist/*.tar.gz; do\n        if [ -f \"$file\" ]; then\n          filename=$(basename \"$file\")\n          cosign sign-blob --yes \\\n            --fulcio-url=${FULCIO_URL} \\\n            --rekor-url=${REKOR_URL} \\\n            --oidc-issuer $CI_SERVER_URL \\\n            --identity-token $SIGSTORE_ID_TOKEN \\\n            --output-signature \"dist/${filename}.sig\" \\\n            --output-certificate \"dist/${filename}.crt\" \\\n            \"$file\"\n        fi\n      done\n  artifacts:\n    paths:\n      - dist/\n","sign:",[187,565,566,575,584,591,598,608,614,622,627,632,637,642,647,652,657,662,667,672,678,684,690,697,704],{"__ignoreMap":229},[233,567,568,570,572],{"class":235,"line":236},[233,569,401],{"class":239},[233,571,244],{"class":243},[233,573,574],{"class":247},".python+cosign-job\n",[233,576,577,579,581],{"class":235,"line":251},[233,578,411],{"class":239},[233,580,244],{"class":243},[233,582,583],{"class":247},"sign\n",[233,585,586,589],{"class":235,"line":262},[233,587,588],{"class":239},"  id_tokens",[233,590,364],{"class":243},[233,592,593,596],{"class":235,"line":273},[233,594,595],{"class":239},"    SIGSTORE_ID_TOKEN",[233,597,364],{"class":243},[233,599,600,603,605],{"class":235,"line":284},[233,601,602],{"class":239},"      aud",[233,604,244],{"class":243},[233,606,607],{"class":247},"sigstore\n",[233,609,610,612],{"class":235,"line":295},[233,611,421],{"class":239},[233,613,364],{"class":243},[233,615,616,618],{"class":235,"line":306},[233,617,369],{"class":243},[233,619,621],{"class":620},"sD7c4","|\n",[233,623,624],{"class":235,"line":317},[233,625,626],{"class":247},"      for file in dist/*.whl dist/*.tar.gz; do\n",[233,628,629],{"class":235,"line":328},[233,630,631],{"class":247},"        if [ -f \"$file\" ]; then\n",[233,633,634],{"class":235,"line":339},[233,635,636],{"class":247},"          filename=$(basename \"$file\")\n",[233,638,639],{"class":235,"line":475},[233,640,641],{"class":247},"          cosign sign-blob --yes \\\n",[233,643,644],{"class":235,"line":483},[233,645,646],{"class":247},"            --fulcio-url=${FULCIO_URL} \\\n",[233,648,649],{"class":235,"line":491},[233,650,651],{"class":247},"            --rekor-url=${REKOR_URL} \\\n",[233,653,654],{"class":235,"line":499},[233,655,656],{"class":247},"            --oidc-issuer $CI_SERVER_URL \\\n",[233,658,659],{"class":235,"line":507},[233,660,661],{"class":247},"            --identity-token $SIGSTORE_ID_TOKEN \\\n",[233,663,664],{"class":235,"line":515},[233,665,666],{"class":247},"            --output-signature \"dist/${filename}.sig\" \\\n",[233,668,669],{"class":235,"line":524},[233,670,671],{"class":247},"            --output-certificate \"dist/${filename}.crt\" \\\n",[233,673,675],{"class":235,"line":674},18,[233,676,677],{"class":247},"            \"$file\"\n",[233,679,681],{"class":235,"line":680},19,[233,682,683],{"class":247},"        fi\n",[233,685,687],{"class":235,"line":686},20,[233,688,689],{"class":247},"      done\n",[233,691,693,695],{"class":235,"line":692},21,[233,694,502],{"class":239},[233,696,364],{"class":243},[233,698,700,702],{"class":235,"line":699},22,[233,701,510],{"class":239},[233,703,364],{"class":243},[233,705,707,709],{"class":235,"line":706},23,[233,708,518],{"class":243},[233,710,521],{"class":247},[12,712,713],{},"Diese Signierung-Stage führt mehrere zentrale Operationen aus:",[56,715,716],{},[22,717,718,719,722,723,726],{},"Erhält ein OIDC-Token von GitLab zur Authentifizierung bei Sigstore-Diensten 2. Verarbeitet jedes erstellte Paket (sowohl Wheel als auch Quell-Distribution) 3. Nutzt Cosign zur Erstellung einer kryptographischen Signatur (",[187,720,721],{},".sig",") für jedes Paket 4. Generiert ein Zertifikat (",[187,724,725],{},".crt","), das die Authentizität der Signatur beweist 5. Speichert sowohl Signaturen als auch Zertifikate zusammen mit den Paketen als Artefakte",[95,728,730],{"id":729},"verifizierung-die-sicherheitskontrolle","Verifizierung: Die Sicherheitskontrolle",[12,732,733],{},"Die Verifizierung ist das finale Qualitätskontroll-Gate. Dies ist nicht nur eine Prüfung, sondern eine Sicherheitsuntersuchung, bei der jeder Aspekt des Pakets überprüft wird.",[223,735,738],{"className":225,"code":736,"language":227,"meta":737,"style":229},"  extends: .python+cosign-job\n  stage: verify\n  script:\n    - |\n      failed=0\n      for file in dist/*.whl dist/*.tar.gz; do\n        if [ -f \"$file\" ]; then\n          filename=$(basename \"$file\")\n          if ! cosign verify-blob \\\n            --signature \"dist/${filename}.sig\" \\\n            --certificate \"dist/${filename}.crt\" \\\n            --certificate-identity \"${CERTIFICATE_IDENTITY}\" \\\n            --certificate-oidc-issuer \"${CERTIFICATE_OIDC_ISSUER}\" \\\n            \"$file\"; then\n            failed=1\n          fi\n        fi\n      done\n      if [ $failed -eq 1 ]; then\n        exit 1\n      fi\n","verify:",[187,739,740,748,757,763,769,774,778,782,786,791,796,801,806,811,816,821,826,830,834,839,844],{"__ignoreMap":229},[233,741,742,744,746],{"class":235,"line":236},[233,743,401],{"class":239},[233,745,244],{"class":243},[233,747,574],{"class":247},[233,749,750,752,754],{"class":235,"line":251},[233,751,411],{"class":239},[233,753,244],{"class":243},[233,755,756],{"class":247},"verify\n",[233,758,759,761],{"class":235,"line":262},[233,760,421],{"class":239},[233,762,364],{"class":243},[233,764,765,767],{"class":235,"line":273},[233,766,369],{"class":243},[233,768,621],{"class":620},[233,770,771],{"class":235,"line":284},[233,772,773],{"class":247},"      failed=0\n",[233,775,776],{"class":235,"line":295},[233,777,626],{"class":247},[233,779,780],{"class":235,"line":306},[233,781,631],{"class":247},[233,783,784],{"class":235,"line":317},[233,785,636],{"class":247},[233,787,788],{"class":235,"line":328},[233,789,790],{"class":247},"          if ! cosign verify-blob \\\n",[233,792,793],{"class":235,"line":339},[233,794,795],{"class":247},"            --signature \"dist/${filename}.sig\" \\\n",[233,797,798],{"class":235,"line":475},[233,799,800],{"class":247},"            --certificate \"dist/${filename}.crt\" \\\n",[233,802,803],{"class":235,"line":483},[233,804,805],{"class":247},"            --certificate-identity \"${CERTIFICATE_IDENTITY}\" \\\n",[233,807,808],{"class":235,"line":491},[233,809,810],{"class":247},"            --certificate-oidc-issuer \"${CERTIFICATE_OIDC_ISSUER}\" \\\n",[233,812,813],{"class":235,"line":499},[233,814,815],{"class":247},"            \"$file\"; then\n",[233,817,818],{"class":235,"line":507},[233,819,820],{"class":247},"            failed=1\n",[233,822,823],{"class":235,"line":515},[233,824,825],{"class":247},"          fi\n",[233,827,828],{"class":235,"line":524},[233,829,683],{"class":247},[233,831,832],{"class":235,"line":674},[233,833,689],{"class":247},[233,835,836],{"class":235,"line":680},[233,837,838],{"class":247},"      if [ $failed -eq 1 ]; then\n",[233,840,841],{"class":235,"line":686},[233,842,843],{"class":247},"        exit 1\n",[233,845,846],{"class":235,"line":692},[233,847,848],{"class":247},"      fi\n",[12,850,851],{},"Die Verifizierung-Stage implementiert mehrere Sicherheitsprüfungen:",[56,853,854],{},[22,855,856,857,860],{},"Untersucht jede Paketdatei im ",[187,858,859],{},"dist","-Verzeichnis 2. Nutzt Cosign zur Überprüfung, dass die Signatur zum Paketinhalt passt 3. Bestätigt, dass die Zertifikats-Identität der erwarteten GitLab-Pipeline-Identität entspricht 4. Validiert, dass das Zertifikat vom vertrauenswürdigen OIDC-Provider ausgestellt wurde 5. Lässt die gesamte Pipeline fehlschlagen, wenn eine Prüfung fehlschlägt, sodass nur verifizierte Pakete fortfahren",[95,862,864],{"id":863},"veröffentlichung-die-kontrollierte-freigabe","Veröffentlichung: Die kontrollierte Freigabe",[12,866,867],{},"Bei der Veröffentlichung werden die verifizierten Pakete über die GitLab-Paket-Registry verfügbar gemacht. Dies ist eine sorgfältig orchestrierte Freigabe, die sicherstellt, dass nur verifizierte, authentifizierte Pakete ihr Ziel erreichen.",[223,869,872],{"className":225,"code":870,"language":227,"meta":871,"style":229},"  extends: .python-job\n  stage: publish\n  script:\n    - |\n      cat \u003C\u003C EOF > ~/.pypirc\n      [distutils]\n      index-servers = gitlab\n      [gitlab]\n      repository = ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi\n      username = gitlab-ci-token\n      password = ${CI_JOB_TOKEN}\n      EOF\n      TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token \\\n        twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi \\\n        dist/*.whl dist/*.tar.gz\n","publish:",[187,873,874,882,891,897,903,908,913,918,923,928,933,938,943,948,953],{"__ignoreMap":229},[233,875,876,878,880],{"class":235,"line":236},[233,877,401],{"class":239},[233,879,244],{"class":243},[233,881,406],{"class":247},[233,883,884,886,888],{"class":235,"line":251},[233,885,411],{"class":239},[233,887,244],{"class":243},[233,889,890],{"class":247},"publish\n",[233,892,893,895],{"class":235,"line":262},[233,894,421],{"class":239},[233,896,364],{"class":243},[233,898,899,901],{"class":235,"line":273},[233,900,369],{"class":243},[233,902,621],{"class":620},[233,904,905],{"class":235,"line":284},[233,906,907],{"class":247},"      cat \u003C\u003C EOF > ~/.pypirc\n",[233,909,910],{"class":235,"line":295},[233,911,912],{"class":247},"      [distutils]\n",[233,914,915],{"class":235,"line":306},[233,916,917],{"class":247},"      index-servers = gitlab\n",[233,919,920],{"class":235,"line":317},[233,921,922],{"class":247},"      [gitlab]\n",[233,924,925],{"class":235,"line":328},[233,926,927],{"class":247},"      repository = ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi\n",[233,929,930],{"class":235,"line":339},[233,931,932],{"class":247},"      username = gitlab-ci-token\n",[233,934,935],{"class":235,"line":475},[233,936,937],{"class":247},"      password = ${CI_JOB_TOKEN}\n",[233,939,940],{"class":235,"line":483},[233,941,942],{"class":247},"      EOF\n",[233,944,945],{"class":235,"line":491},[233,946,947],{"class":247},"      TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token \\\n",[233,949,950],{"class":235,"line":499},[233,951,952],{"class":247},"        twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi \\\n",[233,954,955],{"class":235,"line":507},[233,956,957],{"class":247},"        dist/*.whl dist/*.tar.gz\n",[12,959,960],{},"Die Veröffentlichung-Stage übernimmt mehrere wichtige Aufgaben:",[56,962,963],{},[22,964,965,966,969],{},"Erstellt eine ",[187,967,968],{},".pypirc","-Konfigurationsdatei mit GitLab-Paket-Registry-Zugangsdaten 2. Nutzt das GitLab-CI-Job-Token für sichere Authentifizierung 3. Lädt sowohl Wheel- als auch Quell-Distributions-Pakete in die GitLab-PyPI-Registry hoch 4. Stellt die Pakete zur Installation via pip bereit",[95,971,973],{"id":972},"signaturen-veröffentlichen-verifizierung-ermöglichen","Signaturen veröffentlichen: Verifizierung ermöglichen",[12,975,976],{},"Nach Veröffentlichung der Pakete müssen deren Signaturen und Zertifikate zur Verifizierung verfügbar gemacht werden. Diese werden in der generischen Paket-Registry von GitLab gespeichert und sind damit einfach zugänglich für Nutzer, die die Paket-Authentizität verifizieren möchten.",[223,978,981],{"className":225,"code":979,"language":227,"meta":980,"style":229},"  extends: .python+cosign-job\n  stage: publish_signatures\n  script:\n    - |\n      for file in dist/*.whl dist/*.tar.gz; do\n        if [ -f \"$file\" ]; then\n          filename=$(basename \"$file\")\n          curl --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n               --fail \\\n               --upload-file \"dist/${filename}.sig\" \\\n               \"${GENERIC_PACKAGE_BASE_URL}/${filename}.sig\"\n\n          curl --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n               --fail \\\n               --upload-file \"dist/${filename}.crt\" \\\n               \"${GENERIC_PACKAGE_BASE_URL}/${filename}.crt\"\n        fi\n      done\n","publish_signatures:",[187,982,983,991,1000,1006,1012,1016,1020,1024,1029,1034,1039,1044,1050,1054,1058,1063,1068,1072],{"__ignoreMap":229},[233,984,985,987,989],{"class":235,"line":236},[233,986,401],{"class":239},[233,988,244],{"class":243},[233,990,574],{"class":247},[233,992,993,995,997],{"class":235,"line":251},[233,994,411],{"class":239},[233,996,244],{"class":243},[233,998,999],{"class":247},"publish_signatures\n",[233,1001,1002,1004],{"class":235,"line":262},[233,1003,421],{"class":239},[233,1005,364],{"class":243},[233,1007,1008,1010],{"class":235,"line":273},[233,1009,369],{"class":243},[233,1011,621],{"class":620},[233,1013,1014],{"class":235,"line":284},[233,1015,626],{"class":247},[233,1017,1018],{"class":235,"line":295},[233,1019,631],{"class":247},[233,1021,1022],{"class":235,"line":306},[233,1023,636],{"class":247},[233,1025,1026],{"class":235,"line":317},[233,1027,1028],{"class":247},"          curl --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n",[233,1030,1031],{"class":235,"line":328},[233,1032,1033],{"class":247},"               --fail \\\n",[233,1035,1036],{"class":235,"line":339},[233,1037,1038],{"class":247},"               --upload-file \"dist/${filename}.sig\" \\\n",[233,1040,1041],{"class":235,"line":475},[233,1042,1043],{"class":247},"               \"${GENERIC_PACKAGE_BASE_URL}/${filename}.sig\"\n",[233,1045,1046],{"class":235,"line":483},[233,1047,1049],{"emptyLinePlaceholder":1048},true,"\n",[233,1051,1052],{"class":235,"line":491},[233,1053,1028],{"class":247},[233,1055,1056],{"class":235,"line":499},[233,1057,1033],{"class":247},[233,1059,1060],{"class":235,"line":507},[233,1061,1062],{"class":247},"               --upload-file \"dist/${filename}.crt\" \\\n",[233,1064,1065],{"class":235,"line":515},[233,1066,1067],{"class":247},"               \"${GENERIC_PACKAGE_BASE_URL}/${filename}.crt\"\n",[233,1069,1070],{"class":235,"line":524},[233,1071,683],{"class":247},[233,1073,1074],{"class":235,"line":674},[233,1075,689],{"class":247},[12,1077,1078],{},"Die Signaturen-Veröffentlichung-Stage führt folgende Schlüsseloperationen aus:",[56,1080,1081],{},[22,1082,1083,1084,1086,1087,1089],{},"Verarbeitet jedes erstellte Paket zur Identifikation der zugehörigen Signaturdateien 2. Nutzt die GitLab-API zum Upload der Signatur-Datei (",[187,1085,721],{},") in die generische Paket-Registry 3. Lädt die zugehörige Zertifikat-Datei (",[187,1088,725],{},") hoch 4. Stellt diese Verifizierungs-Artefakte für nachgelagerte Paket-Nutzer bereit 5. Verwendet dieselbe Version und denselben Paketnamen zur Aufrechterhaltung der Verbindung zwischen Paketen und Signaturen",[95,1091,1093],{"id":1092},"nutzer-verifizierung-die-anwendererfahrung-testen","Nutzer-Verifizierung: Die Anwendererfahrung testen",[12,1095,1096],{},"Die finale Stufe simuliert, wie Endnutzer die Authentizität des Pakets verifizieren werden. Diese Stufe dient sowohl als finale Prüfung als auch als praktisches Beispiel des Verifizierungsprozesses.",[223,1098,1101],{"className":225,"code":1099,"language":227,"meta":1100,"style":229},"  extends: .python+cosign-job\n  stage: consumer_verification\n  script:\n    - |\n      git init\n      git config --global init.defaultBranch main\n      mkdir -p pkg signatures\n\n      pip download --index-url \"https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple\" \\\n          \"${NORMALIZED_NAME}==${PACKAGE_VERSION}\" --no-deps -d ./pkg\n\n      pip download --no-binary :all: \\\n          --index-url \"https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple\" \\\n          \"${NORMALIZED_NAME}==${PACKAGE_VERSION}\" --no-deps -d ./pkg\n\n      failed=0\n      for file in pkg/*.whl pkg/*.tar.gz; do\n        if [ -f \"$file\" ]; then\n          filename=$(basename \"$file\")\n          sig_url=\"${GENERIC_PACKAGE_BASE_URL}/${filename}.sig\"\n          cert_url=\"${GENERIC_PACKAGE_BASE_URL}/${filename}.crt\"\n\n          curl --fail --silent --show-error \\\n               --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n               --output \"signatures/${filename}.sig\" \\\n               \"$sig_url\"\n\n          curl --fail --silent --show-error \\\n               --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n               --output \"signatures/${filename}.crt\" \\\n               \"$cert_url\"\n\n          if ! cosign verify-blob \\\n            --signature \"signatures/${filename}.sig\" \\\n            --certificate \"signatures/${filename}.crt\" \\\n            --certificate-identity \"${CERTIFICATE_IDENTITY}\" \\\n            --certificate-oidc-issuer \"${CERTIFICATE_OIDC_ISSUER}\" \\\n            \"$file\"; then\n            failed=1\n          fi\n        fi\n      done\n\n      if [ $failed -eq 1 ]; then\n        exit 1\n      fi\n","consumer_verification:",[187,1102,1103,1111,1120,1126,1132,1137,1142,1147,1151,1156,1161,1165,1170,1175,1179,1183,1187,1192,1196,1200,1205,1210,1214,1219,1225,1231,1237,1242,1247,1252,1258,1264,1269,1274,1280,1286,1291,1296,1301,1306,1311,1316,1321,1326,1331,1336],{"__ignoreMap":229},[233,1104,1105,1107,1109],{"class":235,"line":236},[233,1106,401],{"class":239},[233,1108,244],{"class":243},[233,1110,574],{"class":247},[233,1112,1113,1115,1117],{"class":235,"line":251},[233,1114,411],{"class":239},[233,1116,244],{"class":243},[233,1118,1119],{"class":247},"consumer_verification\n",[233,1121,1122,1124],{"class":235,"line":262},[233,1123,421],{"class":239},[233,1125,364],{"class":243},[233,1127,1128,1130],{"class":235,"line":273},[233,1129,369],{"class":243},[233,1131,621],{"class":620},[233,1133,1134],{"class":235,"line":284},[233,1135,1136],{"class":247},"      git init\n",[233,1138,1139],{"class":235,"line":295},[233,1140,1141],{"class":247},"      git config --global init.defaultBranch main\n",[233,1143,1144],{"class":235,"line":306},[233,1145,1146],{"class":247},"      mkdir -p pkg signatures\n",[233,1148,1149],{"class":235,"line":317},[233,1150,1049],{"emptyLinePlaceholder":1048},[233,1152,1153],{"class":235,"line":328},[233,1154,1155],{"class":247},"      pip download --index-url \"https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple\" \\\n",[233,1157,1158],{"class":235,"line":339},[233,1159,1160],{"class":247},"          \"${NORMALIZED_NAME}==${PACKAGE_VERSION}\" --no-deps -d ./pkg\n",[233,1162,1163],{"class":235,"line":475},[233,1164,1049],{"emptyLinePlaceholder":1048},[233,1166,1167],{"class":235,"line":483},[233,1168,1169],{"class":247},"      pip download --no-binary :all: \\\n",[233,1171,1172],{"class":235,"line":491},[233,1173,1174],{"class":247},"          --index-url \"https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple\" \\\n",[233,1176,1177],{"class":235,"line":499},[233,1178,1160],{"class":247},[233,1180,1181],{"class":235,"line":507},[233,1182,1049],{"emptyLinePlaceholder":1048},[233,1184,1185],{"class":235,"line":515},[233,1186,773],{"class":247},[233,1188,1189],{"class":235,"line":524},[233,1190,1191],{"class":247},"      for file in pkg/*.whl pkg/*.tar.gz; do\n",[233,1193,1194],{"class":235,"line":674},[233,1195,631],{"class":247},[233,1197,1198],{"class":235,"line":680},[233,1199,636],{"class":247},[233,1201,1202],{"class":235,"line":686},[233,1203,1204],{"class":247},"          sig_url=\"${GENERIC_PACKAGE_BASE_URL}/${filename}.sig\"\n",[233,1206,1207],{"class":235,"line":692},[233,1208,1209],{"class":247},"          cert_url=\"${GENERIC_PACKAGE_BASE_URL}/${filename}.crt\"\n",[233,1211,1212],{"class":235,"line":699},[233,1213,1049],{"emptyLinePlaceholder":1048},[233,1215,1216],{"class":235,"line":706},[233,1217,1218],{"class":247},"          curl --fail --silent --show-error \\\n",[233,1220,1222],{"class":235,"line":1221},24,[233,1223,1224],{"class":247},"               --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \\\n",[233,1226,1228],{"class":235,"line":1227},25,[233,1229,1230],{"class":247},"               --output \"signatures/${filename}.sig\" \\\n",[233,1232,1234],{"class":235,"line":1233},26,[233,1235,1236],{"class":247},"               \"$sig_url\"\n",[233,1238,1240],{"class":235,"line":1239},27,[233,1241,1049],{"emptyLinePlaceholder":1048},[233,1243,1245],{"class":235,"line":1244},28,[233,1246,1218],{"class":247},[233,1248,1250],{"class":235,"line":1249},29,[233,1251,1224],{"class":247},[233,1253,1255],{"class":235,"line":1254},30,[233,1256,1257],{"class":247},"               --output \"signatures/${filename}.crt\" \\\n",[233,1259,1261],{"class":235,"line":1260},31,[233,1262,1263],{"class":247},"               \"$cert_url\"\n",[233,1265,1267],{"class":235,"line":1266},32,[233,1268,1049],{"emptyLinePlaceholder":1048},[233,1270,1272],{"class":235,"line":1271},33,[233,1273,790],{"class":247},[233,1275,1277],{"class":235,"line":1276},34,[233,1278,1279],{"class":247},"            --signature \"signatures/${filename}.sig\" \\\n",[233,1281,1283],{"class":235,"line":1282},35,[233,1284,1285],{"class":247},"            --certificate \"signatures/${filename}.crt\" \\\n",[233,1287,1289],{"class":235,"line":1288},36,[233,1290,805],{"class":247},[233,1292,1294],{"class":235,"line":1293},37,[233,1295,810],{"class":247},[233,1297,1299],{"class":235,"line":1298},38,[233,1300,815],{"class":247},[233,1302,1304],{"class":235,"line":1303},39,[233,1305,820],{"class":247},[233,1307,1309],{"class":235,"line":1308},40,[233,1310,825],{"class":247},[233,1312,1314],{"class":235,"line":1313},41,[233,1315,683],{"class":247},[233,1317,1319],{"class":235,"line":1318},42,[233,1320,689],{"class":247},[233,1322,1324],{"class":235,"line":1323},43,[233,1325,1049],{"emptyLinePlaceholder":1048},[233,1327,1329],{"class":235,"line":1328},44,[233,1330,838],{"class":247},[233,1332,1334],{"class":235,"line":1333},45,[233,1335,843],{"class":247},[233,1337,1339],{"class":235,"line":1338},46,[233,1340,848],{"class":247},[12,1342,1343],{},"Diese Nutzer-Verifizierung-Stage simuliert die Endnutzer-Erfahrung durch:",[56,1345,1346],{},[22,1347,1348],{},"Erstellung einer sauberen Umgebung zum Test der Paket-Installation 2. Download der veröffentlichten Pakete aus der GitLab-PyPI-Registry 3. Abruf der zugehörigen Signaturen und Zertifikate aus der generischen Paket-Registry 4. Durchführung derselben Verifizierungsschritte, die Endnutzer ausführen würden 5. Sicherstellung, dass der gesamte Prozess aus Nutzer-Perspektive funktioniert 6. Fehlschlag der Pipeline bei Fehlern in einem Verifizierungsschritt für frühzeitige Problemerkennung",[95,1350,1352],{"id":1351},"zusammenfassung","Zusammenfassung",[12,1354,1355],{},"Diese umfassende Pipeline bietet eine sichere und zuverlässige Methode zum Erstellen, Signieren und Veröffentlichen von Python-Paketen in die GitLab-Paket-Registry. Durch Befolgung dieser Praktiken und Implementierung der empfohlenen Sicherheitsmaßnahmen lässt sich sicherstellen, dass Pakete angemessen verifiziert und sicher an Nutzer verteilt werden.",[12,1357,1358],{},"Die Pipeline kombiniert moderne Sicherheitspraktiken mit effizienter Automatisierung zur Schaffung einer robusten Software-Lieferkette. Mittels Sigstores Cosign für Signierung und Attestierung sowie GitLabs integrierten Sicherheitsfunktionen lassen sich Nutzern vertrauenswürdige, kryptographisch verifizierte Pakete bereitstellen.",[1360,1361,1362],"blockquote",{},[1363,1364,1366,1367,1372],"h4",{"id":1365},"starte-noch-heute-deine-sicherheitsreise-mit-einer-kostenlosen-testversion-von-gitlab-ultimate","Starte noch heute deine Sicherheitsreise mit einer ",[25,1368,1371],{"href":1369,"rel":1370},"https://gitlab.com/-/trials/new?glm_content=default-saas-trial&glm_source=about.gitlab.com",[],"kostenlosen Testversion von GitLab Ultimate",".",[95,1374,1376],{"id":1375},"weitere-informationen","Weitere Informationen",[19,1378,1379],{},[22,1380,1381,29,1386,29,1391],{},[25,1382,1385],{"href":1383,"rel":1384},"https://docs.gitlab.com/ci/yaml/signing_examples/",[],"Dokumentation: Sigstore für schlüssellose Signierung und Verifizierung nutzen",[25,1387,1390],{"href":1388,"rel":1389},"https://about.gitlab.com/blog/keyless-signing-with-cosign/",[],"Sicherheit optimieren durch schlüssellose Signierung und Verifizierung in GitLab",[25,1392,1395],{"href":1393,"rel":1394},"https://about.gitlab.com/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd/",[],"Container-Images mit Build-Provenance mittels Cosign in GitLab CI/CD annotieren",[95,1397,1399],{"id":1398},"für-deutsche-unternehmen-könnte-dies-folgende-themen-betreffen","Für deutsche Unternehmen könnte dies folgende Themen betreffen:",[12,1401,1402],{},"Teams, die kryptographische Paket-Signierung implementieren, adressieren möglicherweise auch Compliance-Anforderungen – beispielsweise in regulierten Branchen, wo kryptographische Signaturen und Herkunftsnachweise für bereitgestellte Software verlangt werden.",[12,1404,1405],{},"Für spezifische Compliance-Bewertungen und regulatorische Anforderungen empfiehlt sich Rücksprache mit entsprechender Fachberatung.",[1407,1408,1409],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}",{"title":229,"searchDepth":251,"depth":251,"links":1411},[1412,1413,1414,1418,1419,1420,1421,1422,1423,1424,1425,1426],{"id":97,"depth":251,"text":28},{"id":124,"depth":251,"text":33},{"id":161,"depth":251,"text":37,"children":1415},[1416,1417],{"id":168,"depth":262,"text":45},{"id":221,"depth":262,"text":51},{"id":375,"depth":251,"text":376},{"id":552,"depth":251,"text":553},{"id":729,"depth":251,"text":730},{"id":863,"depth":251,"text":864},{"id":972,"depth":251,"text":973},{"id":1092,"depth":251,"text":1093},{"id":1351,"depth":251,"text":1352},{"id":1375,"depth":251,"text":1376},{"id":1398,"depth":251,"text":1399},"security","2025-12-09","Implementierung einer sicheren CI/CD-Pipeline über sechs Stufen mit der GitLab-DevSecOps-Plattform.","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662080/Blog/Hero%20Images/AdobeStock_1097303277.jpg",{},"/de-de/blog/secure-and-publish-python-packages-a-guide-to-ci-integration",{"title":5,"description":1429,"ogTitle":5,"ogDescription":1429,"noIndex":1436,"ogImage":1432,"ogUrl":1437,"ogSiteName":1438,"ogType":1439,"canonicalUrls":1437},false,"https://about.gitlab.com/blog/secure-and-publish-python-packages-a-guide-to-ci-integration","https://about.gitlab.com","article","secure-and-publish-python-packages-a-guide-to-ci-integration","de-de/blog/secure-and-publish-python-packages-a-guide-to-ci-integration",[1427,1443,1444,1445,1446,1447,1448,1449,1450],"integrations","partners","features","CI","CI/CD","DevSecOps platform","tutorial","solutions architecture","BlogPost","95oIEboy-ztcLYvWKb9JsshU0m7R8J_WXXMUfQ-sCJ0",{"logo":1454,"freeTrial":1459,"sales":1464,"login":1469,"items":1474,"search":1800,"minimal":1834,"duo":1852,"switchNav":1861,"pricingDeployment":1872},{"config":1455},{"href":1456,"dataGaName":1457,"dataGaLocation":1458},"/de-de/","gitlab logo","header",{"text":1460,"config":1461},"Kostenlose Testversion anfordern",{"href":1462,"dataGaName":1463,"dataGaLocation":1458},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de&glm_content=default-saas-trial/","free trial",{"text":1465,"config":1466},"Demo anfordern",{"href":1467,"dataGaName":1468,"dataGaLocation":1458},"/de-de/sales/?contact-topic=request-demo","sales",{"text":1470,"config":1471},"Anmelden",{"href":1472,"dataGaName":1473,"dataGaLocation":1458},"https://gitlab.com/users/sign_in/","sign in",[1475,1504,1605,1610,1722,1778],{"text":1476,"config":1477,"menu":1479},"Plattform",{"dataNavLevelOne":1478},"platform",{"type":1480,"columns":1481},"cards",[1482,1488,1496],{"title":1476,"description":1483,"link":1484},"Die intelligente Orchestrierungsplattform für DevSecOps",{"text":1485,"config":1486},"Die Plattform erkunden",{"href":1487,"dataGaName":1478,"dataGaLocation":1458},"/de-de/platform/",{"title":1489,"description":1490,"link":1491},"GitLab Duo Agent Platform","Agentische KI für den gesamten Software-Lebenszyklus",{"text":1492,"config":1493},"Lerne GitLab Duo kennen",{"href":1494,"dataGaName":1495,"dataGaLocation":1458},"/de-de/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1497,"description":1498,"link":1499},"Warum GitLab?","Erfahre, warum sich Unternehmen für GitLab entscheiden",{"text":1500,"config":1501},"Mehr erfahren",{"href":1502,"dataGaName":1503,"dataGaLocation":1458},"/de-de/why-gitlab/","why gitlab",{"text":1505,"left":1048,"config":1506,"menu":1508},"Produkt",{"dataNavLevelOne":1507},"solutions",{"type":1509,"link":1510,"columns":1514,"feature":1584},"lists",{"text":1511,"config":1512},"Alle Lösungen anzeigen",{"href":1513,"dataGaName":1507,"dataGaLocation":1458},"/de-de/solutions/",[1515,1539,1562],{"title":1516,"description":1517,"link":1518,"items":1523},"Automatisierung","CI/CD und Automatisierung zur Beschleunigung der Bereitstellung",{"config":1519},{"icon":1520,"href":1521,"dataGaName":1522,"dataGaLocation":1458},"AutomatedCodeAlt","/de-de/solutions/delivery-automation/","automated software delivery",[1524,1527,1530,1535],{"text":1447,"config":1525},{"href":1526,"dataGaLocation":1458,"dataGaName":1447},"/de-de/solutions/continuous-integration/",{"text":1489,"config":1528},{"href":1494,"dataGaLocation":1458,"dataGaName":1529},"gitlab duo agent platform - product menu",{"text":1531,"config":1532},"Quellcodeverwaltung",{"href":1533,"dataGaLocation":1458,"dataGaName":1534},"/de-de/solutions/source-code-management/","Source Code Management",{"text":1536,"config":1537},"Automatische Softwarebereitstellung",{"href":1521,"dataGaLocation":1458,"dataGaName":1538},"Automated software delivery",{"title":1540,"description":1541,"link":1542,"items":1547},"Sicherheit","Entwickle Code schneller ohne Abstriche bei der Sicherheit",{"config":1543},{"href":1544,"dataGaName":1545,"dataGaLocation":1458,"icon":1546},"/de-de/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1548,1552,1557],{"text":1549,"config":1550},"Anwendungssicherheitstests",{"href":1544,"dataGaName":1551,"dataGaLocation":1458},"Application security testing",{"text":1553,"config":1554},"Schutz der Software-Lieferkette",{"href":1555,"dataGaLocation":1458,"dataGaName":1556},"/de-de/solutions/supply-chain/","Software supply chain security",{"text":1558,"config":1559},"Software-Compliance",{"href":1560,"dataGaName":1561,"dataGaLocation":1458},"/de-de/solutions/software-compliance/","software compliance",{"title":1563,"link":1564,"items":1569},"Messung",{"config":1565},{"icon":1566,"href":1567,"dataGaName":1568,"dataGaLocation":1458},"DigitalTransformation","/de-de/solutions/visibility-measurement/","visibility and measurement",[1570,1574,1579],{"text":1571,"config":1572},"Sichtbarkeit und Messung",{"href":1567,"dataGaLocation":1458,"dataGaName":1573},"Visibility and Measurement",{"text":1575,"config":1576},"Wertstrommanagement",{"href":1577,"dataGaLocation":1458,"dataGaName":1578},"/de-de/solutions/value-stream-management/","Value Stream Management",{"text":1580,"config":1581},"Analysen und Einblicke",{"href":1582,"dataGaLocation":1458,"dataGaName":1583},"/de-de/solutions/analytics-and-insights/","Analytics and insights",{"title":1585,"type":1509,"items":1586},"GitLab für",[1587,1593,1599],{"text":1588,"config":1589},"Enterprise",{"icon":1590,"href":1591,"dataGaLocation":1458,"dataGaName":1592},"Building","/de-de/enterprise/","enterprise",{"text":1594,"config":1595},"Kleinunternehmen",{"icon":1596,"href":1597,"dataGaLocation":1458,"dataGaName":1598},"Work","/de-de/small-business/","small business",{"text":1600,"config":1601},"Öffentlicher Sektor",{"icon":1602,"href":1603,"dataGaLocation":1458,"dataGaName":1604},"Organization","/de-de/solutions/public-sector/","public sector",{"text":1606,"config":1607},"Preise",{"href":1608,"dataGaName":1609,"dataGaLocation":1458,"dataNavLevelOne":1609},"/de-de/pricing/","pricing",{"text":1611,"config":1612,"menu":1614},"Ressourcen",{"dataNavLevelOne":1613},"resources",{"type":1509,"link":1615,"columns":1619,"feature":1711},{"text":1616,"config":1617},"Alle Ressourcen anzeigen",{"href":1618,"dataGaName":1613,"dataGaLocation":1458},"/de-de/resources/",[1620,1652,1679],{"title":1621,"items":1622},"Erste Schritte",[1623,1628,1633,1638,1643,1648],{"text":1624,"config":1625},"Installieren",{"href":1626,"dataGaName":1627,"dataGaLocation":1458},"/de-de/install/","install",{"text":1629,"config":1630},"Kurzanleitungen",{"href":1631,"dataGaName":1632,"dataGaLocation":1458},"/de-de/get-started/","quick setup checklists",{"text":1634,"config":1635},"Lernen",{"href":1636,"dataGaLocation":1458,"dataGaName":1637},"https://university.gitlab.com/","learn",{"text":1639,"config":1640},"Produktdokumentation",{"href":1641,"dataGaName":1642,"dataGaLocation":1458},"https://docs.gitlab.com/","product documentation",{"text":1644,"config":1645},"Best-Practice-Videos",{"href":1646,"dataGaName":1647,"dataGaLocation":1458},"/de-de/getting-started-videos/","best practice videos",{"text":1649,"config":1650},"Integrationen",{"href":1651,"dataGaName":1443,"dataGaLocation":1458},"/de-de/integrations/",{"title":1653,"items":1654},"Entdecken",[1655,1660,1665,1670,1674],{"text":1656,"config":1657},"Kundenerfolge",{"href":1658,"dataGaName":1659,"dataGaLocation":1458},"/de-de/customers/","customer success stories",{"text":1661,"config":1662},"Blog",{"href":1663,"dataGaName":1664,"dataGaLocation":1458},"/de-de/blog/","blog",{"text":1666,"config":1667},"Demo-Hub",{"href":1668,"dataGaName":1669,"dataGaLocation":1458},"/de-de/demo-hub/","demo hub",{"text":1671,"config":1672},"The Source",{"href":1673,"dataGaName":1664,"dataGaLocation":1458},"/de-de/the-source/",{"text":1675,"config":1676},"Remote",{"href":1677,"dataGaName":1678,"dataGaLocation":1458},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1680,"items":1681},"Vernetzen",[1682,1687,1692,1697,1702,1707],{"text":1683,"config":1684},"GitLab-Services",{"href":1685,"dataGaName":1686,"dataGaLocation":1458},"/de-de/services/","services",{"text":1688,"config":1689},"Beitragen",{"href":1690,"dataGaName":1691,"dataGaLocation":1458},"https://contributors.gitlab.com","contribute",{"text":1693,"config":1694},"Community",{"href":1695,"dataGaName":1696,"dataGaLocation":1458},"/community/","community",{"text":1698,"config":1699},"Forum",{"href":1700,"dataGaName":1701,"dataGaLocation":1458},"https://forum.gitlab.com/","forum",{"text":1703,"config":1704},"Veranstaltungen",{"href":1705,"dataGaName":1706,"dataGaLocation":1458},"/events/","events",{"text":1708,"config":1709},"Partner",{"href":1710,"dataGaName":1444,"dataGaLocation":1458},"/de-de/partners/",{"config":1712,"title":1715,"text":1716,"link":1717},{"background":1713,"textColor":1714},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Neues bei GitLab","Über die neuesten Funktionen und Verbesserungen auf dem Laufenden bleiben.",{"text":1718,"config":1719},"Aktuelle Nachrichten",{"href":1720,"dataGaName":1721,"dataGaLocation":1458},"/de-de/whats-new/","whats new",{"text":1723,"config":1724,"menu":1726},"Unternehmen",{"dataNavLevelOne":1725},"company",{"type":1509,"columns":1727},[1728],{"items":1729},[1730,1735,1741,1743,1748,1753,1758,1763,1768,1773],{"text":1731,"config":1732},"Über",{"href":1733,"dataGaName":1734,"dataGaLocation":1458},"/de-de/company/","about",{"text":1736,"config":1737,"footerGa":1740},"Karriere",{"href":1738,"dataGaName":1739,"dataGaLocation":1458},"/jobs/","jobs",{"dataGaName":1739},{"text":1703,"config":1742},{"href":1705,"dataGaName":1706,"dataGaLocation":1458},{"text":1744,"config":1745},"Geschäftsführung",{"href":1746,"dataGaName":1747,"dataGaLocation":1458},"/company/team/e-group/","leadership",{"text":1749,"config":1750},"Handbuch",{"href":1751,"dataGaName":1752,"dataGaLocation":1458},"https://handbook.gitlab.com/","handbook",{"text":1754,"config":1755},"Investor Relations",{"href":1756,"dataGaName":1757,"dataGaLocation":1458},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1759,"config":1760},"Trust Center",{"href":1761,"dataGaName":1762,"dataGaLocation":1458},"/de-de/security/","trust center",{"text":1764,"config":1765},"AI Transparency Center",{"href":1766,"dataGaName":1767,"dataGaLocation":1458},"/de-de/ai-transparency-center/","ai transparency center",{"text":1769,"config":1770},"Newsletter",{"href":1771,"dataGaName":1772,"dataGaLocation":1458},"/company/contact/#contact-forms","newsletter",{"text":1774,"config":1775},"Presse",{"href":1776,"dataGaName":1777,"dataGaLocation":1458},"/press/","press",{"text":1779,"config":1780,"menu":1781},"Kontakt",{"dataNavLevelOne":1725},{"type":1509,"columns":1782},[1783],{"items":1784},[1785,1790,1795],{"text":1786,"config":1787},"Vertrieb kontaktieren",{"href":1788,"dataGaName":1789,"dataGaLocation":1458},"/de-de/sales/","talk to sales",{"text":1791,"config":1792},"Support-Portal",{"href":1793,"dataGaName":1794,"dataGaLocation":1458},"https://support.gitlab.com/hc/en-us","support portal",{"text":1796,"config":1797},"Kundenportal",{"href":1798,"dataGaName":1799,"dataGaLocation":1458},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1801,"login":1802,"suggestions":1809},"Schließen",{"text":1803,"link":1804},"Um Repositorys und Projekte zu durchsuchen, melde dich an bei",{"text":1805,"config":1806},"gitlab.com",{"href":1472,"dataGaName":1807,"dataGaLocation":1808},"search login","search",{"text":1810,"default":1811},"Vorschläge",[1812,1814,1819,1821,1826,1831],{"text":1489,"config":1813},{"href":1494,"dataGaName":1489,"dataGaLocation":1808},{"text":1815,"config":1816},"Codevorschläge (KI)",{"href":1817,"dataGaName":1818,"dataGaLocation":1808},"/de-de/solutions/code-suggestions/","Code Suggestions (AI)",{"text":1447,"config":1820},{"href":1526,"dataGaName":1447,"dataGaLocation":1808},{"text":1822,"config":1823},"GitLab auf AWS",{"href":1824,"dataGaName":1825,"dataGaLocation":1808},"/de-de/partners/technology-partners/aws/","GitLab on AWS",{"text":1827,"config":1828},"GitLab auf Google Cloud",{"href":1829,"dataGaName":1830,"dataGaLocation":1808},"/de-de/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":1497,"config":1832},{"href":1502,"dataGaName":1833,"dataGaLocation":1808},"Why GitLab?",{"freeTrial":1835,"mobileIcon":1840,"desktopIcon":1845,"secondaryButton":1848},{"text":1836,"config":1837},"Kostenlos testen",{"href":1838,"dataGaName":1463,"dataGaLocation":1839},"https://gitlab.com/-/trials/new/","nav",{"altText":1841,"config":1842},"GitLab-Symbol",{"src":1843,"dataGaName":1844,"dataGaLocation":1839},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1841,"config":1846},{"src":1847,"dataGaName":1844,"dataGaLocation":1839},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1621,"config":1849},{"href":1850,"dataGaName":1851,"dataGaLocation":1839},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de/get-started/","get started",{"freeTrial":1853,"mobileIcon":1857,"desktopIcon":1859},{"text":1854,"config":1855},"Mehr über GitLab Duo erfahren",{"href":1494,"dataGaName":1856,"dataGaLocation":1839},"gitlab duo",{"altText":1841,"config":1858},{"src":1843,"dataGaName":1844,"dataGaLocation":1839},{"altText":1841,"config":1860},{"src":1847,"dataGaName":1844,"dataGaLocation":1839},{"button":1862,"mobileIcon":1867,"desktopIcon":1869},{"text":1863,"config":1864},"/Option",{"href":1865,"dataGaName":1866,"dataGaLocation":1839},"#contact","switch",{"altText":1841,"config":1868},{"src":1843,"dataGaName":1844,"dataGaLocation":1839},{"altText":1841,"config":1870},{"src":1871,"dataGaName":1844,"dataGaLocation":1839},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1873,"mobileIcon":1878,"desktopIcon":1880},{"text":1874,"config":1875},"Zurück zur Preisübersicht",{"href":1608,"dataGaName":1876,"dataGaLocation":1839,"icon":1877},"back to pricing","GoBack",{"altText":1841,"config":1879},{"src":1843,"dataGaName":1844,"dataGaLocation":1839},{"altText":1841,"config":1881},{"src":1847,"dataGaName":1844,"dataGaLocation":1839},{"title":1883,"button":1884,"config":1888},"GitLab Orbit ist da: die Kontextebene für KI-Agenten",{"text":1500,"config":1885},{"href":1886,"dataGaName":1887,"dataGaLocation":1458},"/de-de/gitlab-orbit/","orbit",{"layout":1889,"disabled":1436},"release",{"data":1891},{"text":1892,"source":1893,"edit":1899,"contribute":1904,"config":1909,"items":1914,"minimal":2120},"Git ist eine Marke von Software Freedom Conservancy und unsere Verwendung von „GitLab“ erfolgt unter Lizenz.",{"text":1894,"config":1895},"Quelltext der Seite anzeigen",{"href":1896,"dataGaName":1897,"dataGaLocation":1898},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1900,"config":1901},"Diese Seite bearbeiten",{"href":1902,"dataGaName":1903,"dataGaLocation":1898},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1905,"config":1906},"Beteilige dich",{"href":1907,"dataGaName":1908,"dataGaLocation":1898},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1910,"facebook":1911,"youtube":1912,"linkedin":1913},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1915,1960,2013,2055,2087],{"title":1606,"links":1916,"subMenu":1931},[1917,1921,1926],{"text":1918,"config":1919},"Tarife anzeigen",{"href":1608,"dataGaName":1920,"dataGaLocation":1898},"view plans",{"text":1922,"config":1923},"Vorteile von Premium",{"href":1924,"dataGaName":1925,"dataGaLocation":1898},"/de-de/pricing/premium/","why premium",{"text":1927,"config":1928},"Vorteile von Ultimate",{"href":1929,"dataGaName":1930,"dataGaLocation":1898},"/de-de/pricing/ultimate/","why ultimate",[1932],{"title":1779,"links":1933},[1934,1936,1938,1940,1945,1950,1955],{"text":1786,"config":1935},{"href":1788,"dataGaName":1468,"dataGaLocation":1898},{"text":1791,"config":1937},{"href":1793,"dataGaName":1794,"dataGaLocation":1898},{"text":1796,"config":1939},{"href":1798,"dataGaName":1799,"dataGaLocation":1898},{"text":1941,"config":1942},"Status",{"href":1943,"dataGaName":1944,"dataGaLocation":1898},"https://status.gitlab.com/","status",{"text":1946,"config":1947},"Nutzungsbedingungen",{"href":1948,"dataGaName":1949,"dataGaLocation":1898},"/terms/","terms of use",{"text":1951,"config":1952},"Datenschutzerklärung",{"href":1953,"dataGaName":1954,"dataGaLocation":1898},"/de-de/privacy/","privacy statement",{"text":1956,"config":1957},"Cookie-Einstellungen",{"dataGaName":1958,"dataGaLocation":1898,"id":1959,"isOneTrustButton":1048},"cookie preferences","ot-sdk-btn",{"title":1505,"links":1961,"subMenu":1970},[1962,1966],{"text":1963,"config":1964},"DevSecOps-Plattform",{"href":1487,"dataGaName":1965,"dataGaLocation":1898},"devsecops platform",{"text":1967,"config":1968},"KI-unterstützte Entwicklung",{"href":1494,"dataGaName":1969,"dataGaLocation":1898},"ai-assisted development",[1971],{"title":1972,"links":1973},"Themen",[1974,1978,1983,1988,1993,1998,2003,2008],{"text":1447,"config":1975},{"href":1976,"dataGaName":1977,"dataGaLocation":1898},"/de-de/topics/ci-cd/","cicd",{"text":1979,"config":1980},"GitOps",{"href":1981,"dataGaName":1982,"dataGaLocation":1898},"/de-de/topics/gitops/","gitops",{"text":1984,"config":1985},"DevOps",{"href":1986,"dataGaName":1987,"dataGaLocation":1898},"/de-de/topics/devops/","devops",{"text":1989,"config":1990},"Versionskontrolle",{"href":1991,"dataGaName":1992,"dataGaLocation":1898},"/de-de/topics/version-control/","version control",{"text":1994,"config":1995},"DevSecOps",{"href":1996,"dataGaName":1997,"dataGaLocation":1898},"/de-de/topics/devsecops/","devsecops",{"text":1999,"config":2000},"Cloud-nativ",{"href":2001,"dataGaName":2002,"dataGaLocation":1898},"/de-de/topics/cloud-native/","cloud native",{"text":2004,"config":2005},"KI für das Programmieren",{"href":2006,"dataGaName":2007,"dataGaLocation":1898},"/de-de/topics/devops/ai-for-coding/","ai for coding",{"text":2009,"config":2010},"Agentische KI",{"href":2011,"dataGaName":2012,"dataGaLocation":1898},"/de-de/topics/agentic-ai/","agentic ai",{"title":2014,"links":2015},"Lösungen",[2016,2019,2021,2026,2030,2033,2036,2039,2041,2043,2045,2050],{"text":1549,"config":2017},{"href":1544,"dataGaName":2018,"dataGaLocation":1898},"Application Security Testing",{"text":1536,"config":2020},{"href":1521,"dataGaName":1522,"dataGaLocation":1898},{"text":2022,"config":2023},"Agile Entwicklung",{"href":2024,"dataGaName":2025,"dataGaLocation":1898},"/de-de/solutions/agile-delivery/","agile delivery",{"text":2027,"config":2028},"SCM",{"href":1533,"dataGaName":2029,"dataGaLocation":1898},"source code management",{"text":1447,"config":2031},{"href":1526,"dataGaName":2032,"dataGaLocation":1898},"continuous integration & delivery",{"text":1575,"config":2034},{"href":1577,"dataGaName":2035,"dataGaLocation":1898},"value stream management",{"text":1979,"config":2037},{"href":2038,"dataGaName":1982,"dataGaLocation":1898},"/de-de/solutions/gitops/",{"text":1588,"config":2040},{"href":1591,"dataGaName":1592,"dataGaLocation":1898},{"text":1594,"config":2042},{"href":1597,"dataGaName":1598,"dataGaLocation":1898},{"text":1600,"config":2044},{"href":1603,"dataGaName":1604,"dataGaLocation":1898},{"text":2046,"config":2047},"Bildungswesen",{"href":2048,"dataGaName":2049,"dataGaLocation":1898},"/de-de/solutions/education/","education",{"text":2051,"config":2052},"Finanzdienstleistungen",{"href":2053,"dataGaName":2054,"dataGaLocation":1898},"/de-de/solutions/finance/","financial services",{"title":1611,"links":2056},[2057,2059,2061,2063,2066,2068,2071,2073,2075,2077,2079,2081,2083,2085],{"text":1624,"config":2058},{"href":1626,"dataGaName":1627,"dataGaLocation":1898},{"text":1629,"config":2060},{"href":1631,"dataGaName":1632,"dataGaLocation":1898},{"text":1634,"config":2062},{"href":1636,"dataGaName":1637,"dataGaLocation":1898},{"text":1639,"config":2064},{"href":1641,"dataGaName":2065,"dataGaLocation":1898},"docs",{"text":1661,"config":2067},{"href":1663,"dataGaName":1664,"dataGaLocation":1898},{"text":2069,"config":2070},"Neuerungen",{"href":1720,"dataGaName":1721,"dataGaLocation":1898},{"text":1656,"config":2072},{"href":1658,"dataGaName":1659,"dataGaLocation":1898},{"text":1675,"config":2074},{"href":1677,"dataGaName":1678,"dataGaLocation":1898},{"text":1683,"config":2076},{"href":1685,"dataGaName":1686,"dataGaLocation":1898},{"text":1688,"config":2078},{"href":1690,"dataGaName":1691,"dataGaLocation":1898},{"text":1693,"config":2080},{"href":1695,"dataGaName":1696,"dataGaLocation":1898},{"text":1698,"config":2082},{"href":1700,"dataGaName":1701,"dataGaLocation":1898},{"text":1703,"config":2084},{"href":1705,"dataGaName":1706,"dataGaLocation":1898},{"text":1708,"config":2086},{"href":1710,"dataGaName":1444,"dataGaLocation":1898},{"title":1723,"links":2088},[2089,2091,2093,2095,2097,2099,2104,2109,2111,2113,2115],{"text":1731,"config":2090},{"href":1733,"dataGaName":1725,"dataGaLocation":1898},{"text":1736,"config":2092},{"href":1738,"dataGaName":1739,"dataGaLocation":1898},{"text":1744,"config":2094},{"href":1746,"dataGaName":1747,"dataGaLocation":1898},{"text":1749,"config":2096},{"href":1751,"dataGaName":1752,"dataGaLocation":1898},{"text":1754,"config":2098},{"href":1756,"dataGaName":1757,"dataGaLocation":1898},{"text":2100,"config":2101},"Nachhaltigkeit",{"href":2102,"dataGaName":2103,"dataGaLocation":1898},"/sustainability/","Sustainability",{"text":2105,"config":2106},"Vielfalt, Inklusion und Zugehörigkeit",{"href":2107,"dataGaName":2108,"dataGaLocation":1898},"/de-de/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1759,"config":2110},{"href":1761,"dataGaName":1762,"dataGaLocation":1898},{"text":1769,"config":2112},{"href":1771,"dataGaName":1772,"dataGaLocation":1898},{"text":1774,"config":2114},{"href":1776,"dataGaName":1777,"dataGaLocation":1898},{"text":2116,"config":2117},"Transparenzerklärung zu moderner Sklaverei",{"href":2118,"dataGaName":2119,"dataGaLocation":1898},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2121},[2122,2125,2128],{"text":2123,"config":2124},"Terms",{"href":1948,"dataGaName":1949,"dataGaLocation":1898},{"text":2126,"config":2127},"Cookies",{"dataGaName":1958,"dataGaLocation":1898,"id":1959,"isOneTrustButton":1048},{"text":2129,"config":2130},"Datenschutz",{"href":1953,"dataGaName":1954,"dataGaLocation":1898},[2132],{"id":2133,"title":7,"body":1431,"config":2134,"content":2136,"description":1431,"extension":2140,"meta":2141,"navigation":1048,"path":2142,"seo":2143,"stem":2144,"__hash__":2145},"blogAuthors/en-us/blog/authors/tim-rizzi.yml",{"template":2135},"BlogAuthor",{"name":7,"config":2137},{"headshot":2138,"ctfId":2139},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661866/Blog/Author%20Headshots/trizzi-headshot.jpg","trizzi","yml",{},"/en-us/blog/authors/tim-rizzi",{},"en-us/blog/authors/tim-rizzi","ADPqrpcnKveFJS0m_zFV0VLtb_h_txu59QVgz_YwKMc",[2147,2155,2163],{"title":2148,"description":2149,"heroImage":2150,"category":1427,"date":2151,"authors":2152,"slug":2154,"externalUrl":1431},"Wie GitLab Schwachstellen über Refactorings hinweg verfolgt","Das verbesserte Scope+Offset-Fingerprinting hält das Tracking stabil, wenn Kommentare, Leerzeilen oder Reformatierungen dazukommen.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1759320418/xjmqcozxzt4frx0hori3.png","2026-08-12",[2153],"Julian Thome","improved-scope-offset-fingerprinting",{"title":2156,"description":2157,"heroImage":2150,"category":1427,"date":2158,"authors":2159,"slug":2162,"externalUrl":1431},"GitLab Secrets Manager unterstützt ESO, Terraform und API","GitLab Secrets Manager liefert Secrets sicher an Kubernetes, Terraform und externe Workflows, aus einer einzigen Quelle für die gesamte Toolchain.","2026-08-06",[2160,2161],"Erick Bajao","Joe Randazzo","gitlab-secrets-manager-add-eso-terraform-api-support",{"title":2164,"description":2165,"heroImage":2166,"category":1427,"date":2167,"authors":2168,"slug":2170,"externalUrl":1431},"Mit Claude und GitLab jeden Commit bis zur Produktion absichern","Claude Security findet Schwachstellen in der Coding-Session. GitLab übernimmt danach: Scans, Policy-Durchsetzung und Audit-Nachweise im Lebenszyklus.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1756122536/akivvcnafog9c4dhhzkp.png","2026-08-03",[2169],"Alisa Ho","claude-security-and-gitlab",{"promotions":2172},[2173,2187,2199,2210],{"id":2174,"categories":2175,"header":2177,"text":2178,"button":2179,"image":2184},"ai-modernization",[2176],"ai","Hält KI, was uns versprochen wurde?","Das Quiz dauert maximal 5 Minuten.",{"text":2180,"config":2181},"Ermittle deinen KI-Reifegrad",{"href":2182,"dataGaName":2183,"dataGaLocation":1664},"/de-de/assessments/ai-modernization-assessment/","modernization assessment",{"config":2185},{"src":2186},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2188,"categories":2189,"header":2191,"text":2178,"button":2192,"image":2196},"devops-modernization",[2190,1997],"product","Verwaltest du Tool-Chaos oder stellst du Innovationen bereit?",{"text":2193,"config":2194},"Ermittle deinen DevOps-Reifegrad",{"href":2195,"dataGaName":2183,"dataGaLocation":1664},"/de-de/assessments/devops-modernization-assessment/",{"config":2197},{"src":2198},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2200,"categories":2201,"header":2202,"text":2178,"button":2203,"image":2207},"security-modernization",[1427],"Tauschst du Schnelligkeit gegen Sicherheit ein?",{"text":2204,"config":2205},"Ermittle deinen Sicherheitsreifegrad",{"href":2206,"dataGaName":2183,"dataGaLocation":1664},"/de-de/assessments/security-modernization-assessment/",{"config":2208},{"src":2209},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2211,"paths":2212,"header":2215,"text":2216,"button":2217,"image":2222},"github-azure-migration",[2213,2214],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Ist dein Team bereit für den Umzug von GitHub nach Azure?","GitHub stellt bereits auf Azure um. Finde heraus, was das für dich bedeutet.",{"text":2218,"config":2219},"Erfahre, wie GitLab im Vergleich zu GitHub abschneidet",{"href":2220,"dataGaName":2221,"dataGaLocation":1664},"/de-de/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2223},{"src":2198},{"header":2225,"blurb":2226,"button":2227,"secondaryButton":2232},"Beginne noch heute, schneller zu entwickeln","Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.\n",{"text":2228,"config":2229},"Kostenlosen Test starten",{"href":2230,"dataGaName":1463,"dataGaLocation":2231},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/de-de/","feature",{"text":1786,"config":2233},{"href":1788,"dataGaName":1468,"dataGaLocation":2231},1786803749969]