Skip to content

Predefined Policies Documentation Unclear #72

@TonyBostonTB

Description

@TonyBostonTB

Summary

The relationship between predefined policies (configured in Helm values under ingress.policies) and auto-generated policies (created from service annotations) is not clearly documented. It's unclear whether predefined policies are meant to be referenced or are merely "policy bases" that get extended with auto-generated variants.

Current Behavior

When a service is annotated with netbird.io/policy: 'longhorn-ui' and a predefined policy named longhorn-ui exists in the Helm configuration:

  • Both policies coexist: the predefined longhorn-ui AND the auto-generated longhorn-ui-namespace-servicename
  • The NBResource status shows a policyNameMapping that maps the logical name to the generated name
  • The predefined policy appears unused by the exposed service

Example Configuration

Helm values:

ingress:
  enabled: true
  allowAutomaticPolicyCreation: true
  policies:
    longhorn-ui:
      name: 'Longhorn UI Access'
      description: 'Team DevOps access to Longhorn UI'
      sourceGroups: ['team-devops']
      bidirectional: false

Service annotations:

annotations:
  netbird.io/expose: 'true'
  netbird.io/groups: 'service-longhorn-ui'
  netbird.io/policy: 'longhorn-ui'
  netbird.io/policy-source-groups: 'team-devops'
  netbird.io/policy-ports: '80'
  netbird.io/policy-protocol: 'tcp'

Result

Two NBPolicy resources are created:

  1. longhorn-ui (predefined policy from Helm values)
  2. longhorn-ui-longhorn-system-longhorn-frontend (auto-generated from service)

NBResource status shows:

status:
  policyName: longhorn-ui
  policyNameMapping:
    longhorn-ui: longhorn-ui-longhorn-system-longhorn-frontend
  # ... other fields ...

Questions Needing Documentation

1. What is the purpose of predefined policies?

  • Are they templates/bases for auto-generated policies?
  • Should they be directly assigned to resources?
  • Are they only for manually created NBResource objects?
  • Should they prevent auto-generation when a matching name is used?

2. How should the netbird.io/policy annotation work?

  • Does it reference an existing policy or just provide a naming hint?
  • Should it prevent auto-generation if a matching policy exists?
  • Is it meant to be a "base" that gets extended with service-specific details?

3. What is the policyNameMapping?

  • Why does it map from the predefined policy name to the auto-generated policy name?
  • Does this indicate the predefined policy is a "base" or "template"?
  • Why isn't the service using the predefined policy directly?

4. What is the intended workflow?

Option A: Predefined as Templates

  • Define common policy settings as predefined policies
  • These get extended/instantiated per-service with specific ports/destinations
  • Multiple services can reference the same predefined policy

Option B: Predefined as Standalone

  • Create predefined policies separately
  • Services reference them directly without auto-generation
  • Requires disabling allowAutomaticPolicyCreation?

Option C: Something else?

Code References

The policy lookup and creation logic is in internal/controller/nbresource_controller.go:

Policy Lookup (approximately line 100+):

kubernetesPolicyName := policy
if v, ok := nbResource.Status.PolicyNameMapping[policy]; ok {
    kubernetesPolicyName = v
}
err := r.Client.Get(ctx, types.NamespacedName{Name: kubernetesPolicyName}, &nbPolicy)

Policy Name Mapping Update (in handlePolicyCreate):

if nbResource.Status.PolicyNameMapping == nil {
    nbResource.Status.PolicyNameMapping = make(map[string]string)
}
nbResource.Status.PolicyNameMapping[policy] = generatedName

This code suggests predefined policies are "bases" that get mapped to auto-generated implementations, but this behavior is not documented.

Suggested Documentation Improvements

  1. Add a section explaining predefined policies vs auto-generated policies

    • What each type is for
    • When to use which approach
    • How they interact
  2. Clarify the policyNameMapping mechanism

    • What it does
    • Why it exists
    • How it affects policy behavior
  3. Provide examples of both workflows

    • Example: Using auto-generation with predefined bases
    • Example: Using manual policies with allowAutomaticPolicyCreation: false
    • Example: Mixed approach (if supported)
  4. Document how predefined policies interact with service annotations

    • What happens when netbird.io/policy matches a predefined policy
    • What happens when it doesn't match
    • Which policy settings are inherited vs overridden
  5. Explain when to use allowAutomaticPolicyCreation: true vs false

    • Use cases for each
    • Trade-offs
    • Security implications
  6. Add a troubleshooting section

    • "Why do I have two policies with similar names?"
    • "Which policy is my service actually using?"
    • "How do I verify my policy settings are applied correctly?"

Related Files

  • internal/controller/nbresource_controller.go - Policy lookup and creation logic
  • internal/controller/service_controller.go - Service annotation handling
  • docs/usage.md - Would benefit from expanded policy documentation
  • examples/ - Additional examples showing different policy patterns

Impact

The unclear documentation leads to:

  • Confusion about expected behavior
  • Difficulty troubleshooting policy issues
  • Potential security misconfigurations (e.g., assuming predefined policy settings apply when they don't)
  • User frustration when behavior doesn't match expectations

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions