Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nye ambisjoner for Nais CLIet #513

Open
frodesundby opened this issue Feb 13, 2025 · 8 comments
Open

Nye ambisjoner for Nais CLIet #513

frodesundby opened this issue Feb 13, 2025 · 8 comments

Comments

@frodesundby
Copy link
Contributor

Dette issuet beskriver den overordnede ambisjonen for Nais CLIet.
Her samler vi hovedtrekkene, retningen og har oversikt over rekkefølgen på oppgavene.

Dette er moder-issuet, som refereres til fra de konkrete initiativene som vil spinne ut i fra dette.

Essensen

Vi ønsker å gjøre kommandolinja til en førsteklasses flate ut i mot brukerene våre, slik Console er i dag.
I det ligger det at vi ønsker å samle eksisterende funksjonalitet, samt legge til nye funksjoner slik at man får ett enkelt CLI å forholde seg til.
Ved å utvide funksjonaliteten, kan vi også forenkle bruker-reisen betraktelig ved å kutte avhengigheter til andre CLIer som vi lener oss på i dag, primært gcloud og kubectl.

Andre betraktninger

  • Vi ønsker å logge inn bruker uten å måtte ha gcloud installert.
  • Når bruker er logget inn, må vi se og finne ut av hvilken tenant og hva slags team brukeren opererer i. Dette fordrer etableringen av et konsept om kontekst. Vi tenker at bruker bevisst opererer i kontekst av et team, lignende namespace i kubectl eller prosjekt i GCP. Hvilken tenant er mer behind-the-scenes for bruker.

Førsteutkast av toppnivåkommandoer:

Her er et grovt førsteutkast av type kommandoer man ser for seg i nytt CLI (på lang sikt)

▶ nais --help
NAME:   nais - A Nais cli

COMMANDS:
   login      Login using Google Auth # For now
   device     management of naisdevice
   kubeconfig  Create a kubeconfig file for connecting to available clusters // etterhvert kan vi vurdere behovet for dette 

   postgres   All postgres related functionality
   bucket     All bucket related functionality
   bigquery   All bigquery related functionality
   valkey     All valkey related functionality
   opensearch All opensearch related functionality

   team       All team related functionality
   app        All app related functionality
   job        All job related functionality
   cdn        All CDN related functionality

   # CI tools
   init       Generates template files for CI and Workload
   build      Builds Dockerfile and tags image
   sign       Signs and attests a built image (working title)
   push       Push a signed image and SBOM to GAR
   deploy     deploys yaml-file(s) to an environment # Existing nais deploy cli functionality
   run        Builds Dockerfile, signs, pushes and deploys valid yaml-file(s) to environment
   validate   Validate nais.yaml configuration

   #aiven       Command used for management of AivenApplication // deles opp og presenteres som individuelle tjenester
   #debug       Create and attach to a debug container // flyttes under app

Steg på veien / milepæler

1. Konsolidere eksisterende CI-funksjonalitet / nais run

Samle eksisterende kommandolinjeverktøy og GitHub Actions-tooling til én binary.
Dette vil gi bedre støtte for Nais CI gjennom lokal utvikling, som blir så og si identisk med det som skjer på GitHub.
I tillegg kan vi støtte flere ulike miljøer hos våre tenants, som bruker andre ting enn GitHub, f.eks Azure DevOps og GitLab. Ved å tilby Nais-funksjonalitet fra en enkelt binær, kan vi på sikt ha samme syntaks og dokumentasjon på tvers av ulike Git- og CI-tilbydere.

Ved å samle CI-relatert funksjonalitet som i dag gjøres i docker-build-push, samt deploy CLI/nais deploy action i CLIet, muliggjør vi:

  • Lokal bygg og deploy til Nais
  • Bygg og deploy på alle CI-pipeline verktøy, ikke bare GitHub Actions. (bonus: vi slipper vedlikeholde to actions)

    Det at dette oppfører seg likt, gjør at det blir så godt som sømløs overgang fra å si "få dette greiene jeg har lokalt i min mappe nå til å kjøre på Nais", til å si: "ta tilstanden i dette repositoriet til å kjøre på Nais". 
Altså: "kjør dette på Nais" -> nais run.

Ønsket utfall:

  • CLI har kommandoer for bygg, sign og deploy
  • nais/docker-build-push deprecated
  • nais/deploy/actions/deploy deprecated
  • Etablere GitHub action nais/setup som laster ned og cacher Nais CLI binary, inspirert av fly.
  • Ny dokumentasjon for hvordan bygge og deploye med dette fra GitHub
  • Ny dokumentasjon for hvordan bygge og deploye med dette fra andre versjonskontroll-as-a-service'er
  • Ny dokumentasjon for hvordan bygge og deploye med dette fra lokal maskin
  • Bygge inn funksjonaliteten vi trenger fra gcloud-kommandoen.
  • Automatisk deteksjon og bruk av credentials, både lokalt og på GitHub
  • Windows-, Debian- og Homebrew-pakker

Eksempel på ny GitHub Actions-syntaks:

- uses: nais/setup@v1   # setup Nais tooling
- run: nais ci deploy   # run Nais build and deploy application to k8s

2. Nais login

Ønsket utfall:

  • Autoriserer som bruker ved hjelp av personlig google-konto
  • Autorisere som ServiceAccount (nais-api SA som erstatter deploy-key)
  • Autorisere som GitHub-Workflow (jwt) (Eventuelt også andre (GitLab?) på sikt)

Både brukere og serviceAccounts bør ha en uniform login-mekanisme for å kunne utføre det CLI’et tilbyr av funksjonalitet.
nais login autentiserer og autoriserer:

  • Push til GAR
  • Signering og attestering
  • Deploy på vegne av team med SA
  • Øvrig funksjonalitet i nais API
    Det er ikke ønskelig å avvikle dagens nøkkelløse deploy.

3. Hjelpe team i gang med nais (nais init)

Vi kan forenkle oppstartsreisen for nye team og applikasjoner ved å tilby CLI-funksjonalitet

nais init starter en hjelper som stiller relevante spørsmål for å komme frem til "riktig" app eller job-spec
Det er viktig å unngå spørsmål som ikke er relevante for brukeren for å unngå spørsmålsfatigue.
Resultatet som presenteres er en ferdig <workload>.yaml som legges i ./nais

En annen utvidelse kan være å hjelpe til med å bygge workflow.yaml

Eksempel på deler av flyten
Hovedpoenget er å gruppere funksjonaliteten vår og presentere det på en naturlig måte for brukerene våre.
De viktigste grupperingene er:
Ressurser og skalering

  • Hvordan vil du skalere appen?
  • Hvor mye minne/cpu vil den trenge?
  • Ender i ferdig konfigurert resources og replicas
    Kommunikasjon
  • Er det noen som skal kommunisere med appen din?
mennesker? maskiner? begge? internt / ekstern?
  • Skal appen din kommunisere med andre?
tokens? internt? eksternt? endepunkter?
    Disse spørsmålene kan struktureres i ett tre, og bør ende opp i ferdig konfigurasjon for bl.a. auth, ingresses og accessPolicies.
    Persistens
  • postgres, kafka, bucket, bq, valkey, opensearch?
    Defaults
    Bruker den nais standarder? port: 8080, metrikker på /metrics, isalive på /isalive, isready etc?
    +Hemmeligheter? +Miljøvariabler?

4. Utvide med Nais console/API funksjonalitet

Det er naturlig å kunne gjøre en del av de tingene man gjør i Console gjennom CLI-et også, for eksempel:

  • List og describe av ressurser
  • Status på team og applikasjon
  • Vulnerabilities på team og applikasjon
  • Slette og restarte app
  • Administrere teammedlemmer
  • Sjekke logger
  • Autoriserer GitHub-repo til team
    Dette implementeres gjennom å gjøre kall til Nais API.
@Reasonable-Solutions
Copy link
Contributor

Local builds

first things first: Here i would be worried about a developer machine being compromised and
used to deploy (signed!) artifacts into the production environments of our tenants.

In theory i am, unsurprisingly, pro local builds (reproducible and verifiable local builds).
In reality, it's a poor practice and we should not support it.

nais ci build etc

