Security

Cedar Authorization

Cedar policies control three authorization domains in Lattice: cluster access, secret access, and security overrides. All domains use default-deny semantics — access must be explicitly granted.

This guide covers Cedar authorization patterns and examples. For the CedarPolicy CRD spec and field reference, see the CedarPolicy API reference.

Overview

Cluster Access

Controls which users and groups can connect to Kubernetes clusters via the auth proxy.

Secret Access

Controls which services can retrieve secrets from providers during service compilation.

Security Overrides

Controls which services can relax Pod Security Standards (capabilities, privileged mode, host networking).

Entity Model

Cedar policies reference six entity types that map to Lattice authorization concepts.

Lattice::User principal

Individual users from OIDC. Referenced by email, e.g. "alice@example.com".

Lattice::Group principal

User groups from the OIDC groups claim. Referenced by group name, e.g. "sre-team".

Lattice::Service principal

Pod/service identity as "namespace/name". Attributes: namespace, name.

Lattice::Cluster resource

Kubernetes cluster. Attributes: environment, region, tier.

Lattice::SecretPath resource

Secret identity as "provider:path". Attributes: path, provider.

Lattice::SecurityOverride resource

Security feature as "category:id". Attributes: category, override_id.

Actions

Three Cedar actions map to the authorization domains.

Lattice::Action::"AccessCluster" Cluster proxy access. Principal: User/Group. Resource: Cluster.
Lattice::Action::"AccessSecret" Secret retrieval during service compilation. Principal: Service. Resource: SecretPath.
Lattice::Action::"OverrideSecurity" PSS relaxation (capabilities, privileged, etc.). Principal: Service. Resource: SecurityOverride.

Cluster Access Policies

Cluster access policies control which users and groups can connect to clusters. The principal is a Lattice::User or Lattice::Group, and the resource is a Lattice::Cluster.

cluster-access.cedar
// SRE team can access all production clusters
permit (
  principal in Lattice::Group::"sre-team",
  action == Lattice::Action::"AccessCluster",
  resource
) when {
  resource.environment == "production"
};

// Developers can access staging clusters in their region
permit (
  principal in Lattice::Group::"developers",
  action == Lattice::Action::"AccessCluster",
  resource
) when {
  resource.environment == "staging"
};

Secret Access Policies

Secret access policies control which services can retrieve secrets during compilation. The principal is a Lattice::Service and the resource is a Lattice::SecretPath. Use resource.path like for wildcard matching.

Namespace-Scoped Access

secret-namespace.cedar
// Payments namespace services can access payments/* secrets
permit (
  principal,
  action == Lattice::Action::"AccessSecret",
  resource
) when {
  principal is Lattice::Service &&
  principal.namespace == "payments" &&
  resource.path like "secret/data/payments/*"
};

Provider Isolation

secret-provider-isolation.cedar
// Only platform namespace can use the vault-admin provider
forbid (
  principal,
  action == Lattice::Action::"AccessSecret",
  resource
) when {
  resource.provider == "vault-admin" &&
  !(principal is Lattice::Service && principal.namespace == "platform")
};

Environment Boundaries

secret-staging-forbid.cedar
// Staging clusters cannot access production secrets
forbid (
  principal,
  action == Lattice::Action::"AccessSecret",
  resource
) when {
  resource.path like "secret/data/production/*"
};

Security Override Policies

Security override policies control which services can relax Pod Security Standards. The principal is a Lattice::Service and the resource is a Lattice::SecurityOverride.

Override types: capability:NET_ADMIN, capability:SYS_MODULE, privileged, runAsRoot, hostNetwork, shareProcessNamespace

Specific Service Override

override-specific.cedar
// Grant NET_ADMIN capability to the nzbget service for VPN sidecar
permit (
  principal == Lattice::Service::"media/nzbget",
  action == Lattice::Action::"OverrideSecurity",
  resource == Lattice::SecurityOverride::"capability:NET_ADMIN"
);

Namespace-Wide Override

override-namespace.cedar
// Legacy namespace gets broad security overrides
permit (
  principal,
  action == Lattice::Action::"OverrideSecurity",
  resource
) when {
  principal is Lattice::Service &&
  principal.namespace == "legacy"
};

Category-Based Filtering

override-category.cedar
// Allow all capability overrides but forbid privileged mode
permit (
  principal,
  action == Lattice::Action::"OverrideSecurity",
  resource
) when {
  resource.category == "capability"
};

forbid (
  principal,
  action == Lattice::Action::"OverrideSecurity",
  resource == Lattice::SecurityOverride::"privileged"
);

Policy Inheritance

When propagate: true is set on a CedarPolicy, it is distributed to all child clusters in the hierarchy. Inherited policies receive the lattice.dev/inherited label on child clusters.

Inherited Policies

Distributed from parent clusters. Evaluated in a separate phase before local policies. Labeled with lattice.dev/inherited.

Local Policies

Defined directly on the cluster. Evaluated after inherited policies. Can further restrict or extend access within the inherited baseline.

propagated-policy.yaml
apiVersion: lattice.dev/v1alpha1
kind: CedarPolicy
metadata:
  name: secret-access-baseline
spec:
  description: "Baseline secret access policies for all clusters"
  policies: |
    // Every service can read its own namespace secrets
    permit (
      principal,
      action == Lattice::Action::"AccessSecret",
      resource
    ) when {
      principal is Lattice::Service &&
      resource.path like "secret/data/" + principal.namespace + "/*"
    };
  priority: 0
  propagate: true       # distributed to all child clusters

Evaluation Semantics

Cedar evaluation follows strict rules to produce deterministic authorization decisions.

1
Default Deny

If no policy matches, the request is denied. Access must be explicitly permitted.

2
Forbid Overrides Permit

If any forbid statement matches, the request is denied regardless of any permit statements.

3
Priority Ordering

Policies are evaluated in priority order (higher values first). Within the same priority, inherited policies are evaluated before local policies.

4
Batch Evaluation

All matching policies are collected and evaluated together. The final decision is the aggregate result across all applicable policies.