Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ include:

## What Counts as a Vulnerability

See the [Security Guide](../docs/security.md) and
[Threat Model](../docs/threat-model.md) for the security architecture, trust
See the [Security Guide](../docs/security/security.md) and
[Threat Model](../docs/security/threat-model.md) for the security architecture, trust
boundaries, and assumptions this section is based on.

In scope: the Agent Substrate control plane (`ateapi`, `atecontroller`,
Expand Down Expand Up @@ -81,7 +81,7 @@ from most to least severe:
- Sample applications under `demos/` and load-testing harnesses under
`benchmarking/`.
- Documented scope boundaries and future capabilities listed in
[docs/security.md](../docs/security.md) at the time of your report. If you are
[docs/security/security.md](../docs/security/security.md) at the time of your report. If you are
unsure whether a finding is covered by a documented limitation, report it
privately anyway and let a maintainer make the call.

Expand Down
120 changes: 120 additions & 0 deletions .github/workflows/site.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Builds the website in site/ on every pull request that could change it, and
Comment thread
moficodes marked this conversation as resolved.
# publishes it to GitHub Pages from main.
name: site
on:
pull_request:
paths:
- 'site/**'
- 'docs/**'
- 'demos/*/README.md'
- 'tools/site-content/**'
- 'tools/site-release-data/**'
- 'hack/site.sh'
- 'hack/test-site-templates.sh'
- '.github/workflows/site.yaml'
push:
branches: [main]
paths:
- 'site/**'
- 'docs/**'
- 'demos/*/README.md'
- 'tools/site-content/**'
- 'tools/site-release-data/**'
- 'hack/site.sh'
- 'hack/test-site-templates.sh'
- '.github/workflows/site.yaml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
# Keep in sync with module.hugoVersion.min in site/hugo.yaml.
HUGO_VERSION: 0.163.3
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
# site-release-data needs the latest release tag and its history.
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
# The root module, for tools/site-release-data. Hugo fetches Docsy
# with the same Go.
go-version-file: 'go.mod'
cache: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm
cache-dependency-path: site/package-lock.json
- name: Install Hugo
run: |
base="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}"
tarball="hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
cd "${RUNNER_TEMP}"
curl -sSfLO "${base}/${tarball}"
curl -sSfLO "${base}/hugo_${HUGO_VERSION}_checksums.txt"
grep " ${tarball}\$" "hugo_${HUGO_VERSION}_checksums.txt" | sha256sum -c -
mkdir -p hugo && tar -xzf "${tarball}" -C hugo hugo
echo "${RUNNER_TEMP}/hugo" >> "${GITHUB_PATH}"
- name: Install PostCSS
working-directory: site
run: npm ci
- name: Generate site content
run: hack/site.sh content
- name: Generate release data
run: hack/site.sh release-data
- name: Test templates
if: github.event_name == 'pull_request'
run: hack/test-site-templates.sh
- name: Configure Pages
id: pages
if: github.event_name != 'pull_request'
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- name: Build
working-directory: site
env:
BASE_URL: ${{ steps.pages.outputs.base_url }}
run: hugo build --environment production --minify ${BASE_URL:+--baseURL "${BASE_URL}/"}
- name: Upload artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: site/public
deploy:
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Do not add `reserved` statements to protos, deprecated aliases, fallbacks for ol

## Version Skew

From v1.0.0, changes must keep upgrades and rollbacks working under [docs/version-skew-policy.md](docs/version-skew-policy.md). Read it before you change an RPC, a CRD, the worker pod template, a database migration, or file(s) that `atelet` and `ateworker` share on a node.
From v1.0.0, changes must keep upgrades and rollbacks working under [docs/reference/version-skew-policy.md](docs/reference/version-skew-policy.md). Read it before you change an RPC, a CRD, the worker pod template, a database migration, or file(s) that `atelet` and `ateworker` share on a node.

## Commit Messages

Expand All @@ -149,7 +149,7 @@ Some attributes are defined in the registry but barred from metric labels: actor

`docs/metrics/substrate.yaml` holds the rules Weaver cannot express: the cardinality rules, the known exceptions, and the subsystems that emit no metrics. Read `blind_spots` before you attribute a fault to a component.

See the [metric registry](docs/observability.md#the-metric-registry) section of the observability guide.
See the [metric registry](docs/guides/observability.md#the-metric-registry) section of the observability guide.

## Testing Instructions

Expand All @@ -161,9 +161,9 @@ See the [metric registry](docs/observability.md#the-metric-registry) section of

## Security Considerations

Agent Substrate is built for zero-trust, multi-tenant execution of untrusted actors. Preserve and extend these invariants when modifying the codebase (see `docs/security.md` and `docs/threat-model.md` for the full architecture):
Agent Substrate is built for zero-trust, multi-tenant execution of untrusted actors. Preserve and extend these invariants when modifying the codebase (see `docs/security/security.md` and `docs/security/threat-model.md` for the full architecture):

- **Workload & Storage Isolation**: Actors run strictly inside `gVisor` (`cmd/ateworker-gvisor`) or `Cloud Hypervisor` microVM (`cmd/ateworker-microvm`) sandboxes; plain Linux containers are not supported. `atelet` scrubs actor directories across lifecycle transitions (`resetActorDirs`), and snapshots are stamped with `ActorSandboxRuntime` metadata and transferred via `cmd/objectstore-plugin`.
- **Component & Actor Identity (mTLS, JWTs, and JWKs)**: Inter-component communication uses mTLS backed by `cmd/podcertcontroller` (`podid`, `servicedns`, and `postgres` signers). Actor JWT signing (`internal/localjwtauthority`), verification (`internal/oidcjwt`), and key discovery (served via `cmd/ate-idp-server`) are built on the standard library's crypto packages. Extend those packages rather than adding `go-jose` or another JOSE library, so the code that decides whether a token is valid stays small and supports only the algorithms Substrate uses.
- **Control-Plane Authentication & Authorization**: `ate-api-server` checks every Control RPC against an embedded OpenFGA model (`cmd/ateapi/internal/authz/model.fga`), always enforced. Every served unary RPC needs an entry in `defaultRPCPermissions` (`registry.go`): an RPC without one is denied, and a test fails the build. Access is granted per global scope and atespace through AccessPolicy (`kubectl ate access-policy`); the install's bootstrap owner is the shared `ate-client` ServiceAccount that `kubectl ate` uses. See `docs/authorization.md` for roles and known gaps. Callers are authenticated via `SPIFFE` mTLS or configured OIDC `JWTProvider`s (`cmd/ateapi/internal/apiauthn`).
- **Control-Plane Authentication & Authorization**: `ate-api-server` checks every Control RPC against an embedded OpenFGA model (`cmd/ateapi/internal/authz/model.fga`), always enforced. Every served unary RPC needs an entry in `defaultRPCPermissions` (`registry.go`): an RPC without one is denied, and a test fails the build. Access is granted per global scope and atespace through AccessPolicy (`kubectl ate access-policy`); the install's bootstrap owner is the shared `ate-client` ServiceAccount that `kubectl ate` uses. See `docs/guides/authorization.md` for roles and known gaps. Callers are authenticated via `SPIFFE` mTLS or configured OIDC `JWTProvider`s (`cmd/ateapi/internal/apiauthn`).
- **Network Isolation, Ingress, & Egress**: `manifests/ate-install/ate-system-networkpolicies.yaml` enforces default-deny ingress across `ate-system`, and `cmd/atecontroller` reconciles per-`WorkerPool` `NetworkPolicy` objects. Actors run in private `/30` point-to-point veth network namespaces (`internal/ateworker/actornet`) with link-local blocking, policy-enforced DNS filtering (`internal/atunnel/dns`), and zero ambient credentials. Outbound traffic traverses `atunnel` to `atenet-egress`, which enforces per-actor `EgressPolicy` and injects credentials out-of-band via `cmd/credential-provider/kubernetes-secrets` (`k8s-credential-provider`) or actor JWT minting.
131 changes: 1 addition & 130 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,132 +1,3 @@
# How to Contribute

We would love to accept your patches and contributions to this project. Before
you spend a lot of time on a contribution, please review the following
guidelines.

## Before you begin

### Sign off your commits

Every commit must be signed off under the
[Developer Certificate of Origin](https://developercertificate.org/) (DCO).
The `Signed-off-by` line certifies that you wrote the change or otherwise have
the right to submit it under the project's license.

Sign off with your real name, not an anonymous ID or a false name. It doesn't
need to be your legal name, just the name the community knows you by. See the
[CNCF DCO guidelines](https://github.com/cncf/foundation/blob/main/policies-guidance/dco-guidelines.md).

Git adds the line with `-s`, using `user.name` and `user.email` from your git
config. The name and email must match the commit author.

```sh
git commit -s -m "fix typo in README"
```

The DCO check on your PR fails if any commit is missing a sign-off. To sign off
the commits already on your branch, then force-push:

```sh
git rebase --signoff upstream/main
```

### Review our Community Guidelines

This project follows [Google's Open Source Community
Guidelines](https://opensource.google/conduct/).

### Set up a local development environment

The [Quickstart (Development)](README.md#quickstart-development) in the README
covers bringing up a local cluster with the default (gVisor) runtime. To run
the microVM runtime locally — which needs `/dev/kvm`, or Lima nested
virtualization on Apple Silicon — see
[docs/dev/microvm-local.md](docs/dev/microvm-local.md). To measure where a
suspend or resume spends its time on such a cluster, follow
[docs/dev/suspend-resume-phase-breakdown.md](docs/dev/suspend-resume-phase-breakdown.md).

## Contribution process

This is a very new project, so we are still working out exactly how it is going
to be developed. For now, we are focused on iterating quickly to find the right
design and architecture. This has implications for contributors:

1) Things are moving quickly, so PRs may need to be rebased or updated
frequently. Small PRs that are focused on a single issue or feature are easier
to review and update than large PRs that touch many different parts of the
codebase.

2) While we welcome new contributors, we are really focused on the minimal
capabilities needed to make this project useful. Small fixes and cleanups can
go straight to a PR. Before you start anything larger, please discuss it with
us first (if there is an issue open, comment there and if not, open one), and
search open PRs so we are not duplicating work that is already in flight. We
want to make sure that your work is aligned with our near-term goals for the
project.

3) PRs which are not aligned with our near-term goals may be closed without
extensive review. We are not trying to be discouraging, but we need to make
sure that we are focused on the most important work.

If you are building something that runs *on* Substrate rather than changing
Substrate itself, see [Integration
Repositories](docs/integration-repos.md) for where that code should live.

### Sizing PRs for review

We optimize PRs for easy review — large PRs get broken
down, small PRs get merged.

* **Large PRs**: split huge changes into a series of smaller PRs, each a
logically distinct feature. When the intermediate steps are not useful
on their own, keep the change as one PR split into commits at logical
break points for review. PRs are squash-merged, so only the branch
`HEAD` needs to build and pass tests.
* **Small and bulk PRs**: if you find a typo, review the whole file and
fix everything in one pass rather than sending the single edit. Group
related typo, doc, and single-line cleanup fixes into one PR rather
than opening several small ones for the same area. Maintainers may ask
you to consolidate fragmented PRs into one, or close them in favor of a
combined submission.

As a rough scale: S is under 30 changed lines, M under 100, L under 500, XL under 1000. Most PRs should be L or smaller; XL and above are candidates for breaking down.

### Code Reviews

All submissions, including submissions by project members, require review. We
use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests)
for this purpose.

Changes that add or alter behavior should come with tests, and existing tests
should be updated when behavior they cover changes. We will not merge code that
causes tests to fail. Every test runs in CI on every PR, so please don't add
tests whose only purpose is to raise coverage numbers. Tests should be
inherently valuable for future changes.

Follow the [PostgreSQL schema evolution rules](docs/dev/postgresql-schema-evolution.md) for each application schema change.

Each pull request title becomes its line in the [release notes](docs/dev/release-notes.md).

### Root-gated tests

Tests that need root (overlay mounts, mknod, `trusted.*` xattrs, ...) call
`roottest.Require(t, ...)` from [internal/roottest](internal/roottest) as
their first statement. They skip in a plain `go test ./...`; CI reruns every
package whose tests import that package under `sudo`. To run them locally:

```sh
hack/run-root-tests.sh
```

New privileged tests only need the `roottest.Require` call — no CI changes.

### Copyright Headers

Every file containing source code must include copyright and license
information. This includes any JS/CSS files that you might be serving out to
browsers. (This is to help well-intentioned people avoid accidental copying
that doesn't comply with the license.)

Our standard headers for various filetypes can be found in
[./hack/boilerplate](./hack/boilerplate/).
Moved to [docs/project/contributing.md](docs/project/contributing.md).
Loading
Loading