# Creating a Seal Project

A **Seal Project** is the entity inside the Seal Platform that represents one of your codebases or build pipelines. Each Seal Project has its own [package discovery mode](/new-documentation/new-docs/package-discovery-mode.md) (source code, CLI, artifact server, or imported manifest), its own deployment method, and its own scan history. Most of Seal's day-to-day surfaces (Sealing Rules, the Protection page, reports) are scoped per Seal Project.

Users with the Admin, Sealer, or Collaborator [role](/new-documentation/new-docs/users-and-sso/user-roles.md) can create, edit, and archive Seal Projects. Watchers cannot.

## How Seal Projects get created

You can create a Seal Project in four ways:

* **Through the onboarding wizard** when a tenant is first set up. The wizard creates one Seal Project per imported GitHub repository.
* **From the Projects page** using the **Import projects** dropdown, with five sources: GitHub, GitLab, Azure DevOps, Snyk, or file upload (for one-shot manifest or SBOM imports).
* **From the Projects page** using the **New project** button, for Seal Projects that do not correspond to an imported source-control repository.
* **Implicitly through the Seal CLI.** When the CLI runs with a `SEAL_PROJECT` value that does not match any existing Seal Project in your tenant, the Seal Platform creates a new project automatically and uses the supplied value as the project's Project ID. This is useful for organizations with thousands of pipelines, where pre-creating projects through the UI is impractical.

## Project ID and project name

Every Seal Project has two distinct identifiers:

* **Project ID:** machine-readable, immutable after creation, restricted to letters, numbers, dots, hyphens, and underscores (no spaces or other punctuation), up to 255 characters. The Seal CLI and the Seal Public API both work against the Project ID. The `SEAL_PROJECT` environment variable holds the Project ID.
* **Name:** human-readable, mutable, allows spaces and a wider character set. The name is used in the Seal UI: the Projects table, page titles, search.

Both fields are unique within a tenant. The two are independent: renaming a project in the UI does not affect its Project ID, and the Project ID cannot be changed once the project exists.

### How the two identifiers are populated

* **Imported from source control.** Seal generates the Project ID automatically from the connected repository (it is opaque, not human-friendly). The display name is derived from the owner, repository name, and (when one repository contains multiple manifests) the path to the manifest file.
* **Created manually with the New project button.** You provide a name. The Project ID is assigned by the platform.
* **Created implicitly through the CLI.** The Project ID is the exact value of `SEAL_PROJECT`. The platform fills in a starter name based on it, which you can change later.

### Picking a Project ID

The only path that lets you pick a Project ID is implicit creation through the Seal CLI: whatever value you put in `SEAL_PROJECT` becomes the Project ID. SCM imports and the **New project** button both leave the Project ID to the platform.

Because the Project ID is what your CI/CD pipelines and any automation reference forever, the value you choose for `SEAL_PROJECT` deserves the same care you would put into naming a build artifact or a container image. What works in practice:

* **Mirror your existing naming.** If your CI/CD pipelines, container registries, or other tooling already name things by `{team}/{service}` or `{repo}-{component}`, use the same shape for the Project ID. Cross-tool searches stay clean.
* **Stay consistent on case and separators.** Pick lowercase or mixed-case, dots or hyphens or underscores, and apply uniformly. Customers who slip into `my-app`, `MyApp`, and `my_app` for the same component end up with three Seal Projects instead of one.
* **Disambiguate when one repository ships multiple components.** If a single source repository builds two different containers or components, give them distinct Project IDs (typically by appending the path or component label).

## Mapping projects to your environment

A Seal Project's source-code or CLI mode operates against a single manifest file (`requirements.txt`, `package-lock.json`, `pom.xml`, and so on). That has two consequences for how you carve up your repositories.

* **One Seal Project per programming language.** A repository that contains a Python service plus a Java tool needs two Seal Projects, one per manifest. There is no way to scan multiple manifests under a single project.
* **One Seal Project per deployable unit.** Beyond the per-language constraint, give each separately-built artifact its own Seal Project.

Some scenarios:

* **One repository, one application, one manifest.** One Seal Project. Name it after the repo.
* **One repository, multiple manifests** (monorepo, multi-language, or multi-component). One Seal Project per manifest, named with the path or component as a suffix.
* **CLI-only deployment with no source-control connection.** One Seal Project per CI/CD pipeline that runs the CLI. Either pre-create the project from the **New project** button or let the CLI create it implicitly on first run.

