rego-language
This skill should be used when the user asks to "write rego", "rego syntax", "rego policy", "rego rule", "opa policy", mentions `.rego` files, asks about Rego built-in functions, comprehensions, or partial rules. Provides Rego v1 language reference and idiomatic patterns.
What this skill does
# Rego Language
Rego v1 language reference for writing OPA policies. Covers syntax, data types, rules, comprehensions, built-in functions, and idiomatic patterns.
**Rego Version:** v1 (released December 2024). All examples use v1 syntax with mandatory `if` and `contains` keywords.
**CRITICAL: DO NOT write v0 syntax.** Most Rego examples on the internet, in blog posts, and in training data use pre-v1 syntax. The following patterns are DEPRECATED and MUST NOT be used:
- `deny[msg] { ... }` -- WRONG. Use `deny contains msg if { ... }`
- `allow { ... }` -- WRONG. Use `allow if { ... }`
- `default allow = false` -- WRONG. Use `default allow := false`
- `arr[_]` or `arr[i]` -- WRONG. Use `some x in arr`
- `import future.keywords.if` -- WRONG. Keywords are built-in in v1.
If reviewing existing code that uses these patterns, flag them for migration.
## Modes of Operation
| Mode | Trigger | Action |
|------|---------|--------|
| **Write** | Creating new `.rego` files | Apply v1 syntax, idiomatic patterns |
| **Review** | Reviewing existing Rego | Check for v0 patterns, anti-patterns |
| **Reference** | "How do I X in Rego?" | Provide idiomatic solution |
---
## Package and Imports
Every Rego file starts with a package declaration:
```rego
package authz.kubernetes.pod_security
import rego.v1 # Enables v1 syntax (required for OPA < 1.0, optional for OPA >= 1.0)
import data.lib.helpers
import input.request
```
| Rule | Correct | Wrong |
|------|---------|-------|
| Package naming | `package authz.kubernetes` | `package authz-kubernetes` |
| Separator | Dots for hierarchy | Hyphens, slashes |
| Convention | Snake_case segments | CamelCase |
---
## Rules
### Complete Rules (single value)
```rego
# Boolean deny rule
deny if {
input.request.kind == "Pod"
not input.request.object.spec.securityContext.runAsNonRoot
}
# Value assignment
default allow := false
allow if {
input.user.role == "admin"
}
# With else chain
authorize := "allow" if {
input.user.role == "admin"
} else := "deny"
```
### Partial Rules (set/object generators)
```rego
# Set of violation messages (use `contains`)
violation contains msg if {
some container in input.request.object.spec.containers
container.securityContext.privileged
msg := sprintf("container '%s' must not be privileged", [container.name])
}
# Object generator
labels[key] := value if {
some key, value in input.request.object.metadata.labels
}
```
### Critical v1 Syntax Rules
| Pattern | v1 (Correct) | v0 (Deprecated) |
|---------|-------------|-----------------|
| Complete rule | `allow if { ... }` | `allow { ... }` |
| Partial set | `deny contains msg if { ... }` | `deny[msg] { ... }` |
| Default | `default allow := false` | `default allow = false` |
| Iteration | `some x in collection` | `collection[x]` |
---
## Data Types and Iteration
### Scalar Types
Strings, numbers, booleans, null.
### Composite Types
```rego
# Array (ordered, duplicates allowed)
arr := [1, 2, 3]
# Object (key-value)
obj := {"name": "nginx", "port": 80}
# Set (unordered, unique)
s := {1, 2, 3}
```
### Iteration with `some` and `in`
```rego
# Iterate array elements
some container in input.spec.containers
# Iterate object keys and values
some key, value in input.metadata.labels
# Iterate with index
some i, container in input.spec.containers
# Check membership
"admin" in input.user.roles
```
### Comprehensions
```rego
# Array comprehension
names := [c.name | some c in input.spec.containers]
# Set comprehension
ports := {c.containerPort | some c in input.spec.containers; some p in c.ports; p.containerPort}
# Object comprehension
label_map := {k: v | some k, v in input.metadata.labels; startswith(k, "app/")}
```
---
## Negation and Every
```rego
# Negation
deny if {
not input.spec.securityContext.runAsNonRoot
}
# Universal quantification
deny if {
every container in input.spec.containers {
not container.resources.limits.memory
}
}
```
---
## Functions
```rego
# User-defined function
has_label(obj, key) if {
some k, _ in obj.metadata.labels
k == key
}
# With default return
container_image(c) := image if {
image := concat(":", [c.image, c.tag])
} else := c.image
```
---
## Metadata Annotations
```rego
# METADATA
# title: Deny privileged containers
# description: Containers must not run in privileged mode
# custom:
# severity: high
# benchmark: CIS-K8s-5.2.1
deny contains msg if {
some c in input.spec.containers
c.securityContext.privileged
msg := sprintf("privileged container: %s", [c.name])
}
```
---
## Common Built-in Functions
| Category | Functions |
|----------|-----------|
| **Comparison** | `==`, `!=`, `<`, `>`, `<=`, `>=` |
| **Strings** | `concat`, `contains`, `startswith`, `endswith`, `sprintf`, `split`, `trim`, `lower`, `upper`, `replace`, `regex.match` |
| **Numbers** | `count`, `sum`, `product`, `max`, `min`, `abs`, `round`, `ceil`, `floor` |
| **Aggregates** | `count`, `sum`, `min`, `max`, `sort` |
| **Objects** | `object.get`, `object.keys`, `object.remove`, `object.union`, `object.filter` |
| **Sets** | `intersection`, `union` |
| **Types** | `is_string`, `is_number`, `is_boolean`, `is_null`, `is_array`, `is_object`, `is_set`, `type_name` |
| **Encoding** | `json.marshal`, `json.unmarshal`, `base64.encode`, `base64.decode`, `yaml.marshal`, `yaml.unmarshal` |
| **JWT** | `io.jwt.decode`, `io.jwt.verify_hs256`, `io.jwt.verify_rs256` |
| **HTTP** | `http.send` |
| **Crypto** | `crypto.sha256`, `crypto.hmac.sha256` |
| **Time** | `time.now_ns`, `time.parse_rfc3339_ns`, `time.date` |
| **Regex** | `regex.match`, `regex.find_all_string_submatch_n`, `regex.split` |
---
## Idiomatic Patterns
### Deny-by-default with explicit allow
```rego
package authz
import rego.v1
default allow := false
allow if {
input.user.role == "admin"
}
allow if {
input.user.role == "viewer"
input.method == "GET"
}
```
### Collecting violations
```rego
package kubernetes.admission
import rego.v1
violation contains msg if {
some c in input.review.object.spec.containers
not c.resources.limits.cpu
msg := sprintf("container '%s' missing CPU limit", [c.name])
}
```
### Helper library pattern
```rego
package lib.kubernetes
import rego.v1
pods contains pod if {
some pod in data.kubernetes.pods[_]
}
containers contains container if {
some pod in pods
some container in pod.spec.containers
}
```
---
## Safe Navigation for Optional Fields
Rego does NOT raise errors on missing fields -- expressions with undefined paths silently evaluate to undefined, causing rules to silently not fire. This is a critical bug source: a deny rule checking `c.securityContext.privileged` will NOT fire when `securityContext` is missing entirely, allowing the dangerous case through.
**Always use `object.get` for fields that may not exist:**
```rego
# WRONG: silently skips containers without securityContext
deny contains msg if {
some c in input.spec.containers
c.securityContext.privileged # undefined if securityContext missing -> rule doesn't fire
msg := sprintf("privileged: %s", [c.name])
}
# CORRECT: handles missing securityContext safely
deny contains msg if {
some c in input.spec.containers
sc := object.get(c, "securityContext", {})
object.get(sc, "privileged", false) == true
msg := sprintf("privileged: %s", [c.name])
}
```
Apply this pattern whenever accessing fields 2+ levels deep in input objects that may have optional fields (securityContext, resources, capabilities, annotations).
---
## Anti-Patterns to Avoid
| Anti-Pattern | Fix |
|-------------|-----|
| Using `=` for assignment | Use `:=` for local assignment |
| Implicit iteration (`arr[_]`) | Use `some x in arr` |
| Missing `if` keyword | Always use `if` in v1 |
| `deny[msg]` syntax | Use `deny contains msg if` |
| Deeply nested rules | Extract helper functions |
| `http.send` in hot paths | Cache data externally, use bundles |
---
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.