Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

232 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NACP — Nomad Admission Control Proxy

Quality Gate Status

NACP is a reverse proxy for the HashiCorp Nomad API. It intercepts job registration, planning, and validation requests, then runs configured mutation and validation policies before forwarding accepted jobs to Nomad.

NACP admission flow

Capabilities

StageIntegrationConfiguration type
MutationEmbedded OPA returning JSON Patchopa_json_patch
MutationOPA SDK/bundle returning JSON Patchopa_bundle_json_patch
MutationJSON-Patch webhookjson_patch_webhook
ValidationEmbedded OPAopa
ValidationOPA SDK/bundleopa_bundle
ValidationValidation webhookwebhook
ValidationNotation container-image verificationnotation

Policies receive a shared payload containing the rendered Nomad job and optional request context:

{
"job": { "ID": "example" },
"context": {
"clientIP": "192.0.2.10",
"accessorID": "optional-nomad-token-accessor",
"resolveToken": true,
"tokenInfo": {
"Policies": ["example-policy"]
}
}
}

tokenInfo is deliberately sanitized and never includes the Nomad token SecretID. See types.Payload and config.RequestContext for the source contract.

Admission flow

NACP applies mutators in configuration order, then runs validators against the final mutated job. Validators receive isolated job copies and cannot alter the job forwarded to Nomad.

Admission runs for PUT and POST requests to:

  • /v1/jobs
  • /v1/job/<id>
  • /v1/job/<id>/plan
  • /v1/validate/job

Other Nomad API traffic is proxied without admission processing. Mutator or integration failures stop the request. Validation errors stop registration and planning; for Nomad's validation endpoint they are merged into the Nomad-compatible validation response. Policy warnings are merged into successful Nomad responses.

Install

Release binary

Download an archive and its signed checksum from GitHub Releases.

Go

go install github.com/mxab/nacp/cmd/nacp@latest

Container

Release images are published to ghcr.io/mxab/nacp and run as a non-root user:

docker run --rm -p 6464:6464 \
-v "$PWD/config.hcl:/etc/nacp/config.hcl:ro" \
ghcr.io/mxab/nacp:latest \
-config /etc/nacp/config.hcl

Pin a version tag rather than latest for production deployments.

Quickstart

The module's required Go version is declared in go.mod. Build and run the first embedded-OPA example from its directory so its relative Rego path resolves correctly:

go build -o nacp ./cmd/nacp
cd example/example1
../../nacp -config example1.conf.hcl

In another terminal, point the Nomad CLI at NACP:

NOMAD_ADDR=http://localhost:6464 nomad job run example/example1/example1.nomad

Without -config, NACP listens on 0.0.0.0:6464 and proxies Nomad at http://localhost:4646.

Configuration

Top-level server settings are not wrapped in a server block:

bind="0.0.0.0"port=6464nomad {
address="http://localhost:4646"
}
validator"opa""costcenter" {
opa_rule {
filename="policies/costcenter.rego"query=<<EOHerrors = data.costcenter.errorswarnings = data.costcenter.warningsEOH
}
}

Configuration is validated before the server starts. Missing controller blocks, invalid HTTP endpoints, invalid ports, incomplete TLS key pairs, and bundle controllers without an opa_sdk block are rejected with actionable startup errors. An explicitly supplied but missing configuration file is also an error.

Current combined examples:

Transport and telemetry

NACP supports separate TLS configuration for its listener and upstream Nomad connection. OpenTelemetry logging, metrics, and tracing use the standard OTLP environment variables.

telemetry {
logging {
level="info"slog {
json=true
}
otel {
enabled=true
}
}
metrics {
enabled=true
}
tracing {
enabled=true
}
}

Security and availability

  • Run NACP only on a trusted network path and use TLS for production traffic.
  • If policies consume clientIP, ensure the proxy in front of NACP sanitizes X-Forwarded-For; NACP uses its first value.
  • Enabling resolve_token performs a Nomad /v1/acl/token/self lookup. Lookup failures stop admission rather than continuing without identity context.
  • Webhooks receive the full job and sanitized request context. They should use HTTPS and be treated as trusted policy services.
  • Webhook requests have a 30-second timeout and bounded responses. Network, timeout, malformed-response, and non-2xx failures fail admission closed.
  • OPA SDK/bundle support is currently experimental. Validate bundle refresh and degraded-mode behavior in your environment before relying on it in production.
  • insecure_skip_verify and repo_plain_http are intended only for controlled development environments.

Development

Run the default checks:

test -z "$(gofmt -l .)"
go vet ./...
go test ./...

Notation registry tests require Docker and are opt-in locally:

go test -tags=integration ./pkg/admissionctrl/notation

CI runs the full suite with the integration tag and publishes coverage to SonarCloud.

Documentation

Start with the generated OpenWiki quickstart, then continue to:

OpenWiki pages are generated by automation. Correct source code and maintained documentation first, then allow the OpenWiki workflow to refresh generated pages.

License

See LICENSE.

About

Admission Controller as a proxy for Nomad. Define OPA rules for validation and mutation or plugin remotes

Topics

Resources

Contributing

Security policy

Stars

52 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages