Skip to content

Releases: magicdrive/kjak

v1.2.2

Choose a tag to compare

@github-actions github-actions released this 02 Nov 12:10
Immutable release. Only release title and notes can be modified.
ea0bb31

What's Changed

Full Changelog: v1.2.1...v1.2.2

v1.2.1

Choose a tag to compare

@github-actions github-actions released this 02 Nov 06:31
Immutable release. Only release title and notes can be modified.

What's Changed

  • chore(renovate): raise the Node.js major of renovate-check from the dashboard by @magicdrive in #48

Full Changelog: v1.2.0...v1.2.1

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 31 Oct 05:16
Immutable release. Only release title and notes can be modified.
f22074a

kjak v1.2.0

kjak sends one notification to Slack, Discord, e-mail, any HTTP API or a
plugin of your own, from the command line, a script or CI. v1.2.0 lets a
plugin installed with Homebrew run on macOS, under a statement of its
content that you make. It is a minor release: everything v1.0.0 guarantees
(docs/stability.md)
is kept.

Highlights

  • Plugins installed by Homebrew (macOS). Homebrew makes
    <prefix>/bin, Cellar and opt writable by the admin group, so kjak
    refused every plugin installed with brew. Such a plugin now runs when
    its SHA-256 is the one you stated: a feather of your configuration whose
    sha256 equals the file's, or a project whose kjak config trust
    recorded that path and SHA-256. kjak feather plugins shows the value to
    pin:

    [feathers.mac]
    type = "external"
    plugin = "notify-macos"
    sha256 = "..."     # from kjak feather plugins; update it after brew upgrade

    kjak does not treat the admin group as root (writing there needs no
    authentication). The exception covers only the group-write rule, only
    bin, Cellar and opt of /opt/homebrew and /usr/local (owned by
    you, group admin, not writable by others, ACLs checked as before), and
    only a file in a keg named for the plugin that is a Mach-O executable
    whose load commands name system libraries alone (not a script, not a
    program linked to a library of Homebrew; what the plugin opens or starts
    at run time is not checked). The content and the place are checked again before
    every run, and once more just before the process starts. What it opens to
    other admin users, and the short window that remains before the exec, are
    in docs/security.md.