Please don't. Users should not be able to build and deploy.
you get

  1. Lack of reproducibility
  2. Security vulnerabilities
  3. Inconsistent environments
  4. Poor audit trails

in addition to difficulties talking about provenance. SLSA level 2 requires a build platform for all artifacts and I expect to be the standard from a regulatory perspective going forward.

Build stuff for CI needs to be in CI.

push Push a signed image and SBOM to GAR

This is exactly the same problem as above. If there is no provenance the signature means nothing. "I built something somehow and now it's running in production".

the CI stuff should be separate affair for trusted (and hardened!) build platforms. see https://slsa.dev/spec/v1.1/levels

@jhrv
Copy link
Contributor

jhrv commented Feb 13, 2025

Så det du mener er at ingen kjørende workloads i clusteret skal være uten SBOM og provenance?

Jeg tenker at i en lokal utviklingssetting er reproduserbarhet et poeng som ikke helt gir mening. Det er ingenting iboende i det å kjøre fra lokal maskin som betyr at det ikke kan reproduseres. Det som skal i produksjon vil jo normalt sett uansett kjøres via pipelines og bygges fra main.

Hvis vi kan etter bygging av image, verifisere at dette ble bygget av en autentisert nais-bruker (kan vi gjøre det via Fulcio?) tenker jeg det vil være godt nok.

@Reasonable-Solutions
Copy link
Contributor

What i mean is exactly the first sentence:

first things first: Here i would be worried about a developer machine being compromised and
used to deploy (signed! [or otherwise]) artifacts into the production environments of our tenants.

Hvis vi kan etter bygging av image, verifisere at dette ble bygget av en autentisert nais-bruker (kan vi gjøre det via Fulcio?) tenker jeg det vil være godt nok.

(kan vi gjøre det via Fulcio?)

nope. signatures give you:

  1. Proof of origin - confirms that the holder of the private key created/approved the artifact. The holder of the key here is anyone with access to the machine. Threat actor or legitimate user.
  2. Integrity verification - ensures content hasn't been tampered with since signing ( you can still sign random threat actor content)
  3. Non-repudiation - you can't deny having signed it later, except when you have compromised keys.

it does not give you:

  1. The actual security/safety of the content
  2. That the signer is who they claim to be. (modulo verifiable indentities, but a compromised machine is still compromised!)
  3. Protection against third party key escrow ;)

if you want to say "signature is good enough" you want:

  • machine identity via tpm or similar
  • Secure build environments (so you're not signing compromised images)
  • Build provenance attestations (so you know how and when and where it was built)

I would be hesitant to allow developer machines to deploy and would much prefer that we lean in on the industry best practice of using dedicated build systems for producing artifacts.

@jhrv
Copy link
Contributor

jhrv commented Feb 14, 2025

Ok, men skjønner jeg litt mer hva du mener.

I dag har vi ingen som helst krav til hvor imaget som kjører i clusteret ble bygget. Eneste vi vet i dag om imaget, er at det kommer fra våres image registry, og med det kan utlede at det ble pushet av noen med tilgang.

Selv om det hadde vært bra å kunne si at alle kjørende images i clusteret har en provenance fra et sted som f.eks github actions (er det bra nok?), så er det veldig langt unna der vi er i dag. Jeg tenker det bør bli en separat diskusjon i teamet, ledet an av @ybelMekk @tommytroen, så vi kan være litt mer samla rundt hvilken linje vi skal legge oss på her.

Tanken i forbindelse med dette initiativet var at vi gjorde det et par knepp bedre ved å bruke brukerens egen identitet når man genererer SBOM. Siden man må være innlogget bruker, og vi har compliant device krav på innlogging, så skjer det jo fra en maskin vi ellers stoler nok på til å slippe rett inn i clusteret til å gjøre alle operasjoner der inne.

@Reasonable-Solutions
Copy link
Contributor

note that deciding on slsa level is mentioned in the closed issue "proactive tenant security posture" (which was originally supposed to be about only that). Imo there's really not much to decide on here, the space if you go by the spec has levels 0-4.
We're at 0.7 or somesuch and we should move to 2. ~distribute and verify build provenance on hosted runners.
We are a large org and, as you said, we already have all normal deploys from github actions. The benefits of putting ourselves at level 2 would be, quoting from the spec :
"
Prevents tampering after the build

Deters adversaries who face legal or financial risk by evading security controls, such as employees who face risk of getting fired.

Reduces attack surface by limiting builds to specific build platforms that can be audited and hardened.
"
Since builds normally already happens on the runners the deterrence and attack surface bits come at a very low cost to our users.

@jhrv
Copy link
Contributor

jhrv commented Feb 14, 2025

Syns du har mange gode poenger, men vi må innom noen steg før vi er der at dette kan låses ned. En god start tenker jeg er at @ybelMekk / @tommytroen kaller inn til en prat

@ybelMekk
Copy link
Contributor

Jeg synes diskusjonen er nyttig, og det er viktig at vi alle er bevisste på hva vi ønsker å oppnå med det vi lar kjøre i klustrene.

La meg først si litt om SLSA-nivået.

For øyeblikket er vi på SLSA nivå 2+ og ikke 0.7 som beskrevet tidligere.

SLSA nivå 2 krever at byggeprosessen er automatisert, som vanligvis skjer gjennom CI/CD-pipelines som GitHub Actions eller GitLab CI. Manuelle bygg (for eksempel ved hjelp av en CLI eller et lokalt skript) er ikke tilstrekkelige for nivå 2. Hvis vi kan flagge dette på en måte i Nais Console, kan det være et pluss. Vi kan bruke nivå 1 for testing, men for produksjon bør vi egentlig kreve nivå 2 eller høyere.

Bygget må også produsere signert provenance, ved bruk av verktøy som Cosign, som beskrevet tidligere, som beskriver byggeomgivelsene, avhengighetene og det resulterende artefaktet.

Denne provenance-en må være verifiserbar og knyttet til byggeprosessen. Hvis en bruker signerer lokalt, kan dette ikke verifiseres tilbake til byggeprosessen, som er tilfelle i dag. Når man signerer lokalt, introduseres også et ekstra steg hvor brukeren må logge seg inn med Google (gjennom Sigstore) for å få signert et image.

Som et startpunkt er dette veldig nyttig i test- og utviklingsmiljøer for team, men jeg ser ikke for meg at dette skal være den standardiserte løsningen i produksjon. Da bør det, som Johnny påpeker, brukes i en pipeline av et eller annet slag.

I tillegg må signerte artefakter og metadata lagres i transparenslogger (som Rekor), noe som gir bevis på at signaturen er opprettet og at artefaktet kommer fra en pålitelig kilde. Dette hindrer manipulering og gjør det mulig for andre å verifisere artefaktene uavhengig. Tjenester som Rekor lagrer informasjon om dem som har signert (epost), men det er mulig å hoste sin egen Rekor?

Når vi gjør ting gjennom en pipeline som GitHub, har vi spårbarhet på hvem som gjorde comitten, og gjennom metadata i signaturen kan vi se nøyaktig hvilken commit den kommer fra, akkurat hvilket image og når. Det er verdt å påpeke at komprimerte innloggingsdetaljer også kan være tilgjengelig i GitHub, akkurat som de kan være for et lokalt signert artefakt.

La oss diskutere dette videre, men som nevnt støtter jeg dette i test/dev. Jeg ser gjerne at vi har mer kontroll på hva vi setter som godkjent i produksjon, da dette potensielt kan føre til problemer dersom det ikke håndteres riktig.

@Reasonable-Solutions
Copy link
Contributor

Reasonable-Solutions commented Feb 17, 2025

For øyeblikket er vi på SLSA nivå 2+ og ikke 0.7 som beskrevet tidligere.

I think this is haggling on "having a hosted build platform" is sufficient or if i'ts necessary to use it. otoh, maybe you're right. Maybe it is about the capability rather than the practice.

Det er verdt å påpeke at komprimerte innloggingsdetaljer også kan være tilgjengelig i GitHub, akkurat som de kan være for et lokalt signert artefakt.

That is about attack surface. Local builds has the set of all developer machines over time whereas a hosted build platform with ephemeral builders have a slightly smaller attack surface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants