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
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ The OpenAPI specification is located in the [`trustify-da-api-spec`](https://git
which will provide data that we can send to the _Backend_ using _analysis.js_. See the
[Adding a Provider](#adding-a-provider) section.
* [java_maven.js](src/providers/java_maven.js) is the provider for the _Java_ _Maven_ ecosystem.
* [rust_cargo.js](src/providers/rust_cargo.js) is the provider for the _Rust_ _Cargo_ ecosystem.

#### Types

Expand Down
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ let imageAnalysisWithArch = await client.imageAnalysis(['httpd:2.4.49^^amd64'])
The client automatically detects your project's license with intelligent fallback:
</p>
<ul>
<li><strong>Manifest-first:</strong> For ecosystems with license support (Maven, JavaScript), reads from manifest file (<code>pom.xml</code>, <code>package.json</code>)</li>
<li><strong>Manifest-first:</strong> For ecosystems with license support (Maven, JavaScript, Rust Cargo), reads from manifest file (<code>pom.xml</code>, <code>package.json</code>, <code>Cargo.toml</code>)</li>
<li><strong>LICENSE file fallback:</strong> If no license in manifest, or for ecosystems without license support (Gradle, Go, Python), automatically reads from <code>LICENSE</code>, <code>LICENSE.md</code>, or <code>LICENSE.txt</code></li>
<li><strong>SBOM integration:</strong> Detected licenses are included in generated SBOMs for all ecosystems</li>
<li><strong>SPDX support:</strong> Automatically detects common licenses (Apache-2.0, MIT, GPL, BSD) from LICENSE file content</li>
Expand Down Expand Up @@ -196,14 +196,15 @@ $ trustify-da-javascript-client license /path/to/package.json
<li><a href="https://go.dev/">Golang</a> - <a href="https://go.dev/blog/using-go-modules/">Go Modules</a></li>
<li><a href="https://www.python.org/">Python</a> - <a href="https://pypi.org/project/pip/">pip Installer</a></li>
<li><a href="https://gradle.org/">Gradle (Groovy and Kotlin DSL)</a> - <a href="https://gradle.org/install/">Gradle Installation</a></li>
<li><a href="https://www.rust-lang.org/">Rust</a> - <a href="https://doc.rust-lang.org/cargo/">Cargo</a></li>
</ul>

<h3>License Detection</h3>
<p>
The client automatically detects your project's license with intelligent fallback:
</p>
<ul>
<li><strong>Manifest-first:</strong> For ecosystems with license support (Maven, JavaScript), reads from manifest file (<code>pom.xml</code>, <code>package.json</code>)</li>
<li><strong>Manifest-first:</strong> For ecosystems with license support (Maven, JavaScript, Rust Cargo), reads from manifest file (<code>pom.xml</code>, <code>package.json</code>, <code>Cargo.toml</code>)</li>
<li><strong>LICENSE file fallback:</strong> If no license in manifest, or for ecosystems without license support (Gradle, Go, Python), automatically reads from <code>LICENSE</code>, <code>LICENSE.md</code>, or <code>LICENSE.txt</code></li>
<li><strong>SBOM integration:</strong> Detected licenses are included in generated SBOMs for all ecosystems</li>
<li><strong>SPDX support:</strong> Automatically detects common licenses (Apache-2.0, MIT, GPL, BSD) from LICENSE file content</li>
Expand Down Expand Up @@ -334,7 +335,21 @@ test {
}
```

All of the 5 above examples are valid for marking a package to be ignored
<em>Rust Cargo</em> users can add a comment with <code># trustify-da-ignore</code> (or <code># exhortignore</code>) in <em>Cargo.toml</em> next to the dependency to be ignored. This works for inline declarations, table-based declarations, and workspace-level dependency sections:

```toml
[dependencies]
serde = "1.0" # trustify-da-ignore
tokio = { version = "1.35", features = ["full"] }

[dependencies.regex] # trustify-da-ignore
version = "1.10"

[workspace.dependencies]
log = "0.4" # trustify-da-ignore
```

All of the 6 above examples are valid for marking a package to be ignored
</li>

</ul>
Expand Down Expand Up @@ -366,6 +381,7 @@ let options = {
'TRUSTIFY_DA_PYTHON_PATH' : '/path/to/python',
'TRUSTIFY_DA_PIP_PATH' : '/path/to/pip',
'TRUSTIFY_DA_GRADLE_PATH' : '/path/to/gradle',
'TRUSTIFY_DA_CARGO_PATH' : '/path/to/cargo',
// Configure proxy for all requests
'TRUSTIFY_DA_PROXY_URL': 'http://proxy.example.com:8080'
}
Expand Down Expand Up @@ -411,7 +427,7 @@ The proxy URL should be in the format: `http://host:port` or `https://host:port`

<h4>License resolution and dependency license compliance</h4>
<p>
The client can resolve the <strong>project license</strong> from the manifest (e.g. <code>package.json</code> <code>license</code>, <code>pom.xml</code> <code>&lt;licenses&gt;</code>) and from a <code>LICENSE</code> or <code>LICENSE.md</code> file in the project, and report when they differ. For <strong>component analysis</strong>, you can optionally run a license check: the client fetches dependency licenses from the backend (by purl) and reports dependencies whose licenses are incompatible with the project license. See <a href="docs/license-resolution-and-compliance.md">License resolution and compliance</a> for design and behavior. To disable the check on component analysis, set <code>TRUSTIFY_DA_LICENSE_CHECK=false</code> or pass <code>licenseCheck: false</code> in the options.
The client can resolve the <strong>project license</strong> from the manifest (e.g. <code>package.json</code> <code>license</code>, <code>pom.xml</code> <code>&lt;licenses&gt;</code>, <code>Cargo.toml</code> <code>license</code>) and from a <code>LICENSE</code> or <code>LICENSE.md</code> file in the project, and report when they differ. For <strong>component analysis</strong>, you can optionally run a license check: the client fetches dependency licenses from the backend (by purl) and reports dependencies whose licenses are incompatible with the project license. See <a href="docs/license-resolution-and-compliance.md">License resolution and compliance</a> for design and behavior. To disable the check on component analysis, set <code>TRUSTIFY_DA_LICENSE_CHECK=false</code> or pass <code>licenseCheck: false</code> in the options.
</p>

<h4>Customizing Executables</h4>
Expand Down Expand Up @@ -487,6 +503,11 @@ following keys for setting custom paths for the said executables.
<td><em>gradle</em></td>
<td>TRUSTIFY_DA_PREFER_GRADLEW</td>
</tr>
<tr>
<td><a href="https://www.rust-lang.org/">Rust Cargo</a></td>
<td><em>cargo</em></td>
<td>TRUSTIFY_DA_CARGO_PATH</td>
</tr>
</table>

#### Match Manifest Versions Feature
Expand Down
5 changes: 3 additions & 2 deletions docs/license-resolution-and-compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ The client looks for your project’s license with **automatic fallback**:
1. **Primary: Manifest file** — Reads the license field from:
- `package.json`: `license` field
- `pom.xml`: `<licenses><license><name>` element
- `Cargo.toml`: `license` field under `[package]` or `[workspace.package]`
- `build.gradle` / `build.gradle.kts`: No standard license field (falls back to LICENSE file)
- `go.mod`: No standard license field (falls back to LICENSE file)
- `requirements.txt`: No standard license field (falls back to LICENSE file)

2. **Fallback: LICENSE file** — If no license is found in the manifest, searches for `LICENSE`, `LICENSE.md`, or `LICENSE.txt` in the same directory as your manifest

**How the fallback works:**
- **Ecosystems with manifest license support** (Maven, JavaScript): Uses manifest license if present, otherwise falls back to LICENSE file
- **Ecosystems with manifest license support** (Maven, JavaScript, Rust Cargo): Uses manifest license if present, otherwise falls back to LICENSE file
- **Ecosystems without manifest license support** (Gradle, Go, Python): Automatically reads from LICENSE file
- **SPDX detection**: Common licenses (Apache-2.0, MIT, GPL-2.0/3.0, LGPL-2.1/3.0, AGPL-3.0, BSD-2-Clause/3-Clause) are automatically detected from LICENSE file content

Expand Down Expand Up @@ -167,5 +168,5 @@ Project license information is automatically included in generated SBOMs (Cyclon
**LICENSE file fallback in SBOMs:**
- **All ecosystems** now include license information in the SBOM when available
- **Gradle, Go, Python projects**: Even though these ecosystems don’t have manifest license fields, the SBOM will include the license from your LICENSE file
- **Maven, JavaScript projects**: The SBOM uses the manifest license, or falls back to LICENSE file if not specified in manifest
- **Maven, JavaScript, Rust Cargo projects**: The SBOM uses the manifest license, or falls back to LICENSE file if not specified in manifest
- If neither manifest nor LICENSE file contains a license, the SBOM root component will have no `licenses` field
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"https-proxy-agent": "^7.0.6",
"node-fetch": "^3.3.2",
"packageurl-js": "~1.0.2",
"smol-toml": "^1.6.0",
"tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801",
"web-tree-sitter": "^0.26.6",
"yargs": "^18.0.0"
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default { componentAnalysis, stackAnalysis, imageAnalysis, validateToken

/**
* @typedef {{
* TRUSTIFY_DA_CARGO_PATH?: string | undefined,
* TRUSTIFY_DA_DOCKER_PATH?: string | undefined,
* TRUSTIFY_DA_GO_MVS_LOGIC_ENABLED?: string | undefined,
* TRUSTIFY_DA_GO_PATH?: string | undefined,
Expand Down
4 changes: 3 additions & 1 deletion src/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Javascript_npm from './providers/javascript_npm.js';
import Javascript_pnpm from './providers/javascript_pnpm.js';
import Javascript_yarn from './providers/javascript_yarn.js';
import pythonPipProvider from './providers/python_pip.js'
import rustCargoProvider from './providers/rust_cargo.js'

/** @typedef {{ecosystem: string, contentType: string, content: string}} Provided */
/** @typedef {{isSupported: function(string): boolean, validateLockFile: function(string): void, provideComponent: function(string, {}): Provided | Promise<Provided>, provideStack: function(string, {}): Provided | Promise<Provided>, readLicenseFromManifest: function(string): string | null}} Provider */
Expand All @@ -24,7 +25,8 @@ export const availableProviders = [
new Javascript_pnpm(),
new Javascript_yarn(),
golangGomodulesProvider,
pythonPipProvider]
pythonPipProvider,
rustCargoProvider]

/**
* Match a provider by manifest type only (no lock file check). Used for license reading.
Expand Down
Loading
Loading