Skip to content

feat: osctrld v1.1.0 — daemon mode, osquery lifecycle, extensions, YAML config#1

Merged
javuto merged 43 commits into
jmpsec:mainfrom
alvarofraguas:main
May 24, 2026
Merged

feat: osctrld v1.1.0 — daemon mode, osquery lifecycle, extensions, YAML config#1
javuto merged 43 commits into
jmpsec:mainfrom
alvarofraguas:main

Conversation

@alvarofraguas
Copy link
Copy Markdown
Contributor

Summary

Production-ready v2.0.0 of osctrld with four major features:

  • Daemon mode (service command) — long-running sync loop with configurable interval and jitter, graceful shutdown on SIGINT/SIGTERM
  • Osquery lifecycle management — automatically restarts osquery via OS service manager when synced flags or certificate change on disk
  • Extension deployment — fetches extension manifests from osctrl, downloads and deploys binaries, restarts osquery only on changes
  • YAML configuration — config defaults to YAML format while keeping full JSON backward compatibility via Viper auto-detection

Additional improvements

  • Migrated logging from log/slog to github.com/rs/zerolog with configurable format (text or json)
  • Fixed force flag binding bug (was bound to Verbose instead of Force)
  • Fixed typo and removed dead code
  • Added comprehensive test suite (51 tests) with CI pipeline (golangci-lint + race-enabled tests)
  • Updated README, sample configs, and service files (systemd/launchd) for v2.0.0

Stats

  • 32 files changed, 1,425 insertions, 352 deletions
  • 51 tests all passing
  • CI green (lint + tests)

Test plan

  • All 51 unit tests pass (go test -race -v ./cmd/osctrld/)
  • golangci-lint passes with zero warnings
  • CI pipeline green on push
  • Release builds successfully for all 6 platforms (darwin/linux/windows × amd64/arm64)
  • YAML and JSON config loading verified via tests
  • Daemon mode jitter calculation verified via tests
  • Osquery restart command generation verified per OS via tests
  • Extension manifest parsing and deployment verified via tests

Documents the plan to fix bugs (force flag binding, typo, dead code),
migrate logging from stdlib log to log/slog, improve test coverage
for core action logic, and add a CI pipeline with golangci-lint.
9-task plan covering bug fixes, slog migration, test coverage
for action and helper functions, Makefile fixes, and CI pipeline
with golangci-lint.
Fix 'Cound' -> 'Could' in http-utils.go.
Remove premature cmd.CombinedOutput() in runScript that executed the
script and discarded the result before cmd.Run() tried to run it again.
TestLoadConfigurationValid was failing because it referenced
tests/osctrld-test.json with a relative path that didn't resolve
when running from the repository root.
Replace log.Printf/Println with slog.Info/Warn/Error/Debug.
Remove emoji prefixes, use structured key-value fields instead.
Remove manual verbose guards — slog level filter handles this.
Initialize TextHandler in cliWrapper with level based on --verbose flag.
Cover writeContentExists (create, same-content skip, no-force reject,
force overwrite), genericRetrieve (success, server error, connection
refused), retrieveScript, retrieveCert, retrieveVerify, retrieveFlags,
checkFileExist, and checkFileContent.
Cover getFlags, getCert, enrollNode, removeNode, and verifyNode
using httptest servers to mock the osctrl API. Tests cover both
success and server error paths.
Runs govet, errcheck, staticcheck, unused, gosimple, ineffassign,
and typecheck on every PR and push to main. Tests run with -race
and coverage reporting.
Migrate from log/slog to github.com/rs/zerolog with configurable
output format (text/JSON) via --log-format flag.
8-task plan covering dependency addition, CLI flag, logger init,
and mechanical slog-to-zerolog migration across all 5 source files.
Migrate actions.go (29 call sites), actions_helpers.go (3),
config.go (1), and http-utils.go (1) to zerolog's fluent API.
No slog or stdlib log references remain in the codebase.
Long-running `service` command with 60-min configurable interval,
jitter, graceful shutdown, and flags+cert sync on each tick.
7-task plan: config field, jitter helper, command registration,
syncOnce helper, daemon loop with graceful shutdown, service files.
Remove dead code (runScript), simplify fmt.Sprintf wrapping, and
check all error returns in test helpers.
Use runtime.GOOS instead of hardcoded "darwin" so the test passes
on both macOS and Linux runners.
Removes the main branch trigger and snapshot version generation.
Goreleaser now only runs when a version tag (v*) is pushed,
preventing conflicts with existing release assets.
Add documentation for daemon mode, osquery lifecycle management,
extension deployment, structured logging, configuration reference,
and deployment instructions for systemd and launchd.
Update sample config with new fields.
Rename JSONConfiguration to Configuration with yaml/mapstructure tags.
Rename jsonConfig global to appConfig. Add YAML sample config and test.
Update README, service files, and gitignore to default to YAML.
Both YAML and JSON formats are supported — Viper detects from extension.
@javuto javuto self-requested a review May 24, 2026 07:34
@javuto javuto added ✨ enhancement New feature or request 📍 new version New version released ⚙️ configuration Configuration related issues labels May 24, 2026
Comment thread cmd/osctrld/version.go Outdated
const (
// OsctrldVersion to have the version for all components
OsctrldVersion string = "1.0.0"
OsctrldVersion string = "2.0.0"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not bump the major release just yet, better do 1.1.0

@alvarofraguas alvarofraguas changed the title feat: osctrld v2.0.0 — daemon mode, osquery lifecycle, extensions, YAML config feat: osctrld v1.1.0 — daemon mode, osquery lifecycle, extensions, YAML config May 24, 2026
@javuto javuto merged commit c186313 into jmpsec:main May 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚙️ configuration Configuration related issues ✨ enhancement New feature or request 📍 new version New version released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants