{"id":13563805,"url":"https://github.com/reddec/wd","last_synced_at":"2025-03-15T17:27:12.793Z","repository":{"id":57633368,"uuid":"413804407","full_name":"reddec/wd","owner":"reddec","description":"Yet another webhook daemon","archived":false,"fork":false,"pushed_at":"2021-10-12T14:47:00.000Z","size":115,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-09T00:06:41.158Z","etag":null,"topics":["automate","automation","devops","golang","script","webhook"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reddec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-05T12:15:52.000Z","updated_at":"2023-01-30T23:30:47.000Z","dependencies_parsed_at":"2022-08-31T16:32:02.567Z","dependency_job_id":null,"html_url":"https://github.com/reddec/wd","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Fwd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Fwd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Fwd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reddec%2Fwd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reddec","download_url":"https://codeload.github.com/reddec/wd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243764868,"owners_count":20344496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automate","automation","devops","golang","script","webhook"],"created_at":"2024-08-01T13:01:23.472Z","updated_at":"2025-03-15T17:27:12.720Z","avatar_url":"https://github.com/reddec.png","language":"Go","readme":"# Webhook daemon\n\n[![Build and release](https://github.com/reddec/wd/actions/workflows/release.yaml/badge.svg)](https://github.com/reddec/wd/actions/workflows/release.yaml)\n\nYet another application which can run scripts on request.\n\nSupports:\n\n* Any executable script in directory can be run\n* Isolated temporary working directory for scripts for each run (disabled by `-I`)\n* Buffers response to handle proper response in case scrip non-zero exit code\n* Exports Prometheus metrics (available on `/metrics`, disabled by `-M`)\n* Supports TLS and automatic TLS by Let's encrypt (`--auto-tls example.com`)\n* Supports JWT tokens (`-s secret2 ...`, issue by token `token`)\n* Supports two mode:\n    * scripts from directory (ex: `wd serve path/to/dir`)\n    * single script from command line (ex: `wd run date`)\n* Designed to work in memory-constrained environments\n* Supports async mode\n\n\n## Installation\n\n### Precompiled binaries\n\nFrom binaries and packages - [releases page](https://github.com/reddec/wd/releases)\n\n**Debian/Ubuntu** packages defaults:\n* systemd service `webhooks`, enabled and started after installation\n* webhooks directory is `/var/webhooks`\n* `run-as-script-owner` enabled by default\n* metrics are disabled\n* configuration file is in `/etc/webhooks/webhooks.env` with 0600 permission\n* binding is `127.0.0.1:8080`\n\n### Brew (MacOS)\n\n    brew install reddec/tap/wd\n\nSupports both Intel and Apple Silicon (arm)\n\n### Build\n\nFrom source, requires g1.17+\n    \n    go install github.com/reddec/wd@latest\n\n## Minimal running examples\n\nshow current date\n\n    wd run date\n\nexpose current dir\n\n    wd serve .\n\n## Usage\n\nEven if `wd` comes with already good enough default parameters, it is not opinionated and allows \nprecisely adjust almost any kind of behaviour.\n\n### Metrics\n\nBy-default, `wd` exposes metrics endpoint as `/metrics` without restrictions. You may:\n\n* disable metrics completely by `M, --disable-metrics`\n* put metrics endpoint behind tokens (requires `-s ...`) by `--secure-metrics`. Tokens should be issued for `metrics`\n  action.\n\n### Async execution\n\nIn case of asynchronous execution:\n\n1. request will be dumped to a temporary file on disk \n2. file name will be added to the internal queue (`-q, --queue`)\n3. client will get 204 No Content\n4. in background go-routine, request will be streamed from disk like it was sent by client\n5. it will retry execute request again and again during 1 + `--retries` attempts in case non-2xx code returned. Output\n   will be dropped.\n\nMaximum number of parallel async worker can be limited by `-A,--async-worker`, default is `2`.\n\nAsync mode can be activated by:\n\n* (default) in `--async auto` mode - by query parameter `async=(y,yes,true,t,on,ok,1)`\n* forcefully for all requests by `--async forced`\n\nto disable async execution completely use flag `--async disabled`\n\nDuring async execution the special env variable `HEADER_X_ATTEMPT` will be passed to the script. It contains attempt\nnumber starting from 1.\n\n### Payload\n\nBy-default, request body will be streamed to STDIN of script. This approach allows users to minimize memory consumption\nbecause no information store in memory, so it's possible to handle unlimited amount of data (ie: streaming).\n\nHowever, in case script does not support processing of STDIN (or just for convenience) it is possible to cache payload\ninto memory and pass it as environment variable `REQUEST_PAYLOAD` (`--payload env`) or as last argument of\na script (`--payload arg`). It might be a good idea to adjust maximum payload size by\n`--payload-size, -P` (default is 10Mib).\n\n\u003e Do not use `--payload env` or `--payload arg` for large payloads!\n\nGeneral linux limits: \n* Max argument size - ~32Kib and could vary for each setup\n* Max environment variable size - at least 4Kib and could vary for each setup\n\nIn case of `--payload env` or `--payload  arg` payload has to be read fully before passed to a script\nwhich requires additional memory close double of request body size.\n\nShorthand for `--payload` flag is `-p`.\n\n### Script specific parameter\n\nSince `0.1.0` it's possible to define script specific parameter by [extended attributes](https://en.wikipedia.org/wiki/Extended_file_attributes).\nIt's optional and supported for most systems except Windows. In case of any error, xattrs will be ignored.\n\nThe extended attributes applicable only for `serve` command.\n\nThe following parameters can be used to override parameters provided during startup:\n\n| Attribute              | Type     | Overrides                   |\n|------------------------|----------|-----------------------------|\n| `user.webhook.async`   | mode     | `--async`                   |\n| `user.webhook.timeout` | duration | `--timeout`                 |\n| `user.webhook.delay`   | duration | `--delay`                   |\n| `user.webhook.retries` | int64    | `--retries`                 |\n\n\u003e all values are in string Golang default representation\n\n### Containers as webhooks\n\n`wd` can perfectly work with container runtime. Especially with podman,\nbecause it could be launched without daemon.\n\nExample script `example-date`:\n\n```shell\n#!/bin/sh\nexec podman run --rm -i ubuntu:20.04 date\n```\n\n### Common\n\n```\nUsage:\n  wd [OPTIONS] \u003crun | serve | token\u003e\n\nApplication Options:\n      --cors                         Enable CORS [$CORS]\n  -b, --bind=                        Binding address (default: 127.0.0.1:8080) [$BIND]\n  -t, --timeout=                     Maximum execution timeout (default: 120s) [$TIMEOUT]\n  -s, --secret=                      JWT secret for checking tokens. Use token command to create token [$SECRET]\n  -B, --buffer=                      Buffer response size (default: 8192) [$BUFFER]\n  -a, --async=[auto|forced|disabled] Async mode. auto - relies on async param in query, forced - always async, disabled - no async (default: auto) [$ASYNC]\n  -r, --retries=                     Number of additional retries after first attempt (async only) (default: 3) [$RETRIES]\n  -d, --delay=                       Delay between attempts (async only) (default: 3s) [$DELAY]\n  -W, --workers=                     Maximum number of workers for sync requests. Default is 2 x num CPU [$WORKERS]\n  -A, --async-workers=               Number of workers to process async requests (default: 2) [$ASYNC_WORKERS]\n  -q, --queue=                       Queue size for async requests. 0 means unbound (default: 8192) [$QUEUE]\n  -p, --payload=[stdin|arg|env]      Payload type - how to pass request body to the script (default: stdin) [$PAYLOAD]\n  -M, --disable-metrics              Disable prometheus metrics [$DISABLE_METRICS]\n      --secure-metrics               Require token to access metrics endpoint [$SECURE_METRICS]\n      --auto-tls=                    Automatic TLS (Let's Encrypt) for specified domains. Service must be accessible by 80/443 port. Disables --tls [$AUTO_TLS]\n      --auto-tls-cache-dir=          Location where to store certificates (default: .certs) [$AUTO_TLS_CACHE_DIR]\n      --tls                          Enable HTTPS serving with TLS. Ignored with --auto-tls' [$TLS]\n      --tls-cert=                    Path to TLS certificate (default: server.crt) [$TLS_CERT]\n      --tls-key=                     Path to TLS key (default: server.key) [$TLS_KEY]\n\nHelp Options:\n  -h, --help                         Show this help message\n\nAvailable commands:\n  run    run single script\n  serve  serve server from directory\n  token  issue token\n```\n\n### Run\n\nRun single script. Uses current work dir as work dir for script.\n\n```\nUsage:\n  wd [OPTIONS] run [Binary] [Args...]\n\nApplication Options:\n      --cors                         Enable CORS [$CORS]\n  -b, --bind=                        Binding address (default: 127.0.0.1:8080) [$BIND]\n  -t, --timeout=                     Maximum execution timeout (default: 120s) [$TIMEOUT]\n  -s, --secret=                      JWT secret for checking tokens. Use token command to create token [$SECRET]\n  -B, --buffer=                      Buffer response size (default: 8192) [$BUFFER]\n  -a, --async=[auto|forced|disabled] Async mode. auto - relies on async param in query, forced - always async, disabled - no async (default: auto) [$ASYNC]\n  -r, --retries=                     Number of additional retries after first attempt (async only) (default: 3) [$RETRIES]\n  -d, --delay=                       Delay between attempts (async only) (default: 3s) [$DELAY]\n  -W, --workers=                     Maximum number of workers for sync requests. Default is 2 x num CPU [$WORKERS]\n  -A, --async-workers=               Number of workers to process async requests (default: 2) [$ASYNC_WORKERS]\n  -q, --queue=                       Queue size for async requests. 0 means unbound (default: 8192) [$QUEUE]\n  -p, --payload=[stdin|arg|env]      Payload type - how to pass request body to the script (default: stdin) [$PAYLOAD]\n  -P, --payload-size=                Maximum payload size in bytes. Zero or negative means unlimited (default: 10485760) [$PAYLOAD_SIZE]\n  -M, --disable-metrics              Disable prometheus metrics [$DISABLE_METRICS]\n      --secure-metrics               Require token to access metrics endpoint [$SECURE_METRICS]\n      --auto-tls=                    Automatic TLS (Let's Encrypt) for specified domains. Service must be accessible by 80/443 port. Disables --tls [$AUTO_TLS]\n      --auto-tls-cache-dir=          Location where to store certificates (default: .certs) [$AUTO_TLS_CACHE_DIR]\n      --tls                          Enable HTTPS serving with TLS. Ignored with --auto-tls' [$TLS]\n      --tls-cert=                    Path to TLS certificate (default: server.crt) [$TLS_CERT]\n      --tls-key=                     Path to TLS key (default: server.key) [$TLS_KEY]\n\nHelp Options:\n  -h, --help                         Show this help message\n\n[run command arguments]\n  Binary:                            binary to run\n  Args:                              arguments\n```\n\nExamples:\n\n**current date**\n\n`wd run date`\n\n**current date in seconds**\n\n`wd run -- date +%s`\n\n### Serve\n\nMap request path to script inside directory. It's forbidden to execute scripts outside directory (parents). By-default,\ndirectory and scripts with leading .dot disabled.\n\nTo be more secure, you may run `wd` as root and add flag `-R, --run-as-script-owner` (works only on posix). In that case\n`wd` will run script with same uid/gid as in file. Basically, if you want to run script as specific user - just\ndo `chown` on it. If isolation not disabled, temporary work directory also will be chown to the script uid/gid.\n\n```\nUsage:\n  wd [OPTIONS] serve [serve-OPTIONS] [Scripts]\n\nApplication Options:\n      --cors                         Enable CORS [$CORS]\n  -b, --bind=                        Binding address (default: 127.0.0.1:8080) [$BIND]\n  -t, --timeout=                     Maximum execution timeout (default: 120s) [$TIMEOUT]\n  -s, --secret=                      JWT secret for checking tokens. Use token command to create token [$SECRET]\n  -B, --buffer=                      Buffer response size (default: 8192) [$BUFFER]\n  -a, --async=[auto|forced|disabled] Async mode. auto - relies on async param in query, forced - always async, disabled - no async (default: auto) [$ASYNC]\n  -r, --retries=                     Number of additional retries after first attempt (async only) (default: 3) [$RETRIES]\n  -d, --delay=                       Delay between attempts (async only) (default: 3s) [$DELAY]\n  -W, --workers=                     Maximum number of workers for sync requests. Default is 2 x num CPU [$WORKERS]\n  -A, --async-workers=               Number of workers to process async requests (default: 2) [$ASYNC_WORKERS]\n  -q, --queue=                       Queue size for async requests. 0 means unbound (default: 8192) [$QUEUE]\n  -p, --payload=[stdin|arg|env]      Payload type - how to pass request body to the script (default: stdin) [$PAYLOAD]\n  -P, --payload-size=                Maximum payload size in bytes. Zero or negative means unlimited (default: 10485760) [$PAYLOAD_SIZE]\n  -M, --disable-metrics              Disable prometheus metrics [$DISABLE_METRICS]\n      --secure-metrics               Require token to access metrics endpoint [$SECURE_METRICS]\n      --auto-tls=                    Automatic TLS (Let's Encrypt) for specified domains. Service must be accessible by 80/443 port. Disables --tls [$AUTO_TLS]\n      --auto-tls-cache-dir=          Location where to store certificates (default: .certs) [$AUTO_TLS_CACHE_DIR]\n      --tls                          Enable HTTPS serving with TLS. Ignored with --auto-tls' [$TLS]\n      --tls-cert=                    Path to TLS certificate (default: server.crt) [$TLS_CERT]\n      --tls-key=                     Path to TLS key (default: server.key) [$TLS_KEY]\n\nHelp Options:\n  -h, --help                         Show this help message\n\n[serve command options]\n      -R, --run-as-script-owner      Run scripts from the same Gid/Uid as file. If isolation enabled, temp dir will be also chown. Requires root [$RUN_AS_SCRIPT_OWNER]\n      -w, --work-dir=                Working directory [$WORK_DIR]\n      -I, --disable-isolation        Disable isolated work dirs [$DISABLE_ISOLATION]\n      -D, --enable-dot-files         Enable lookup for scripts in dor directories and files [$ENABLE_DOT_FILES]\n\n[serve command arguments]\n  Scripts:                           Scripts directory\n```\n\nExample:\n\n**expose scripts in current dir**\n\n```\nwd serve .\n```\n\nin case there is a script `echo.sh` in the current directory, it will be available over `/echo.sh`.\n\n### Token\n\nIssue JWT token. By default - there is no expiration time and there is no limits for hooks.\n\n```\nUsage:\n  wd [OPTIONS] token [token-OPTIONS] [Hooks...]\n\nApplication Options:\n      --cors                         Enable CORS [$CORS]\n  -b, --bind=                        Binding address (default: 127.0.0.1:8080) [$BIND]\n  -t, --timeout=                     Maximum execution timeout (default: 120s) [$TIMEOUT]\n  -s, --secret=                      JWT secret for checking tokens. Use token command to create token [$SECRET]\n  -B, --buffer=                      Buffer response size (default: 8192) [$BUFFER]\n  -a, --async=[auto|forced|disabled] Async mode. auto - relies on async param in query, forced - always async, disabled - no async (default: auto) [$ASYNC]\n  -r, --retries=                     Number of additional retries after first attempt (async only) (default: 3) [$RETRIES]\n  -d, --delay=                       Delay between attempts (async only) (default: 3s) [$DELAY]\n  -W, --workers=                     Maximum number of workers for sync requests. Default is 2 x num CPU [$WORKERS]\n  -A, --async-workers=               Number of workers to process async requests (default: 2) [$ASYNC_WORKERS]\n  -q, --queue=                       Queue size for async requests. 0 means unbound (default: 8192) [$QUEUE]\n  -p, --payload=[stdin|arg|env]      Payload type - how to pass request body to the script (default: stdin) [$PAYLOAD]\n  -M, --disable-metrics              Disable prometheus metrics [$DISABLE_METRICS]\n      --secure-metrics               Require token to access metrics endpoint [$SECURE_METRICS]\n      --auto-tls=                    Automatic TLS (Let's Encrypt) for specified domains. Service must be accessible by 80/443 port. Disables --tls [$AUTO_TLS]\n      --auto-tls-cache-dir=          Location where to store certificates (default: .certs) [$AUTO_TLS_CACHE_DIR]\n      --tls                          Enable HTTPS serving with TLS. Ignored with --auto-tls' [$TLS]\n      --tls-cert=                    Path to TLS certificate (default: server.crt) [$TLS_CERT]\n      --tls-key=                     Path to TLS key (default: server.key) [$TLS_KEY]\n\nHelp Options:\n  -h, --help                         Show this help message\n\n[token command options]\n      -n, --name=                    Name of token, will be mapped as sub [$NAME]\n      -e, --expiration=              Token expiration. Zero means no expiration (default: 0) [$EXPIRATION]\n\n[token command arguments]\n  Hooks:                             allowed hooks (nothing means all hooks)\n```\n\n**basic token**\n\n    wd -s secret1 token\n\nAll hooks are allowed. Response can be used as content of `Authorization` header or query parameter `token`.\n\n**named token**\n\n    wd -s secret1 token -n token-name\n\n**token with expiration**\n\n    wd -s secret1 token -e 12h\n\n**token restricted to specific hooks**\n\n    wd -s secret1 token hook1 hook2 hook3\n   \n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freddec%2Fwd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freddec%2Fwd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freddec%2Fwd/lists"}