Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
oci-image-builder
Advanced tools
container image builder. without docker, docker/oci registry client and image building helpers for protocol version 2, fork of container-image-builder
A container registry client and image builder with no dependency on docker. This supports protocol version 2.
This library has a few parts:
Image
class: takes care of authentication, creating new registry clients, and packaging up local files.You can do most things with the Image
class. It takes care of tedious tasks like copying layers missing from one registry into another so you can save your new image.
Create a new image based off of the official node image with your files in it.
;(async()=>{
const image = new Image('node:lts-slim','gcr.io/my-project/my-image')
// add local files to the image.
await image.addFiles({'/directory-root-for-files-in-container':"./"})
// creates a layer in the image with files like
// /directory-root-for-files-in-container/[the files in ./]
// set the default working directory for commands
image.WorkingDir = "/directory-root-for-files-in-container"
// set the default command to run in the container
image.Cmd = ["node","index.js"]
// append environment variables.
image.Env = []
// save the new image at latest
const result = await image.save()
console.log(result)
})();
You can run the image using docker, or deploy it to a docker host:
docker run gcr.io/my-project/my-image:latest
Docker hub and gcr.io have custom auth plugins. If you already have a token or username and secret you can pass them directly when making an Image client.
const image = new Image('node:lts-slim','myspecialregistry.io/my-project/my-image',{
"auth":{
'myspecialregistry.io':{
token:"xxxxxxxxxxx"
}
}
})
node:lts-slim
is a public image so no need to provide auth for docker.io
Also if you have a docker credential helper installed on the system, and in your docker config that matches the registry we'll call it before giving up.
see auth information for more.
npm install container-image-builder
Learning about this distribution api I struggled mapping the names of some of the things to things I was familiar with.
Defined in the order that they compose into an "Image":
digest
blob
layer
config
uncompressedDigest
throughout this client.manifest
Image
Container
const {Image} = require('container-image-builder')
import {Image} from 'container-image-builder'
in typescript etc.image = new Image(baseImage:string,targetImage:string|ImageOptions,options:ImageOptions)
image.addFiles({[targetDirectory]:localDirectory},options): Promise<..>
tar local directories and place each at targetDirectory in a single layer.
symlinks are replaced with their files/directories as they are written to the layer tarball by default.
options
options.ignores
options.ignoreFiles
[".ignore"]
.options.tar
you can also call it with arguments like this but you should probably use the default.
image.addFiles(localDirectory,targetDirectory,options) :Promise<..>
image.addFiles(localDirectory,options) :Promise<..>
BREAKING CHANGE between 1x AND 2x
targetDirectory
and localDirectory
were flipped in the object.targetDirectory
.image.save(tags?: string[], options)
latest
tagtags
, string[]
options
image.WorkingDir = "/custom working dir"
string
image.Cmd = ["ls","./"]
string[]
image.Env = ["HOME=/workspace"]
string[]
image.getImageConfig() Promise<{ImageConfig}>
image.save()
image.getImageData() Promise<{manifest:ImageManifest,config:ImageConfig}>
image.save()
image.client(imageSpecifier,writePermission) Promise<RegistryClient>
string
image.sync(options)
image.save()
image.addLayer(digest: string, uncompressedDigest: string, size: number,urls?: string[])
image.removeLayer(digest:string)
digest, string required
remove the layer tagged in the manifest by digest. save it's offset in the array.
remove the uncompressedDigest from the image config that matches the offset above
const {CustomFile} = require('container-image-builder')
image.addFiles({'/help.md':new CustomFile({data:Buffer.from('hello')})})
image.addFiles({'/google.html':new CustomFile({data:request('https://google.com'),size:**you must have size beforehand for streams**})})
customFile = new CustomFile(options)
0o644
owner read write, everyone read.& 0o7777
and type bits are set based on type.customFile.uid
customFile.gid
customFile.ctime
customFile.atime
customFile.mtime
auth
is provided it will be used to provided authentication metadata for calls to the specified registry. If there is no authentication provider for your particular registry you can an object with the key token as it's value.{auth:{'my.registry.io':{token?:string}}}
gcr.io
in it you can pass additional options.const {auth} = require('container-image-builder')
Authenticate to docker registries. This library has built in support for Google Container Registery (gcr.io
) and docker hub.
for all other cases it'll fall back to using docker credential helpers already installed on your system.
auth(imageSpecifier,scope,options) Promise<{Secret?:string,Username?:string,token?:string}>
gcr.io
.options['any.gcr.io/google-cloud-project']
options['any.gcr.io']
options['gcr.io'] = {...}
GOOGLE_APPLICATION_CREDENTIALS=path to key file.json
and it will work as expected like other google client libraries.options['docker.io'] = {...}
token
is required or Username
,Secret
is required. we'll either try Basic or Bearer auth depending on credentials provided.options.Secret
options.Username
options.token
options[ any other registry ] = {Username:string,Secret:string} or {token:string}
if docker is configured to look for credentials in credentials helpers authentication will be fetched from them automatically https://docs.docker.com/engine/reference/commandline/login/#credential-helpers
this library does not attempt to read base64 or credentials from a secret service/keychain on the host.
As you get more creative you'll find you have to combine work done in the image builder with lower level api calls. like adding a new blob directly to the target registry before you call addLayer.
const RegistryClient = require('container-image-builder')
or
import {RegistryClient} from 'container-image-builder
client = new RegistryClient(registry, repository, auth)
my-google-project/my-app
client.manifest(tag: string) Promise<Manifest>
client.tags() Promise<TagResult>
client.manifestUpload(tag: string|false, manifest: Buffer|{}) Promise<{status: number, digest: string, body: Buffer}>
client.blobExists(digest) Promise<boolean>
client.blob(digest, stream) Promise<Buffer|Readable>
client.upload(blob, contentLength, digest) Promise<{contentLength: number, digest: string}>
client.mount(digest: string, fromRepository: string)
this example copies 'gcr.io/project1/image' to 'us.gcr.io/project2/image' . The credentials value is the parsed JSON object from the file in GOOGLE_APPLICATION_CREDENTIALS
const creds1 = JSON.parse(fs.readFileSync(process.env.OTHER_GOOGLE_APPLICATION_CREDENTIALS))
const creds2 = JSON.parse(fs.readFileSync(process.env.OTHER_GOOGLE_APPLICATION_CREDENTIALS2))
const image = new Image('gcr.io/project1/image','us.gcr.io/project2/image',{
"auth":{
'us.gcr.io/project2':{credentials:creds1},
'gcr.io/project1':{credentials:creds2},
}
})
console.log(await image.save())
This is not an official google product.
FAQs
container image builder. without docker, docker/oci registry client and image building helpers for protocol version 2, fork of container-image-builder
The npm package oci-image-builder receives a total of 181,529 weekly downloads. As such, oci-image-builder popularity was classified as popular.
We found that oci-image-builder demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.