docs: add configuration guide with example and field descriptions#146
docs: add configuration guide with example and field descriptions#146WNN6231 wants to merge 10 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds docs/configuration.md: a comprehensive POP configuration guide with four example YAML files ( ChangesConfiguration Documentation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/configuration.md`:
- Line 3: The sentence "POP uses a YAML configuration file. Below is a complete
example with explanations for each field." overstates coverage; either replace
"with explanations for each field" with a softer phrase such as "with
explanations for the key fields" or "with explanations for most fields", or add
explicit per-field descriptions for every entry in the YAML example so the claim
is accurate; update the sentence text and/or expand the YAML block's inline
comments or an accompanying list so every YAML field has a matching explanation.
- Around line 93-122: Update the "Required Fields" table to include the missing
sections and fields shown in the example: add rows for bootstrapserver.* (e.g.,
bootstrapserver.active, bootstrapserver.addresses), policy.logfile,
policy.doubtlist.* (e.g., policy.doubtlist.action, policy.doubtlist.entries) and
any source-type-specific fields under sources.* (e.g., sources.*.mqtt_topic,
sources.*.file_pattern) and explicitly mark optional entries; ensure entries
reference the exact keys used elsewhere (bootstrapserver, policy.logfile,
policy.doubtlist.*, sources.*) so the table matches the documented configuration
schema.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/configuration.md`:
- Around line 134-149: Update the table so that fields which depend on the
chosen source are marked as conditionally required rather than simply "no":
change the entries for topic, validatorkey, bootstrap, bootstrapurl,
bootstrapkey to indicate "required when source: mqtt", filename to "required
when source: file", and upstream and zone to "required when source: xfr" (you
can use phrasing like "required when `source: mqtt`" etc.) and ensure the
`format` entry still documents per-source allowed formats; keep the rest of the
table unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
oej
left a comment
There was a problem hiding this comment.
Good work. Just have a few minor comments. Will ask the team to review too.
| | `name` | yes | Output identifier | | ||
| | `description` | yes | Human-readable description | | ||
| | `type` | yes | Source list type this output is derived from | | ||
| | `format` | yes | Output format (`rpz`) | |
|
|
||
| ## pop-outputs.yaml | ||
|
|
||
| Outputs define downstream DNS resolvers that receive RPZ NOTIFY and can perform AXFR/IXFR. |
There was a problem hiding this comment.
Clarify that these operations are over DNS
| outputs: | ||
| downstream-resolver: | ||
| active: true | ||
| name: "downstream-resolver" |
There was a problem hiding this comment.
Using the same name as the config option is not clever. Set the name to something different
| | Field | Required | Description | | ||
| |-------|----------|-------------| | ||
| | `policy.logfile` | no | Policy decision log file path | | ||
| | `policy.allowlist.action` | yes | Action for allowlisted names | |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/configuration.md`:
- Around line 306-310: Add explicit language identifiers to the two fenced code
blocks: for the block containing the domain list (the fence that includes
"example.com\nmalicious.example.org\nblocked.test.") add the "text" language
(i.e., change ``` to ```text), and for the block containing the CSV sample (the
fence that starts with "id,domain,category") add the "csv" language (i.e.,
change ``` to ```csv) so markdownlint MD040 is satisfied.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
|
Hi @oej! Thanks for the review 🙏 I've addressed all the comments — let me know if anything else needs adjustment! |
|
@WNN6231 Can you sign your commits and push again? |
There was a problem hiding this comment.
Pull request overview
Adds a new documentation page describing POP’s YAML configuration files, including example configs and field-by-field reference tables, addressing the lack of config documentation raised in #145.
Changes:
- Added
docs/configuration.mdwith example YAML for the 4 config files POP loads at startup. - Added field reference tables for main config, sources, outputs, and policy.
- Documented supported list file formats and provided policy examples.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| log: | ||
| file: "/var/log/dnstapir/pop.log" | ||
| verbose: false | ||
| debug: false | ||
|
|
| services: | ||
| rpz: | ||
| zonename: "rpz.example.com." | ||
| serialcache: "/var/cache/dnstapir/pop-serial.yaml" | ||
| reaper: | ||
| interval: 3600 | ||
|
|
| type: "allowlist" | ||
| format: "domains" # File format: domains, csv, or dawg | ||
| source: "file" | ||
| filename: "/etc/dnstapir/allowlist.txt" | ||
| immutable: false # If true, the list is never updated at runtime | ||
|
|
| | `nxdomain` | `.` — return NXDOMAIN | | ||
| | `nodata` | `*.` — return NODATA | | ||
| | `drop` | `rpz-drop.` — silently drop the query | | ||
| | `redirect` | redirect (target TBD in upstream config) | |
| | `dnstapir-pop.yaml` | Main config: logging, services, API/DNS/bootstrap servers, keystore | | ||
| | `pop-sources.yaml` | Intelligence sources (MQTT, file, RPZ zone transfer) | | ||
| | `pop-outputs.yaml` | RPZ downstream outputs | | ||
| | `pop-policy.yaml` | Policy rules for allow/deny/doubtlist decisions | | ||
|
|
||
| --- | ||
|
|
||
| ## dnstapir-pop.yaml |
- Split examples across all four config files (dnstapir-pop.yaml, pop-sources.yaml, pop-outputs.yaml, pop-policy.yaml) - Fix source field values: mqtt/file/xfr (not URLs) - Fix type field: allowlist/denylist/doubtlist (not protocol) - Fix file source formats: domains/csv/dawg - Fix valid policy actions per StringToAction in tapir package - Add missing outputs section
- Clarify that rpz is currently the only supported output format - Specify that NOTIFY and AXFR/IXFR are DNS operations - Use a distinct example name (primary-resolver) instead of downstream-resolver
- Add 'text' identifier to domains example block - Add 'csv' identifier to CSV example block - Fixes markdownlint MD040 rule
|
Hi @jschlyter, all commits are now signed and verified. Ready for another look. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
docs/configuration.md (1)
138-138: 💤 Low valueConsider rewording to reduce repetition.
The description uses "For" three times in succession, which slightly impacts readability.
Suggested alternative phrasing
-| `format` | yes | Data format. For `source: mqtt`: `json`. For `source: file`: `domains`, `csv`, or `dawg`. For `source: xfr`: `rpz` | +| `format` | yes | Data format: `json` for MQTT sources, `domains`/`csv`/`dawg` for file sources, `rpz` for zone transfers |🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/configuration.md` at line 138, The `format` field description is repetitive; rewrite the sentence for clarity by consolidating the examples and avoiding repeated "For". Update the table entry for `format` to something like: state that it specifies the data format and list per-source allowed values (e.g., `source: mqtt` -> `json`; `source: file` -> `domains`, `csv`, `dawg`; `source: xfr` -> `rpz`) so the `format` row (symbol: `format`) reads as a single, concise phrase referencing each source and its valid formats.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/configuration.md`:
- Around line 221-229: The docs note that the "redirect" action is a
placeholder; update the policy and AXFR code so REDIRECT is implemented
end-to-end: change the hardcoded CNAME target "what-to-do-about-this" to use a
configurable redirect target (add a config field and read it where the
action-to-RPZ mapping is performed), ensure the action-to-RPZ mapping routine
(the mapping function in the policy engine) emits the proper CNAME target for
REDIRECT, and modify ApplyDoubtPolicy to handle the REDIRECT enum/value and
include the redirect CNAME in doubtlist AXFR generation so redirect records are
present in AXFR output; also update the docs text to describe the final redirect
semantics and config key.
- Line 229: Update the docs entry for `redirect` to point to the actual
upstream/tapir config fields that supply the redirect target instead of "TBD":
mention that RPZ CNAME local-data targets are generated from
tapir.ActionToCNAMETarget and specify which tapir/upstream config keys populate
ActionToCNAMETarget, and clarify that the AXFR doubtlist path (ApplyDoubtPolicy)
only supports NXDOMAIN, NODATA, and DROP so `redirect` is not wired there; also
state whether redirect is available for denylist vs doubtlist (and if only
denylist supports redirect via tapir). Use the symbols ApplyDoubtPolicy and
tapir.ActionToCNAMETarget in the text so readers can locate the implementation.
---
Nitpick comments:
In `@docs/configuration.md`:
- Line 138: The `format` field description is repetitive; rewrite the sentence
for clarity by consolidating the examples and avoiding repeated "For". Update
the table entry for `format` to something like: state that it specifies the data
format and list per-source allowed values (e.g., `source: mqtt` -> `json`;
`source: file` -> `domains`, `csv`, `dawg`; `source: xfr` -> `rpz`) so the
`format` row (symbol: `format`) reads as a single, concise phrase referencing
each source and its valid formats.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| ### Valid action values | ||
|
|
||
| | Value | RPZ effect | | ||
| |-------|-----------| | ||
| | `allowlist` or `passthru` | `rpz-passthru.` — allow the name through | | ||
| | `nxdomain` | `.` — return NXDOMAIN | | ||
| | `nodata` | `*.` — return NODATA | | ||
| | `drop` | `rpz-drop.` — silently drop the query | | ||
| | `redirect` | redirect (target TBD in upstream config) | |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for action validation/processing in policy-related code
rg -n -C5 'action.*allowlist|action.*passthru|action.*nxdomain|action.*nodata|action.*drop|action.*redirect' --type go -g '!vendor/**'Repository: dnstapir/pop
Length of output: 1461
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate where RPZ "action" strings are parsed/validated into tapir action tags.
rg -n --hidden -S \
'allowlist|passthru|nxdomain|nodata|rpz-passthru|rpz-drop|redirect|NXDOMAIN|NODATA|DROP' \
--type go -g '!vendor/**' .
# Show the policy action mapping code and nearby parser logic (small windows only).
rg -n -S 'func \(.*\)\s*HasAction|HasAction\(' --type go -g '!vendor/**' .
rg -n -S 'type .*Action|const .*NXDOMAIN|const .*NODATA|const .*DROP|redirect' --type go -g '!vendor/**' .
# Print the relevant policy.go sections around the first match we saw.
sed -n '120,210p' policy.go 2>/dev/null || true
ls -1Repository: dnstapir/pop
Length of output: 4100
🏁 Script executed:
#!/bin/bash
set -u
# 1) Search for redirect/passthru/nxdomain/nodata/drop string handling in Go code
rg -n --hidden -S 'redirect|passthru|allowlist|nxdomain|nodata|rpz-passthru\.|rpz-drop\.' --type go -g '!vendor/**' .
# 2) Open the relevant action-parsing blocks we saw in sources.go and policy.go
echo "---- sources.go (around first action switch) ----"
sed -n '360,470p' sources.go
echo "---- policy.go (around rpzaction mapping) ----"
sed -n '120,210p' policy.go
# 3) Find how policy.allowlist.action is parsed
echo "---- Search for StringToAction usage ----"
rg -n --hidden -S 'StringToAction\(' --type go -g '!vendor/**' .
# 4) Find what tapir action constants exist in-repo (if any)
echo "---- Search for const/enum for actions ----"
rg -n --hidden -S 'type .*Action|const .*NXDOMAIN|const .*NODATA|const .*DROP|rpz-passthru|rpz-drop' --type go -g '!vendor/**' .
# 5) Confirm docs table and what it claims
echo "---- docs/configuration.md (action values table area) ----"
sed -n '200,260p' docs/configuration.mdRepository: dnstapir/pop
Length of output: 14389
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for redirect/RPZ redirect support in this repo's Go code.
rg -n --hidden -S 'redirect|rpz-redirect|rpz.*redirect' --type go -g '!vendor/**' .
# Search for RPZ action CNAME targets handled (confirm supported set).
rg -n --hidden -S 'rpz-[a-z\-]+\.' --type go -g '!vendor/**' .
# Find where tapir.Action parsing is defined/used; look for StringToAction definition in-repo.
rg -n --hidden -S 'func\s+.*StringToAction|StringToAction\s*[:=]' --type go -g '!vendor/**' .
# Inspect structs.go where AllowlistAction / types are declared to see allowed actions.
sed -n '1,140p' structs.go 2>/dev/null || true
# Show go.mod for tapir dependency provenance.
ls -1
cat go.mod 2>/dev/null || trueRepository: dnstapir/pop
Length of output: 38
🏁 Script executed:
#!/bin/bash
set +euo pipefail
echo "== go.mod =="
cat go.mod 2>/dev/null || true
echo "== Search for redirect in repo (Go/docs/config) =="
rg -n --hidden -S 'redirect' -g '!*vendor/**' .
echo "== Search for rpz-redirect or rpz redirect targets =="
rg -n --hidden -S 'rpz-.*redirect|rpz.*redirect' -g '!*vendor/**' .
echo "== Search for rpzaction mapping =="
rg -n --hidden -S 'rpzaction' -g '!*vendor/**' .
echo "== Search for CNAME RPZ target literals =="
rg -n --hidden -S 'case "\."|case "\*\."|rpz-passthru\.|rpz-drop\.' -g '!*vendor/**' .
echo "== Search for tapir.ActionToString keys incl redirect/passthru =="
rg -n --hidden -S 'ActionToString\[[' -g '!*vendor/**' .
echo "== Inspect policy.go further where rpz actions are computed =="
sed -n '1,240p' policy.goRepository: dnstapir/pop
Length of output: 10703
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate tapir module source in GOPATH module cache and search for action parsing.
GOPATH="$(go env GOPATH)"
MODCACHE="$GOPATH/pkg/mod"
echo "GOPATH=$GOPATH"
echo "MODCACHE=$MODCACHE"
# Find tapir module directory matching required version
echo "== tapir module dirs =="
ls -1 "$MODCACHE/github.com/dnstapir" 2>/dev/null | head -n 50 || true
echo "== Search tapir for StringToAction / Action parsing =="
rg -n -S 'func\s+StringToAction|type\s+Action|ActionToString|redirect|rpz-redirect|rpz-passthru|rpz-drop|ALLOWLIST|NXDOMAIN|NODATA|DROP' \
"$MODCACHE/github.com/dnstapir" -g '*tapir*' --no-mmap 2>/dev/null | head -n 200
# Specifically try to print the StringToAction function body if found.
echo "== Attempt to print StringToAction definition context =="
rg -n -S 'func\s+StringToAction\(' "$MODCACHE/github.com/dnstapir" -g '*tapir*' --no-mmap 2>/dev/null | head -n 20
# Open rpz.go around where rpzaction is assigned into CNAME target.
echo "== rpz.go: around CNAME target assignment =="
sed -n '1,260p' rpz.go | sed -n '1,200p' # keep output small
echo "== Search rpz.go for redirect emission =="
rg -n -S 'redirect|rpz-redirect' rpz.go || trueRepository: dnstapir/pop
Length of output: 236
🏁 Script executed:
#!/bin/bash
set +euo pipefail
GOPATH="$(go env GOPATH)"
MODCACHE="$GOPATH/pkg/mod"
TPIR_DIR="$(ls -1 "$MODCACHE/github.com/dnstapir" | head -n 1)"
echo "tapir module dir: $MODCACHE/github.com/dnstapir/$TPIR_DIR"
TAPIR_PATH="$MODCACHE/github.com/dnstapir/$TPIR_DIR"
echo "== tapir go files (top-level scan) =="
find "$TAPIR_PATH" -maxdepth 2 -name '*.go' | head -n 50
echo "== rg: StringToAction =="
rg -n -S 'StringToAction' "$TAPIR_PATH" -g '*.go' --no-mmap || true
echo "== rg: ActionToString =="
rg -n -S 'ActionToString' "$TAPIR_PATH" -g '*.go' --no-mmap || true
echo "== rg: redirect =="
rg -n -S 'redirect' "$TAPIR_PATH" -g '*.go' --no-mmap || true
echo "== rg: rpz-passthru / rpz-drop literals in tapir =="
rg -n -S 'rpz-passthru\.|rpz-drop\.' "$TAPIR_PATH" -g '*.go' --no-mmap || true
echo "== rg: NXDOMAIN / NODATA / DROP / passthru =="
rg -n -S 'NXDOMAIN|NODATA|DROP|passthru|ALLOWLIST' "$TAPIR_PATH" -g '*.go' --no-mmap || trueRepository: dnstapir/pop
Length of output: 7072
🏁 Script executed:
#!/bin/bash
set +euo pipefail
# Inspect tapir action parsing/mapping (bitmask.go)
TAPIR_PATH="/home/jailuser/go/pkg/mod/github.com/dnstapir/tapir@v0.0.0-20251117100352-b3b797ea3b38"
echo "== tapir/bitmask.go: StringToAction and ActionToString =="
sed -n '80,170p' "$TAPIR_PATH/bitmask.go" 2>/dev/null || true
echo "== tapir/bitmask.go: search for REDIRECT handling further =="
rg -n -S 'REDIRECT|redirect' "$TAPIR_PATH/bitmask.go" || true
echo "== tapir/cmd/rpz.go: redirect / rpz output =="
rg -n -S 'redirect|rpz-.*redirect|CNAME' "$TAPIR_PATH/cmd/rpz.go" || true
sed -n '1,120p' "$TAPIR_PATH/cmd/rpz.go" 2>/dev/null || true
# Inspect tapir structs.go for action bitfield and any redirect fields
echo "== tapir/structs.go: REDIRECT fields =="
rg -n -S 'REDIRECT|redirect' "$TAPIR_PATH/structs.go" || true
sed -n '250,430p' "$TAPIR_PATH/structs.go" 2>/dev/null || true
# Inspect pop's rpz.go around where it sets CNAME target and applies actions
echo "== pop/rpz.go: where rpzaction used in CNAME =="
sed -n '1,220p' rpz.go
sed -n '220,320p' rpz.go
# Search for ActionToString usage in pop and rpz CNAME target mapping.
echo "== pop: search ActionToString usage =="
rg -n -S 'ActionToString\[' . -g '!vendor/**'Repository: dnstapir/pop
Length of output: 21842
🏁 Script executed:
#!/bin/bash
set +euo pipefail
TAPIR_PATH="/home/jailuser/go/pkg/mod/github.com/dnstapir/tapir@v0.0.0-20251117100352-b3b797ea3b38"
echo "== tapir: search for placeholder text =="
rg -n -S 'what-to-do-about-this' "$TAPIR_PATH" -g '*.go' || true
echo "== tapir: search for CheckRedirect / redirect policy =="
rg -n -S 'CheckRedirect|redirectPolicy|REDIRECT' "$TAPIR_PATH" -g '*.go' || true
echo "== pop: search for REDIRECT handling in doubt policy =="
rg -n -S 'ApplyDoubtPolicy|REDIRECT|redirect' rpz.go policy.go sources.go -g '*.go' || true
# show ApplyDoubtPolicy for context
rg -n -S 'func ApplyDoubtPolicy' -n policy.go
sed -n '130,190p' policy.goRepository: dnstapir/pop
Length of output: 3617
Fix documented redirect action semantics (currently placeholder/partial).
allowlist/passthru, nxdomain, nodata, and drop are accepted by the policy engine and map to RPZ CNAME targets rpz-passthru., ., *., and rpz-drop. respectively. redirect is also accepted, but it currently maps to the hardcoded placeholder CNAME target what-to-do-about-this (so the redirect target is not actually implemented). Additionally, doubtlist AXFR generation uses ApplyDoubtPolicy, which does not handle REDIRECT, so redirect may be missing from AXFR output for doubtlist-derived records.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/configuration.md` around lines 221 - 229, The docs note that the
"redirect" action is a placeholder; update the policy and AXFR code so REDIRECT
is implemented end-to-end: change the hardcoded CNAME target
"what-to-do-about-this" to use a configurable redirect target (add a config
field and read it where the action-to-RPZ mapping is performed), ensure the
action-to-RPZ mapping routine (the mapping function in the policy engine) emits
the proper CNAME target for REDIRECT, and modify ApplyDoubtPolicy to handle the
REDIRECT enum/value and include the redirect CNAME in doubtlist AXFR generation
so redirect records are present in AXFR output; also update the docs text to
describe the final redirect semantics and config key.
| | `nxdomain` | `.` — return NXDOMAIN | | ||
| | `nodata` | `*.` — return NODATA | | ||
| | `drop` | `rpz-drop.` — silently drop the query | | ||
| | `redirect` | redirect (target TBD in upstream config) | |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for redirect action implementation
rg -n -C5 'redirect' --type go -g '*policy*.go' -g '!vendor/**'Repository: dnstapir/pop
Length of output: 38
🏁 Script executed:
#!/bin/bash
# Inspect docs context around the redirect row
sed -n '210,245p' docs/configuration.md
# Broader search for redirect handling across the repo (excluding vendor)
rg -n -C3 'redirect' -S -g'!vendor/**'Repository: dnstapir/pop
Length of output: 1922
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Find redirect handling in Go across the whole repo (excluding vendor)
rg -n -S --type go 'case\s+"redirect"|case\s+`redirect`|"redirect"' -g '!vendor/**'
# 2) Locate the action mapping by searching for other known action strings
rg -n -S --type go '(allowlist|passthru|nxdomain|nodata|rpz-drop)' -g '!vendor/**'Repository: dnstapir/pop
Length of output: 38
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for any RPZ redirect RHS emission (often uses rpz- prefix)
rg -n -S --type go 'rpz-redirect|rpz.*redirect|redirect\.' -g '!vendor/**'
# Find where RPZ action strings are generated/emitted (look for rpz- constants broadly)
rg -n -S --type go 'rpz-[a-z0-9-]+' -g '!vendor/**' --no-messages | head -n 50
# Show full docs context around the redirect row
sed -n '215,240p' docs/configuration.mdRepository: dnstapir/pop
Length of output: 38
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find how other documented actions are implemented in Go
rg -n -S --type go 'allowlist|passthru|nxdomain|nodata|rpz-drop|drop' -g '!vendor/**'
# Locate the policy/action dispatch area by looking for comparisons/switches (heuristic)
rg -n -S --type go '(switch|case|if)\s*.*(allowlist|passthru|nxdomain|nodata|drop)' -g '!vendor/**'
# Confirm there are no other docs mentions of redirect/target nearby
sed -n '220,238p' docs/configuration.mdRepository: dnstapir/pop
Length of output: 7394
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where tapir.Action parsing/string mapping is implemented (may include redirect support)
rg -n -S --type go 'StringToAction|ActionToString|type Action|const .*Action|REDIRECT' -g '!vendor/**'
# Specifically look for any redirect-like action identifiers in this repo (often tapir.REDIRECT)
rg -n -S --type go 'tapir\.(REDIRECT|Redirect|RPZREDIRECT|RPZ_REDIRECT)' -g '!vendor/**'
# Show the redirect row docs context around line 229
sed -n '220,236p' docs/configuration.mdRepository: dnstapir/pop
Length of output: 1370
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Repo-wide occurrences of the word redirect (excluding vendor/node_modules)
rg -n -S 'redirect' -g '!vendor/**' -g '!node_modules/**'
# Inspect how RPZ responses are computed (policy.go)
sed -n '1,240p' policy.go
# Inspect RPZ generation logic (rpz.go) around where actions are mapped/combined
sed -n '1,220p' rpz.goRepository: dnstapir/pop
Length of output: 13963
🏁 Script executed:
#!/bin/bash
set -euo pipefail
cat go.mod
rg -n "dnstapir/tapir" go.sum | head -n 20Repository: dnstapir/pop
Length of output: 2528
🌐 Web query:
dnstapir tapir redirect ActionToCNAMETarget StringToAction
💡 Result:
The terms “dnstapir tapir redirect ActionToCNAMETarget StringToAction” do not map to a single, clearly documented technical feature in the authoritative sources I located. From the sources I found: 1) DNS TAPIR (dnstapir.se) DNS TAPIR’s architecture describes DNS query logging/analysis components (Resolver → Minimise → Core) and that Core analyzes aggregated DNSTAP data and reports anomalies as “observations”. The pages I found do not mention symbols like ActionToCNAMETarget or StringToAction, nor a “redirect” action mapping [1][2]. 2) Tapir (softwaremill/tapir) Tapir’s official docs explain EndpointInput/endpoint inputs and how to capture query parameters via queryT (single parameter by name) and queryParams (all query parameters). The docs I found do not mention ActionToCNAMETarget or StringToAction [3][4]. 3) “redirect” actions exist in other products, but don’t match your provided identifiers For example, redirection.io documents a “Redirection” action that takes a target URL and status code [5], and ngrok documents a “Redirect Action” that transforms URLs via regex/CEL interpolation. These are different configuration models and do not define the exact symbols you provided [6]. What I need to answer precisely: please share the repository/link or a snippet where “ActionToCNAMETarget” and “StringToAction” appear (or confirm the exact project name and language/runtime). With that, I can do targeted follow-up searches and provide a fully source-cited explanation.
Citations:
- 1: https://www.dnstapir.se/docs/dnstapir-architecture/
- 2: https://www.dnstapir.se/docs/dnstapir-core/
- 3: https://tapir.softwaremill.com/en/v1.11.49/endpoint/ios.html
- 4: https://github.com/softwaremill/tapir/blob/v0.17.0-M9/generated-doc/out/endpoint/ios.md
- 5: https://redirection.io/documentation/user-documentation/actions-reference
- 6: https://ngrok.com/docs/traffic-policy/actions/redirect
🌐 Web query:
rpz redirect target TBD upstream config dnstapir tapir
💡 Result:
The RPZ “redirect target” is the CNAME “local data” value placed in the RPZ zone (i.e., the CNAME RDATA that the policy returns for a matching trigger). For example, the DROP action is encoded by a CNAME whose target is rpz-drop., which results in the query being discarded (no response sent to the client) [1]. Redirects to a “walled garden” are implemented by using a CNAME whose target is the walled-garden name (commonly written as a CNAME to the desired garden hostname, and optionally using wildcard forms for logging / templating) [1][2]. How that relates to “upstream config dnstapir tapir”: DNS TAPIR’s TAPIR Edge/Policy Processor can manipulate resolver responses (including redirecting users) and is connected to policy generation and response handling via RPZ, while DNSTAP is used for logging/observation of DNS traffic flowing through the system [3][4]. In other words, “dnstapir/tapir” provides/produces policy inputs (an RPZ feed/config) based on observations, but the actual “redirect target” that the resolver returns is still the RPZ CNAME local-data target contained in that RPZ policy feed [1][4]. If you tell me which resolver you’re configuring (Unbound/BIND/PowerDNS/other) and the RPZ zone/trigger name you’re using, I can map the exact config field that corresponds to the CNAME local-data “target” for “TBD”.
Citations:
- 1: https://www.ietf.org/archive/id/draft-vixie-dns-rpz-02.txt
- 2: https://rpz-block-list.readthedocs.io/en/latest/rpz-zone.html
- 3: https://www.dnstapir.se/docs/tapir-info-mgmt-en/
- 4: https://www.dnstapir.se/docs/dnstapir-architecture/
Clarify redirect action support and where the redirect target is configured.
docs/configuration.md lists redirect (target TBD in upstream config) as a valid action, but this repo doesn’t provide any redirect-specific mapping: the AXFR doubtlist path (ApplyDoubtPolicy) only handles NXDOMAIN, NODATA, and DROP, so redirect isn’t wired there. RPZ CNAME “local data” targets are generated via tapir.ActionToCNAMETarget[...], so “TBD” should explicitly point to the upstream/tapir config field(s) that define the redirect target and note whether redirect works for denylist vs doubtlist.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/configuration.md` at line 229, Update the docs entry for `redirect` to
point to the actual upstream/tapir config fields that supply the redirect target
instead of "TBD": mention that RPZ CNAME local-data targets are generated from
tapir.ActionToCNAMETarget and specify which tapir/upstream config keys populate
ActionToCNAMETarget, and clarify that the AXFR doubtlist path (ApplyDoubtPolicy)
only supports NXDOMAIN, NODATA, and DROP so `redirect` is not wired there; also
state whether redirect is available for denylist vs doubtlist (and if only
denylist supports redirect via tapir). Use the symbols ApplyDoubtPolicy and
tapir.ActionToCNAMETarget in the text so readers can locate the implementation.
Closes #145
Added docs/configuration.md with:
Summary by CodeRabbit