
Dockeri ENV võib jätta võtme image’isse — kasuta build secret’it

Kui API-võtit või parooli on vaja ainult image’i ehitamisel, eemalda see Dockerfile’i ARG- ja ENV-käskudest ning anna ehitusele ajutise secret mount’ina. Dockeri build secret’i juhend hoiatab, et ARG ja ENV kaudu antud saladus võib jääda lõplikku image’isse; secret mount on kättesaadav ainult seda kasutava RUN-käsu ajal.
Kui võtit vajab töötav rakendus, anna see konteinerile käivitamisel eraldi failina või lase rakendusel see välisest saladusehoidlast hankida. Build secret ei anna töötavale konteinerile püsivat ligipääsu. Ehituse ja käivitamise eristamine aitab vältida olukorda, kus sõltuvuste laadimiseks kasutatud tunnus saadetakse kaasa iga rakenduse eksemplariga.
Miks tuleb ARG ja ENV eemaldada?
ENV-ga määratud väärtus kuulub image’i konfiguratsiooni ja jõuab sellest käivitatud konteineri keskkonda. ARG ei muutu iseenesest töötava konteineri keskkonnamuutujaks, kuid selle väärtus võib jääda ehituse ajalukku või metaandmetesse, eriti kui seda kasutatakse järgmistes käskudes. Seetõttu ei piisa ARG-i nimetamisest ajutiseks muutujaks: otsustav on see, kuhu väärtus ehituse käigus kirjutatakse.
Ka saladuse kasutamise koht loeb. Kui RUN-käsk kirjutab võtme konfiguratsioonifaili ja jätab faili image’i kihti, on võti endiselt kaasa pakitud. Ajutine mount hoiab lähtefaili sellest kihist eemal, kuid käsu enda väljund võib saladuse uuesti paljastada. Ära prindi väärtust ehituslogisse ega kopeeri seda teise faili, mis jääb valmis image’isse.
Dockerfile enne ja pärast: ehitusele vajalik tunnus
Järgnev tinglik Node.js näide laadib käsuga npm ci privaatse sõltuvuse. Eeldus on, et projektis on npm-i lukustusfail. Vanas variandis antakse registri tunnus ARG-ina, kirjutatakse npm-i konfiguratsiooni ja määratakse seejärel ENV-iga ka töötava konteineri jaoks. npm-i konfiguratsiooni kirjutamine tekitab lisaks faili, mis võib image’i jääda.
Dockerfile enne muutmist:
- FROM node:22-alpine
- WORKDIR /app
- COPY package*.json ./
- ARG NPM_TOKEN
- RUN npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN && npm ci
- COPY . .
- ENV NPM_TOKEN=$NPM_TOKEN
- CMD ["node", "server.js"]
Muudetud variandis on registri tunnus kohalikus .npmrc-failis. Fail ühendatakse npm ci ajaks sinna, kust npm seda näites loeb; Dockerfile ei sisalda tunnuse väärtust. required=true katkestab ehituse, kui vajalikku saladust ei antud.
Dockerfile pärast muutmist:
- FROM node:22-alpine
- WORKDIR /app
- COPY package*.json ./
- RUN --mount=type=secret,id=npmrc,target=/root/.npmrc,required=true npm ci
- COPY . .
- CMD ["node", "server.js"]
Selle variandi saab ehitada käsuga docker build --secret id=npmrc,src=./.npmrc -t minu-rakendus:uus . . Lähtefail peab olema ehitust käivitavas masinas või CI-töös olemas. Lisa .npmrc ja käivitamisel kasutatavate võtmete kataloog ka .dockerignore- ning .gitignore-faili. Muidu võib hilisem COPY . . tuua saladuse eraldi image’isse või võib fail sattuda lähtekoodi hoidlasse.
Näites eeldatakse, et npm töötab ehituskonteineris juurkasutajana ja loeb faili asukohast /root/.npmrc. Kui Dockerfile vahetab enne npm ci käsku kasutajat, muuda mount’i target vastavalt selle kasutaja kodukataloogile. Secret mount’i saab vajaduse korral ühendada ka ühe RUN-käsu keskkonnamuutujana, kuid faili lugev tööriist võimaldab vältida väärtuse lisamist protsessi keskkonda.
Compose’is määra ehituse ja käivitamise ligipääs eraldi
Compose’i puhul on build.args ja teenuse environment kaks eri kohta, kust saladus võib jõuda ehitusse või töötava protsessini. Järgmises tinglikus algseades läheb NPM_TOKEN ehitusele argumendina ja API_TOKEN antakse rakendusele keskkonnamuutujana. Need on eri otstarbega tunnused ning kumbagi pole vaja teise kasutusfaasi kaasa võtta.
compose.yaml enne muutmist, asjakohased read:
- services:
- app:
- build:
- context: .
- args:
- NPM_TOKEN: ${NPM_TOKEN}
- environment:
- API_TOKEN: ${API_TOKEN}
Muudetud seades lubab build.secrets kasutada .npmrc-faili image’i ehitamisel. Teenuse secrets annab töötavale rakendusele eraldi api_token-faili. Compose’i saladuste kirjeldus määrab, et faili sisu tuleb ülemise taseme secrets-kirjest ning teenus peab saama saladusele selgesõnalise ligipääsu.
compose.yaml pärast muutmist:
- services:
- app:
- build:
- context: .
- secrets:
- - npmrc
- secrets:
- - api_token
- secrets:
- npmrc:
- file: ./.npmrc
- api_token:
- file: ./secrets/api_token
Töötav rakendus peab lugema väärtuse failist /run/secrets/api_token ise või toetama seadistust, mis osutab sellele failile. Faili ühendamine üksi ei muuda rakenduse koodi. Hoia lähtefail hostis piiratud ligipääsuga ja korralda, et juurutus tooks selle õigesse kohta; Compose’i failiallikas sõltub kohaliku faili olemasolust.
Kontrolli uut image’it ja varasemaid jälgi
Enne ehitamist käivita docker build --check . . Dockeri nimepõhine kontroll võib osutada tundlikule ARG- või ENV-nimele, kuid see ei tuvasta iga võimalikku saladust. Seejärel vaata uue image’i püsivat keskkonda käsuga docker image inspect --format '{{json .Config.Env}}' minu-rakendus:uus . Väljundis ei tohiks olla NPM_TOKEN-i, API_TOKEN-i ega nende väärtusi.
Ehitusajaloo vaatamiseks kasuta käsku docker image history --no-trunc minu-rakendus:uus . Otsi tunnuse väärtust ja käske, mis võisid selle faili või käsurea kaudu image’i kirjutada. Vaata eraldi CI logisid, varasemaid image’eid ning seda, kas .npmrc või muu saladus kopeeriti varem ehituskontekstist sisse. Puhas inspect-väljund näitab üksnes kontrollitud image’i konfiguratsiooni; see ei ütle, mis on alles teistes kihtides, koopiates või logides.
Millal kasutada faili või välist saladusehoidlat?
Kui tunnust on vaja ainult privaatse sõltuvuse hankimiseks, vali build secret. Kui töötav rakendus oskab lugeda faili ja juurutus suudab selle kohale viia, sobib käivitamisel ühendatud saladusfail. Kui teenus vajab keskset õiguste haldust, auditeerimist või sagedast võtmevahetust, saab rakendus või kõrvalkomponent küsida saladuse välisest hoidlast.
OWASP saladuste haldamise juhis kirjeldab nii ühendatud faili kui ka välisest hoidlast hangitud saladust ning hoiatab, et keskkonnamuutujad võivad jõuda logidesse või süsteemitõmmistesse. Väline hoidla vajab siiski kitsaid ligipääsuõigusi: teenus peaks saama küsida ainult talle vajalikku väärtust. Ükskõik millise üleandmisviisi korral peab rakendus vältima saadud saladuse logimist.
Kui vana võti on juba image’is, vaheta see välja
Varem ARG-, ENV- või COPY-käsu kaudu image’isse jõudnud võtit käsitle võimaliku lekkega võtmena. Loo asendusvõti, vii uus üleandmisviis kasutusele, kontrolli teenuse tööd ja tühista vana võtme õigus teenusepakkuja juures esimesel võimalikul hetkel. Kui on märke väärkasutusest, on ligipääsu kiire sulgemine tähtsam kui sujuv üleminek.
Uue image’i avaldamine ega vana tag’i kustutamine ei tühista vana tunnust. Piira ligipääsu varasematele image’i koopiatele ja registritele ning korralda paljastatud väärtuse eemaldamine lähtekoodi ajaloost või logidest seal, kus seda saab teha logide terviklust säilitades. Vana võtme kehtetuks muutmine lõpetab selle kasutatavuse ka siis, kui mõni koopia jääb alles.
Loe ka:
Seotud artiklid


Bitwarden või 1Password: odavam varahoidla ei võitnud kõiki turvateste

NIST paneb AI-agentidele identiteedi: esimene katse tuleb DevSecOpsi

Replit või Lovable: odavam kuutasu ei näita valmis rakenduse kulu

Ragas või DeepEval: sama nimega mõõdikud ei anna sama kvaliteediväravat

Struktureeritud AI-väljund: JSON kehtib alles siis, kui skeem peab
Telli meie uudiskiri
Saa värskeimad Web3, AI ja krüptouudised otse oma postkasti.