> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oasm.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Projects

> Keep a set of assets scanned on its own schedule, and see what every run found

A **Project** is a named part of your attack surface that OASM keeps scanned for you. It combines three things:

* **Scope** — which [assets](https://docs.oasm.io/asset.md) belong to the project, chosen by rules, by hand, or both
* **Workflows** — the pipelines of tools that scan those assets (see [Workflows](https://docs.oasm.io/workflows.md))
* **Triggers** — when each workflow runs on its own: on a schedule, or as soon as new assets join the project

Every run of a project scans only that project's assets, and the project remembers what each run found. That lets it tell you which vulnerabilities are **new**, which keep coming back (**recurring**), and which a later scan **did not see again** — possibly fixed.

Open **Projects** from the console sidebar (in the **Overview** section, under **AI Studio**; route `/projects`).

> [!NOTE]
>
> Projects replace **Groups** (asset groups). Existing groups, their assets, their workflows and their schedules were migrated to projects automatically. The `/asset-group` API and the `/groups` console pages no longer exist — use `/projects` instead.

***

## How a project works

```mermaid theme={null}
flowchart LR
  T[Targets] -->|discovery| A[Assets]
  A -->|scope rules / picked by hand| P[Project scope]
  P --> W[Project workflows]
  S[Schedule] --> W
  N[Assets added] --> W
  M[Run by hand] --> W
  W -->|jobs| K[Workers]
  K --> R[Runs & vulnerabilities<br/>new · recurring · not seen]
```

1. You add [targets](https://docs.oasm.io/target.md); discovery fills the [asset inventory](https://docs.oasm.io/asset.md).
2. The project's **scope rules** select the assets it should cover. With **auto-add** on, assets discovered later join the project as soon as they match a rule.
3. Each **workflow** of the project runs on those assets — when you start it, on its **schedules**, or when **assets are added**.
4. A run starts jobs that connected [workers](https://docs.oasm.io/worker.md) carry out. Results land in the inventory and in the project's **Vulnerabilities**, **Runs** and **Overview** tabs.

### Projects vs targets

| | Target | Project |
| - | - | - |
| **What it is** | Where discovery starts: a domain, IP, CIDR range or Git organization | A part of the discovered attack surface you want kept scanned |
| **Contains** | The assets discovered from it | Assets from any number of targets, selected by rules or by hand |
| **Runs** | The workspace's default discovery workflows, when the target is added or re-scanned | Its own workflows, by hand, on a schedule, or when assets join |
| **Example** | `example.com` | `Production web` — every `*.prod.example.com` host plus `203.0.113.0/24` |

A target answers "what do we own?"; a project answers "what do we keep scanning, how often, and what changed?".

***

## The Projects page

The Projects page shows one card per project:

| On the card | Meaning |
| - | - |
| **Severity bar** | Open vulnerabilities the project found, by severity |
| **+N new** | Open vulnerabilities first seen in the last 7 days |
| **Assets** | Assets in the project's scope |
| **Workflows** | Workflows the project runs |
| **Last run** | When a workflow of the project last ran |
| **Next run** | The next scheduled run, if any |
| **Trigger chips** | How the project runs on its own: schedules, "assets added", or by hand only. An archived project shows **Triggers off** |

Use the toolbar to search by name, show **Active**, **Archived** or **All** projects, and sort by **Highest risk** (most open critical, then high, then medium findings), **Newest**, **Last run**, **Name** or **Most assets**. Click a card to open the project.

***

## Create a project

Click **Create** on the Projects page (route `/projects/create`). The wizard has four steps; only the name and a pipeline are required.

**1. Info**

Give the project a **Name** (unique in the workspace) and an optional **Description** of what it covers — for example `Production hosts`.

**2. Scope**

Choose the assets in two ways, which you can combine:

* **By rules** — add include and exclude rules (see [Scope rules](#scope-rules)). The editor shows a live count of the **assets in scope**. Leave **Add assets found later when they match a rule** checked to keep the scope current as discovery finds new assets.
* **Pick by hand** — tick hosts from the asset inventory. Hand-picked assets stay in the project until you remove them.

You can also skip this step and add assets later from the **Assets** tab.

**3. Pipeline**

Choose what scans the assets:

* **From a template** — start from one of the workspace's default workflows, for example the basic vulnerability scan.
* **Pick tools** — build your own pipeline from the installed [tools](https://docs.oasm.io/tools.md), in stages (see [Build a pipeline](#build-a-pipeline)).

**4. Triggers**

Decide when the pipeline runs on its own (see [Triggers](#triggers)). A new project starts with one schedule to pick and **When assets join the project** turned on; remove what you do not need. Times are entered in your timezone and stored in UTC.

Leave **Run once right after creating** checked to scan the current scope immediately. If the scope is still empty, the project is created and simply waits for assets.

Click **Create**. The project opens on its **Overview** tab. If any part fails — an invalid rule, a tool that needs configuration — nothing is created, so you never end up with a half-built project.

***

## Scope rules

Scope rules decide which assets of the workspace belong to the project. Each rule **includes** or **excludes** the assets it matches:

| Rule type | Value | Matches |
| - | - | - |
| **Target** | A target of the workspace | Every asset discovered from that target |
| **Hostname** | A hostname, with `*` wildcards — `*.example.com`, `api-*.example.com` | Assets whose value matches the pattern (case-insensitive). A bare `*` is refused |
| **CIDR** | An IPv4 or IPv6 network — `203.0.113.0/24`, `2001:db8::/32`. A single address becomes `/32` or `/128` | IP assets inside the range, **and** hostnames that resolved to an address inside it (DNS records or HTTP probes) |
| **Asset** | One asset | That asset |

How the rules combine:

* An asset is in scope when it matches **at least one include rule** and **no exclude rule**.
* Exclude rules only remove assets; a rule set with no include rule selects nothing.
* Each rule shows how many assets it matches, so you can check a rule before you save it.
* Saving the rules syncs the project right away: assets the rules now select join (**source: Rule**), and rule-added assets the rules no longer select leave.

**Hand-picked assets are never touched by rules.** They stay in the project until you remove them by hand, even if no rule matches them.

### Auto-add new assets

With **Add assets found later when they match a rule** on (the default), every asset that discovery finds later is checked against the rules of every active project in the workspace. Matching assets join automatically, and the project's **assets added** triggers pick them up. Turn it off to apply the rules only when you save them.

### Removing an asset that a rule selects

When you remove an asset from the **Assets** tab and an include rule still matches it, OASM adds an **exclude** rule for that asset — otherwise the next rule sync would add it straight back. You can delete that exclude rule later to let it back in.

> [accordion] Example: production web hosts, minus the staging range
>
> | Mode | Type | Value |
> | - | - | - |
> | Include | Hostname | `*.prod.example.com` |
> | Include | CIDR | `203.0.113.0/24` |
> | Exclude | CIDR | `203.0.113.128/25` |
>
> Every host under `prod.example.com` and every asset in `203.0.113.0/24` joins, except those in the upper half of the range — including hostnames that resolve there.

***

## Project workflows

A project runs one or more **workflows**. Each one is a pipeline of tools that the project owns: it is created for the project, edited from it, and deleted with it. Several workflows let you scan the same scope differently — for example a quick daily web scan and a deeper weekly scan.

On the **Workflows** tab, each workflow card shows its pipeline, its triggers (or **Manual only**), and its last run. From the card you can:

* **Run** it now (see [Run a workflow](#run-a-workflow))
* **View workflow** — read its definition as a YAML file (see [Workflows](https://docs.oasm.io/workflows.md#the-workflow-file))
* **Edit** its name, pipeline and triggers
* **Remove** it — its triggers and run history are deleted with it; vulnerabilities stay in the workspace

Click **Add workflow** to create another one from:

* **From a template** — a default workflow of the workspace
* **Pick tools** — your own pipeline
* **Copy from a project** — a copy of a workflow of any project in the workspace, including its tool configuration

### Build a pipeline

With **Pick tools**, you add installed tools and place each one in a **stage**:

* Tools in the same stage run in parallel.
* A stage starts once every tool of the previous stage is done.
* A pipeline has up to 10 stages.

For each tool you can choose:

| Setting | Meaning |
| - | - |
| **Category** | The mode to run a multi-mode tool in — for example `nmap` as a port scanner or a vulnerability scanner |
| **Input** | Which kinds of data the tool receives, best first — for example only `web` services. Defaults to what the tool declares. See [Data kinds](https://docs.oasm.io/workflows.md#data-kinds) |
| **Configuration** | A saved config profile, or an inline configuration. Connector tools that need configuration must have one or the other before the pipeline can be saved |

> [!NOTE]
>
> A typical web pipeline is **Stage 1:** `naabu` (ports) → **Stage 2:** `httpx` (HTTP probe) → **Stage 3:** `nuclei` with **Input** `web` (vulnerabilities). Each stage sees what the previous one found in the same run, so `nuclei` scans every live web service on its real scheme and port. Left at its default input, `nuclei` takes `host` first and scans each host once, by hostname.

Saving a new pipeline keeps the workflow's triggers as they are.

***

## Triggers

Triggers say when a workflow runs on its own. They belong to the workflow — set them in the create wizard or in the workflow editor (**Edit** on a workflow card) under **When it runs**. With no trigger, a workflow runs only when someone starts it.

### Schedules

A schedule runs the workflow on **the whole scope** at fixed times. Pick a time with the schedule builder; it is saved as a 5-field cron expression in UTC.

* A workflow can have several schedules (up to 20) — for example weekdays at 02:00 and Saturdays at 14:00.
* Two schedules at the same time are refused.
* Each workflow keeps its own clock: a project with several workflows runs each on its own schedules.

### When assets join the project

This trigger scans **only the assets that just joined**, not the whole scope. Assets join when you add them by hand, when a rule edit adds them, or when discovery finds a matching asset and auto-add is on.

| Setting | Default | Meaning |
| - | - | - |
| **Gather for (minutes)** | 10 | New assets are collected for this long, then scanned in one run. `0` starts a run right away. Up to 1440 |
| **Most assets per run** | 200 | A larger batch starts further runs right away. 1–5000 |
| **Only assets of** | none checked | Restrict to assets of **Domains**, **IPs**, **CIDR ranges** or **Repositories** targets. None checked means every new asset |

The gathering window keeps a large discovery from flooding your workers: 500 new subdomains become three runs, not 500. An asset removed from the project before the window closes is not scanned. A workflow has at most one "assets added" trigger.

### Turning triggers on and off

Each schedule and the "assets added" trigger has an **Active** switch. Turning one off keeps its settings in the workflow without running it; turn it on again whenever you want. [Archiving](#archive-reopen-and-delete) the project turns every trigger off at once.

The **Schedule** tab shows the runs planned for the **next 7 days** and lists every trigger of the project with its workflow, condition, last fire time, next run and status. "Assets added" triggers have no fixed time, so they appear in the trigger list but not in the 7-day plan. To change a trigger, edit its workflow.

***

## Run a workflow

Start a run whenever you need one — after an infrastructure change, or to verify a fix:

**1. Open the run dialog**

Click **Run** in the project header and pick a workflow, or click **Run** on a workflow card.

**2. Choose what to scan**

* **Whole scope** — every asset of the project
* **Selected assets** — search and tick the assets to scan

**3. Start it**

The run starts and a notification links to it (**Open run**). Follow its progress in the **Runs** tab or the [Job Registry](https://docs.oasm.io/jobs.md).

A run is refused with a clear message when the project has no assets, when none of the selected assets belong to the project, or when the tool of a first-stage step is not installed in the workspace.

***

## Project tabs

The project page (route `/projects/:id/:tab`) has seven tabs. Counts appear as badges on the tabs.

### Overview

* **Assets**, **Open vulnerabilities** and **New in 7 days** at a glance, plus the **Next run** — the next schedule, "When assets are added", or "Only when run by hand".
* **New vulnerabilities per week**, by severity.
* **To fix** — the most severe open vulnerabilities; click one to open its details.
* **Recent activity** — what happened to the project and who did it: runs and what they found, assets picked, removed, discovered or moved by a rule edit, workflows added, edited or removed, vulnerabilities dismissed, and the project's creation, archiving and reopening. Configuration changes (settings, triggers) are kept in the [audit log](https://docs.oasm.io/audit-log.md).

### Assets

The **Scope** card lists the scope rules and whether new assets join on their own; click **Edit rules** to change them. Saving reports how many assets were added and removed.

Below it, the asset table shows each asset with:

* **Source** — **Rule**, with the rule that added it, or **Picked by hand**
* **Vulnerabilities** — open findings the project found on it
* **Last scan** — the project's last run that scanned it, or **Never**

Filter by source, click **Add** to pick hosts by hand, or remove an asset. Removing an asset never deletes it from the workspace, and its findings stay.

### Vulnerabilities

Every vulnerability the project's runs reported, with its severity, **provenance**, first seen and last seen. Filter by severity, provenance, status (open or dismissed) and workflow, or follow a link from a run to see only what that run found.

| Provenance | Meaning |
| - | - |
| **New** | Reported by one run of the project so far |
| **Recurring** | Reported again by later runs |
| **Not seen again** | A later scan of the same asset **with the same tool** did not report it — possibly fixed |

"Not seen again" compares each finding with the last scan of its own asset by its own tool. A run that only scanned a few new assets therefore never marks the rest of the project as fixed.

Open a vulnerability to see its details and **timeline**: the project runs since it was first seen that scanned its asset with the reporting tool, each marked **Reported** or **Scanned, not reported**. Dismissing a vulnerability applies to the whole workspace, not just the project.

### Workflows

The project's workflows — see [Project workflows](#project-workflows).

### Schedule

The runs planned for the next 7 days and every trigger — see [Triggers](#triggers).

### Runs

Every run of the project, newest first:

| Column | Shows |
| - | - |
| **Run** | The workflow and the run's status |
| **Triggered by** | **Manual**, **Schedule** or **Assets added** |
| **Scope** | Assets the run covered |
| **Steps** | Steps finished out of the total |
| **Found** | Vulnerabilities the run found first, and those it reported again |
| **Started** / **Duration** | When it started and how long it took |

Filter by trigger and workflow. Open a run to see its graph and jobs in the [Job Registry](https://docs.oasm.io/jobs.md).

### Settings

* **Information** — rename the project or change its description.
* **Notifications** — runs of a project notify like any scan: new vulnerabilities and scan results go to the workspace's [notification](https://docs.oasm.io/notifications.md) and [integration](https://docs.oasm.io/integrations/overview.md) channels.
* **Danger Zone** — archive, reopen or delete the project.

***

## Archive, reopen and delete

| Action | What happens |
| - | - |
| **Archive** | Every schedule and trigger stops, auto-add stops, and the project becomes read-only. All data — assets, runs, vulnerabilities — stays. The project moves to the **Archived** filter |
| **Reopen** | The project becomes editable again and its active schedules are registered again |
| **Delete** | Deletes the project, the workflows it owns and their run history. You confirm by typing `delete`. Assets and vulnerabilities stay in the workspace |

***

## Permissions

| Permission | Allows |
| - | - |
| `project.read` — View projects | Open the Projects page, every tab, runs and vulnerabilities |
| `project.write` — Create and edit projects | Create, edit, archive, reopen and delete projects; change scope, workflows and triggers; start runs |

Assign them through a [permission group](https://docs.oasm.io/permissions.md). Archived projects refuse every change until they are reopened.

***

## Events and audit

Project changes are recorded in the [audit log](https://docs.oasm.io/audit-log.md) and published as events:

| Event | When |
| - | - |
| `project.created` | A project is created |
| `project.updated` | Its settings, assets, scope rules, workflows or triggers change. `metadata.change` says which — `settings`, `assets.added`, `assets.discovered`, `assets.removed`, `scope`, `workflow.added`, `workflow.updated`, `workflow.removed` or `triggers` — with counts or the workflow name |
| `project.archived` / `project.unarchived` | The project is archived or reopened |
| `project.deleted` | The project is deleted |

Assets joining through discovery are recorded with the **system** as the actor.

***

## API

Everything available in the console — scope rules, assets, pipelines, triggers, runs, and results — is also available through the API. See the API Reference tab.

***

## Common questions

> [accordion] Can an asset be in several projects?
>
> Yes. Projects are independent: the same asset can be in a "Production web" project scanned daily and a "PCI scope" project scanned weekly. Each project tracks its own runs and provenance for it.

> [accordion] Why did an asset I removed not come back after editing the rules?
>
> Removing an asset that a rule still matched added an exclude rule for it. Delete that exclude rule on the **Assets** tab to let the asset back in.

> [accordion] Why didn't a new asset join my project?
>
> Check that the project is not archived, that **Add assets found later when they match a rule** is on, and that the asset matches an include rule and no exclude rule. The rule list shows how many assets each rule matches.

> [accordion] Why did my run start nothing?
>
> A run needs assets in scope, and the first-stage tools must be installed. Steps whose input has nothing to scan — for example `nuclei` on hosts with no web service and `input: web` — are skipped and do not block later steps. See [Workflows](https://docs.oasm.io/workflows.md#how-a-run-executes).

> [accordion] Is “Not seen again” the same as fixed?
>
> Not necessarily. It means a later scan of the same asset with the same tool did not report it. Confirm the fix before you close related work, for example by running the workflow again on that asset with **Selected assets**.

> [accordion] What happened to my old groups?
>
> Every group became a project with the same assets (all hand-picked) and the same workflows. Each group schedule became a schedule trigger of its workflow, and past runs that clearly belonged to a group were linked to the project, so its history and vulnerability provenance start filled. Custom permission groups that had `group.read` / `group.write` now have `project.read` / `project.write`. Audit entries written before the change keep their old `asset_group.created` / `asset_group.deleted` actions.

***

## Best practices

* **Prefer rules to hand-picking.** A hostname or CIDR rule with auto-add keeps the scope current as your infrastructure grows; hand-pick only the exceptions.
* **Pair a schedule with "assets added".** The schedule rescans everything periodically; "assets added" catches new exposure within minutes instead of waiting for the next schedule.
* **Split heavy and light scans into separate workflows.** A daily light pipeline and a weekly deep one give quick feedback without loading your workers every day.
* **Narrow inputs for web scanners.** Set `input: web` on web scanners so they scan every live web service on its real port instead of guessing a URL from the hostname.
* **Archive instead of deleting.** Archiving stops all scanning but keeps the history for audits; reopen any time.
* **Watch "Not seen again".** It is the quickest way to spot findings that were fixed — or assets that stopped answering.

***

## Related pages

> [card] [Workflows](https://docs.oasm.io/workflows.md)
>
> The workflow file, data kinds and how a run executes.

> [card] [Assets](https://docs.oasm.io/asset.md)
>
> The inventory that project scopes select from.

> [card] [Targets](https://docs.oasm.io/target.md)
>
> Where discovery starts.

> [card] [Job Registry](https://docs.oasm.io/jobs.md)
>
> Every job a project run starts, across the workspace.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.