### Anti-patterns

* **Reusing one Project ID across unrelated pipelines.** The platform attributes each scan to the project the ID matches, and the latest scan overwrites the previous one. Two pipelines reporting under the same `SEAL_PROJECT` value will see each other's results clobber theirs.
* **Frequently switching a project's modes.** See [Mode changes](#mode-changes) below.

## The Default project

Every tenant has a built-in Seal Project named **Default**. It collects package-detection results that cannot be attributed to a specific project, including unattributed SBOM uploads and similar one-shot activity.

The Default project is special. Treat it as a catch-all view rather than a real Seal Project:

* Do not connect it to source control.
* Do not point your Seal CLI at it.

If you find detection results in the Default project that belong somewhere else, the right move is usually to create the appropriate Seal Project and re-run the relevant scan or import there.

## Editing a project

In the Projects table, click the edit icon on a project row. The **Edit project** modal opens with these fields:

* **Name**.
* **Description** (optional).
* **Source control path URL** is the URL to the project's manifest file in your source control system (for example, the GitHub URL of `requirements.txt` or `package-lock.json`). The UI validates that the URL points to a recognized manifest file; non-manifest URLs are rejected.

Changes save with the **Save** button.

### Connecting an existing project to source control

You can take a project that started as CLI-only or artifact-server-only and connect it to your source control system later. From the project's Edit modal, set the **Source control path URL** to the URL of the project's manifest file. Seal needs read access to the repository, which is provided by the connected SCM integration.

### Archiving a project

Click the archive icon on a project row. The project moves from the **Projects** tab to the **Projects archive** tab and stops being scanned. Archived projects are not deleted; you can restore them from the archive.

### Deleting a project

Click the delete icon. The project is permanently removed, along with its scan history. Deleting is irreversible; archive first if you might want the project back.

## Mode changes

A project's CLI fix mode and package discovery mode can change after creation, but they behave differently.

### CLI fix mode

The CLI fix mode is freely changeable in any direction. It updates whenever the Seal CLI runs against the project: the platform records the mode the CLI ran in (local, remote, or all) and shows that as the project's current mode. To switch modes, change the CLI's invocation in your pipeline; the next run updates the recorded mode.

### Package discovery mode

The package discovery mode is one-way. Behind the scenes, the platform picks a single "best" signal source per project and ignores everything else. The order, from least to most reliable:

1. **Imported manifest** (a one-shot snapshot at upload time).
2. **Artifact server** (signal accumulates as your build pulls sealed packages).
3. **CLI** (the CLI reports each run).
4. **Source code** (Seal's SCM integration reads your manifests directly).

A project moves up this hierarchy automatically when a more reliable source produces signal. Pulling a sealed package from the Seal Artifact Server while a project is in imported-manifest mode promotes it to artifact-server mode. Running the Seal CLI against the project promotes it to CLI mode. Connecting source control promotes it to source-code mode.

The reason this is one-way is that a "downgrade" cannot really happen: if a project is in source-code mode and your build also pulls from the Seal Artifact Server, the artifact-server pulls are ignored. The same applies all the way down: any signal from a less reliable source than the project's current mode is dropped. So if you point an unrelated pipeline's CLI invocation, or a stray artifact-server pull, at a project that already has a more reliable source, those events disappear silently rather than appearing under that project.

To genuinely operate a project in a less reliable mode, archive or delete it and create a new one.

{% hint style="info" %}
**Tip: pick a mode and stick with it.** The platform tolerates mode changes, but reports and Sealing Rules become harder to reason about when a project bounces between modes. Change only when you have a reason to.
{% endhint %}

## Related

* [The onboarding wizard](/new-documentation/new-docs/onboarding-wizard.md): the wizard creates your tenant's first Seal Projects.
* [Package discovery mode](/new-documentation/new-docs/package-discovery-mode.md): the four modes a Seal Project can use.
* [Choosing your deployment method](https://github.com/seal-community/gitbook/blob/main/new-docs/setup-apps-os/choosing-deployment-method.md): the deployment method options for Seal Apps.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sealsecurity.io/new-documentation/new-docs/creating-a-seal-project.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