Compatibility

  • Nothing that ran before is refused now, and nothing is removed or changed
    in meaning. A plugin anywhere but Homebrew's directories is checked
    exactly as in v1.1.0.
  • New: in kjak feather plugins -o json, plugins[].homebrew (true for a
    plugin in Homebrew's directories, with its sha256); in the text output,
    its state Homebrew: runs only for a feather with sha256 = "..." (or a project trust). kjak config trust notes such a plugin.
  • Linux (Linuxbrew included) and Windows behave as in v1.1.0.
  • The plugin protocol is still version 1.

Install

brew install magicdrive/tap/kjak            # macOS, Linux; brew upgrade kjak later

or, without Homebrew, on macOS and Linux:

curl -fsSLO https://raw.githubusercontent.com/magicdrive/kjak/v1.2.0/install.sh
sh install.sh --version v1.2.0              # into ~/.local/bin; sh install.sh --upgrade later

or the archive of your platform below, checked with kjak_checksums.txt
and, optionally, its build provenance:

gh attestation verify kjak_1.2.0_linux_amd64.tar.gz --repo magicdrive/kjak \
  --signer-workflow magicdrive/kjak/.github/workflows/release.yml --source-ref refs/tags/v1.2.0

Developers can build from source with Go 1.27 (make build, or
go install github.com/magicdrive/kjak@v1.2.0).

Platforms

platform archive
macOS arm64, amd64 tar.gz; Homebrew, install script
Linux amd64, arm64 tar.gz; Homebrew, install script
Windows amd64 zip

The notes of v1.0.0 on keychains, secrets-file permissions and plugins per
platform still apply.

Known limitations

  • A plugin installed by Homebrew needs its sha256 updated after each
    brew upgrade. Between kjak's last check and the exec, another admin user
    of the Mac could still replace it (docs/security.md).
  • OS-native notifications are not supported.
  • Windows has no keychain support. On macOS and Linux the keychain tools
    are tested as test doubles, not against a real keychain.
  • Changes other than adding a feather, group or template rewrite the
    configuration file without its comments.
  • Plugins are not sandboxed: they run with your rights.
  • The macOS binaries are not notarized.

Full Changelog: v1.1.0...v1.2.0

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 15:01
Immutable release. Only release title and notes can be modified.
5c51124

kjak v1.1.0

kjak sends one notification to Slack, Discord, e-mail, any HTTP API or a
plugin of your own, from the command line, a script or CI. v1.1.0 is about
getting started: a tutorial for every feather in English and Japanese,
complete configuration examples, a self-documenting kjak config init, and
configuration changes that keep your comments when they only add. It is a
minor release: everything v1.0.0 guarantees
(docs/stability.md)
is kept.

Highlights

  • Tutorials for every feather, in English and Japanese: Discord, Slack,
    Gmail, any SMTP server, HTTP APIs and plugins, from the setup on the
    service to a first notification, with complete config.toml files, the
    command line, secrets, troubleshooting and security notes
    (docs/tutorials).
    The plugin tutorial comes with a small working plugin,
    kjak-feather-log.
  • Configuration examples: complete files for one feather, several,
    groups, templates and secrets files
    (docs/examples).
  • kjak config init writes a catalog: the same configuration as before
    (no feather), followed by a commented example of every feather, group,
    template and default, each feather linked to its tutorial. kjak config init --minimal writes it without the examples.
  • Comments kept when adding. feather add, group set and template set of a new name append to the file and keep its comments and layout.
    Other changes still rewrite it, and now say so when that drops comments
    (kjak: note: FILE was rewritten without its comments).
  • Documentation checked in CI. The example files and the TOML blocks of
    the tutorials, the getting started guides and the READMEs are parsed and
    validated (the TOML of the other documents is parsed). The kjak
    commands of the documents' sh blocks are run, in order, against the
    real command line in an empty sandbox (send as a dry run): an unknown
    command, flag, level, type or a value of the wrong form fails the build;
    lines with shell substitutions or redirections, and commands that read
    standard input, are left out. Links are checked, and a feather type
    without a tutorial in both languages, or without an example, fails the
    build.

Compatibility

  • New: the flag kjak config init --minimal. Nothing is removed or
    changed in meaning.
  • kjak config init writes a longer file; its configuration is the same as
    v1.0.0's (tested). The text of the file is not part of the contract.
  • A file that only gets a new feather, group or template is appended to
    instead of rewritten; what it contains reads back exactly as a rewrite
    would (kjak checks, and rewrites otherwise).
  • OS-native notifications are still not supported: the type names os,
    native, macos, linux and windows stay reserved and refused.

Install

brew install magicdrive/tap/kjak            # macOS, Linux; brew upgrade kjak later

or, without Homebrew, on macOS and Linux:

curl -fsSLO https://raw.githubusercontent.com/magicdrive/kjak/v1.1.0/install.sh
sh install.sh --version v1.1.0              # into ~/.local/bin; sh install.sh --upgrade later

or the archive of your platform below, checked with kjak_checksums.txt
and, optionally, its build provenance:

gh attestation verify kjak_1.1.0_linux_amd64.tar.gz --repo magicdrive/kjak \
  --signer-workflow magicdrive/kjak/.github/workflows/release.yml --source-ref refs/tags/v1.1.0

Developers can build from source with Go 1.27 (make build, or
go install github.com/magicdrive/kjak@v1.1.0).

Platforms

platform archive
macOS arm64, amd64 tar.gz; Homebrew, install script
Linux amd64, arm64 tar.gz; Homebrew, install script
Windows amd64 zip

The notes of v1.0.0 on keychains, secrets-file permissions and plugins per
platform still apply.

Known limitations

  • OS-native notifications are not supported (a later version).
  • Windows has no keychain support. On macOS and Linux the keychain tools
    are tested as test doubles, not against a real keychain.
  • Changes other than adding a feather, group or template rewrite the
    configuration file without its comments.
  • Plugins are not sandboxed: they run with your rights.
  • The macOS binaries are not notarized.

Full Changelog: v1.0.0...v1.1.0

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 10:55
Immutable release. Only release title and notes can be modified.
b88c4b8

kjak v1.0.0

kjak sends one notification to Slack, Discord, e-mail, any HTTP API or a
plugin of your own, from the command line, a script or CI. v1.0.0 is the
first stable release: the command line, the configuration, the JSON output,
the exit status, the error codes and the plugin protocol are now a contract
kept for all of 1.x (docs/stability.md).

Highlights

  • Stable contract. docs/stability.md lists what 1.x
    guarantees (commands and flags, exit status, JSON schema version 1, error
    codes, configuration and secrets files, the trust store, retry semantics,
    plugin protocol v1, the version line), what it does not (text output,
    messages, provider payloads, descriptive values inside JSON documents),
    and what makes a major, a minor or a patch release. Tests check it against
    the code.
  • Secrets files. Secrets live in a private TOML file of their own
    ({ secret = "dev_slack.webhook_url" }), personal (--secrets,
    $KJAK_SECRETS, ~/.config/kjak/secrets.toml) or per project
    (.kjak.secrets.toml, trusted with the project). kjak refuses a secrets
    file anyone else can read, checking the mode bits and the ACLs on Linux,
    macOS and Windows. kjak config migrate-secrets moves literal secrets out
    of a configuration file.
  • http feathers. Any HTTP API: method, headers, query, bearer/basic/
    header authentication by reference, a JSON or text body or a template,
    success statuses, idempotency keys and method-aware retries, behind an
    address policy (https only, no redirects, no loopback, private,
    link-local or cloud-metadata address unless allowed; checked where the
    connection is made).
  • External feather plugins. kjak-feather-<name> executables speaking
    a documented JSON protocol (v1) on stdin/stdout. kjak checks which
    executable runs, gives it only its own secrets and a minimal environment
    in a private working directory, and ends its whole process tree (process
    group on Unix, Job Object on Windows) at its timeout, the deadline and
    Ctrl-C, SIGTERM or SIGHUP. kjak feather plugins lists them without
    running any.
  • Project trust, tightened. A trusted .kjak.toml reads your
    environment variables, keychain entries and personal secrets only by the
    names you allowed when you trusted it, and its slack, discord and email
    feathers reach public addresses only unless the file allows more.
  • Install script. install.sh installs a release on macOS and Linux
    (amd64, arm64) without Homebrew: checked against the release's checksums,
    only the binary taken out of the archive, the installed one replaced in a
    single rename, no sudo, no PATH change.
  • Quality. golangci-lint, fuzzing, mutation testing, end-to-end tests of
    the built binary (and of v0.0.4 configurations), native CI on every
    release platform.

Senders

feather sends secrets retries
slack an incoming webhook message webhook_url 429, 5xx except 502/504, a connection that failed before the request was sent
discord a webhook message (title, body, level color, URL) webhook_url as slack, retry_after honored
email an e-mail over SMTP (STARTTLS, TLS or, explicitly, plain), AUTH PLAIN/LOGIN password SMTP 4xx, a connection that failed before the data
http any HTTP request; the body is JSON, text or a template of the message url_secret, auth by method (retry.policy): GET/PUT/DELETE, and POST/PATCH with an idempotency key
external whatever the plugin does the ones it is given only with retry.policy = "plugin"

Groups send to several feathers at once; templates turn variables into a
message (--template, --template-file, kjak template render). Every
target is delivered on its own, at most --concurrency at a time, within
one deadline (--timeout, default 10s): one feather's failure never hides
another's result. The report (-o json) gives each target's status,
acceptance (confirmed, rejected, unknown), attempts and errors, and the
outcome of the send (success, partial, failure, canceled); exit 0
when nothing failed, 1 when a delivery failed, 2 when nothing was sent
(usage, configuration, credentials, trust), 130 when interrupted. An
unknown acceptance (a request that may have been delivered) is never
retried.

Breaking changes

Compared to v0.0.4. Each is a security fix or a fix of the output contract,
refused before anything is sent; the migration guide has the steps.

  • Project feathers need a new trust for env and keychain
    references.
    A project trusted by v0.0.4 stays trusted, but its slack,
    discord and email feathers that read an environment variable or a
    keychain entry are refused (exit 2, nothing sent) until you trust the
    project again and allow those names (kjak config trust; in CI
    --yes --allow-user-secrets: --yes alone now fails for such a project).
  • A project's slack, discord and email feathers reach public addresses
    only, without a proxy.
    A project feather that sends to localhost, a
    private network or a private SMTP server fails with blocked (exit 1)
    until the project allows it (allow_networks, allow_hosts). Global
    feathers are not affected.
  • --to must name something. --to "" or --to , (an empty variable
    in a script) is a usage error (exit 2); v0.0.4 sent to defaults.targets.
  • Message templates cannot loop (range, define, template,
    block), and printf refuses a width or precision of 1000 or more, *
    and argument indexes.
  • Configuration files must be regular files. A configuration file, a
    project file or the trust store that is a FIFO, a device or a directory is
    refused (a symbolic link to a regular file still works).
  • Text fields cannot hold control characters (username, host,
    user, from, subject_prefix, plugin, path, ..., a keychain
    service or account), and a keychain account cannot hold /.
  • config validate -o json prints a JSON document on success
    ("valid": true, the files, the literal secrets by key); v0.0.4 printed
    the PATH: OK text lines there. Failures print the same error document as
    before, and the exit status is unchanged.
  • kjak version and kjak feather types take no argument but
    --help (an unexpected one is exit 2).
  • Downgrade: once a trust entry uses the new keys (a project secrets
    file, allowed names, plugins), v0.0.4 cannot read the trust store
    ("broken trust store"). Keep a copy of trust.toml if you may go back.

Unchanged: configurations without literals or control characters, env
and keychain references of the global configuration, groups, templates
without loops, the JSON report (fields were only added), the exit status,
the request bodies sent to Slack, Discord and e-mail.

Deprecated

  • { literal = "..." } credentials and feather add --secret-stdin. They
    keep working in 1.x; kjak send warns about them on stderr (and warns
    that the file is readable by others when it is), kjak config validate
    reports them and --strict refuses them. Move them with
    kjak config migrate-secrets, then rotate them.

Migration

  1. Install v1.0.0 (below).
  2. kjak config validate (and --strict to find literals);
    kjak config migrate-secrets if you have any, then rotate the secrets
    that were ever committed or shared.
  3. In each repository with a .kjak.toml: review it, then
    kjak config trust again if a send says the trust does not allow a
    reference; add allow_networks/allow_hosts to project feathers that
    send to a local or private address. In CI use
    kjak config trust --yes --allow-user-secrets after the review.
  4. Replace range/define/template/block in message templates; check
    scripts that pass --to "$VAR".

Details: docs/migration.md.

Security

  • Secrets: separate private files, checked on the opened file (owner, mode,
    ACLs; fail closed), never printed. Every error and report is redacted of
    every resolved secret — also its URL forms, the base64 forms sent for HTTP
    basic authentication and SMTP AUTH, a fragment left by a truncation and
    multi-line secrets. A configuration file with literal secrets that others
    can read is warned about.
  • Projects: every env/keychain/personal secret reference and plugin
    environment variable is allowed by name; an address policy for every
    network feather of a project; plugins pinned by the trust (path and
    SHA-256).
  • Plugins: a minimal environment (PATH with absolute directories only), a
    private working directory per attempt, the whole process tree ended; a
    plugin file is found only under its exact name (also on file systems that
    ignore case).
  • Untrusted text: terminal escape sequences in a project file are refused
    or escaped before they reach your terminal (config trust shows what you
    approve).
  • SSRF: metadata services (AWS, GCP, Azure WireServer, Tencent, ...),
    IPv4-in-IPv6 and NAT64 forms are refused; DNS rebinding is covered by
    checking the address where the connection is made.
  • Denial of service: a FIFO as a configuration file and looping templates
    are refused; an SMTP server that does not answer QUIT does not hold the
    send.
  • TLS: kjak uses the system's certificate authorities; SSL_CERT_FILE and
    SSL_CERT_DIR replace them on macOS and Windows (Go 1.27), see
    docs/security.md.

Report a vulnerability privately: SECURITY.md.

Fixes

  • results[].duration_ms in the JSON re...
Read more

v0.0.4

Choose a tag to compare

@github-actions github-actions released this 26 Oct 01:01
Immutable release. Only release title and notes can be modified.
6cad383

What's Changed

  • Revert "build: adopt Hephaestus and modernize development workflows" (pushed to main by mistake) by @magicdrive in #12
  • build: adopt Hephaestus and modernize development workflows by @magicdrive in #13

Full Changelog: v0.0.3...v0.0.4

v0.0.3

Choose a tag to compare

@magicdrive magicdrive released this 23 Oct 13:19
Immutable release. Only release title and notes can be modified.
72b511f

Changelog

  • 72b511f Merge pull request #11 from magicdrive/fix/e2e-inherited-descriptors-limit
  • 271389a test(e2e): give kjak the raised descriptor limit with its 1100 descriptors
  • 2a05859 Merge pull request #10 from magicdrive/fix/macos-ci-after-pr9
  • be062e2 test(subcmd): wait for the writers a test leaves, before the next counts descriptors
  • 9d5468e Merge pull request #9 from magicdrive/hardening/production-validation
  • f78144c docs: align the delivery tables with the classification
  • 1f713dc test: protocol matrices of Slack, Discord and SMTP through the engine
  • 3202044 fix(discord): cap the retry_after of a 429 body like Retry-After
  • e97272f fix(send): see a macOS FIFO writer that closes without writing
  • 0a646c2 Merge pull request #8 from magicdrive/hardening/deadline-io-contract
  • 010f2d4 docs: a FIFO is read through kjak's descriptor; macOS constraints
  • c822676 fix(send): cancel a macOS FIFO read without writing into the FIFO
  • 82ffead test: fail rather than skip the high-descriptor tests on CI
  • c7ef75c docs(troubleshooting): standard input macOS cannot wait for
  • ccea166 fix(send): keep input cancelable at any descriptor number
  • dcab135 docs: describe the deadline of a send, FIFO input and the output contract
  • bc6ccb1 fix(cli): tell a closed pipe on Windows too
  • d9fc8b1 test(cli): pin the output contract and the broken pipe on every system
  • 2b96706 fix(send): make standard input and a --json-input FIFO cancelable
  • 236930d fix(send): start the deadline before the credentials
  • add1e37 Merge pull request #7 from magicdrive/hardening/production-reliability
  • bd0b273 docs: describe SIGTERM, interrupted stdin and unwritable output
  • 20c0450 fix(cli): fail a command whose output cannot be written
  • 16765c5 fix(credential): do not wait for the output of a keychain tool's children
  • 5858b18 fix(send): stop reading standard input when interrupted
  • f409466 fix(cmd): cancel on SIGTERM and survive a closed stdout
  • 6fc6f6a Merge pull request #6 from magicdrive/refactor/transport-libraries
  • d83905f fix(email): do not fold a subject into a line of only white space
  • 844d991 docs(development): record why the transports keep the standard library
  • e6a0058 fix(email): fold long To and Subject headers
  • 8a54872 Merge pull request #5 from magicdrive/docs/bilingual-setup-guide
  • 70fc218 test(e2e): check the commands of the guides, not only README.md
  • 7f5b159 docs: add bilingual setup and configuration guides

v0.0.2

Choose a tag to compare

@magicdrive magicdrive released this 22 Oct 13:05
Immutable release. Only release title and notes can be modified.

Changelog

  • 8037ece fix(release): release with PERSONAL_GITHUB_TOKEN, as in ark and enma
  • 7bc2ca6 Merge pull request #4 from magicdrive/refactor/align-ark-enma
  • 07db5e6 build(make): follow enma's Makefile
  • 7adccd4 build(release): let GoReleaser publish, as in ark and enma
  • 41177be docs: describe the simplified CI and release
  • 31f2a7b ci: align CI with enma (test, lint, fuzz, dist)
  • 01bdd6b Merge pull request #3 from magicdrive/fix/release-immutable-verification
  • 6be5105 docs(release): record the v0.0.1 failure and re-run rules
  • af45c89 fix(release): wait for the immutable, attested release and keep the tap layout

kjak v0.0.1

Choose a tag to compare

@github-actions github-actions released this 22 Oct 10:58
Immutable release. Only release title and notes can be modified.
eb6e06d

kjak v0.0.1. Install: brew install magicdrive/tap/kjak. Verify: gh attestation verify --repo magicdrive/kjak