This is very elegant with tags, thank you for the tip.
The important point for my config was to know that a view with tags is acting like is has an implicit answer: allowed.

I confirm it works, I use it this way:
views:
- answer: refused
  subnets:
  - 0.0.0.0/0
  - ::/0
- answer: allow
  options: &no_dns64
    dns64: false
  subnets:
  - 127.0.0.0/8
  - <other allowed IPv4 ranges>
- answer: allow
  dst-subnet: <dst_subnet_public_ipv6>
  options: *no_dns64
  subnets: &ipv6_allowed
  - ::1/128
  - <other allowed IPv6 ranges>
- answer: allow
  dst-subnet: <dst_subnet_anycast_ipv6>
  options: *no_dns64
  subnets: *ipv6_allowed
- tags: [ dns64 ]
  dst-subnet: <dst_subnet_anycast_dns64_ipv6>
  subnets: *ipv6_allowed
lua:
  policy-script: |
    assert(C.kr_rule_local_data_ins(
      kres.rrset(kres.str2dname('security.ubuntu.com.'), kres.type.AAAA, nil, C.KR_RULE_TTL_DEFAULT),
      nil, policy.get_tagset({'dns64'}), C.KR_RULE_OPTS_DEFAULT
    ) == 0)

Thanks you again!

Le 13 janv. 2026 à 10:57, Vladimír Čunát <vladimir.cunat@nic.cz> a écrit :

On 12/01/2026 00.11, * wrote:
However, I cannot use it in my production environment as this returns NODATA globally (all views) for security.ubuntu.com.
I have several views not using dns64 for which the AAAA record should be the existing original answer.
While on Lua level it's not ergonomic, tags are supported in these APIs, so you can do a tiny change, e.g.:

lua:
  policy-script: |
    assert(C.kr_rule_local_data_ins(
      kres.rrset(kres.str2dname('security.ubuntu.com.'), kres.type.AAAA, nil, C.KR_RULE_TTL_DEFAULT),
      nil, policy.get_tagset({'myTag'}), C.KR_RULE_OPTS_DEFAULT
    ) == 0) 


and then you just need to add myTag to the views where you want to apply this rule (in YAML).

You can read more about tags and views in the docs, around page
https://www.knot-resolver.cz/documentation/latest/config-policy-new.html