Skip to content
Open
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
2 changes: 2 additions & 0 deletions compiler-cli/src/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,12 +907,14 @@ impl ProvidedPackage {
requirements,
retirement_status: None,
outer_checksum: vec![],
security_advisories: vec![],
meta: (),
};
hexpm::Package {
name: name.as_str().into(),
repository: "local".into(),
releases: vec![release],
advisories: vec![],
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler-cli/src/dependencies/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,10 +643,12 @@ fn provided_local_to_hex() {
let hex_package = hexpm::Package {
name: "package".into(),
repository: "local".into(),
advisories: vec![],
releases: vec![hexpm::Release {
version: Version::new(1, 0, 0),
retirement_status: None,
outer_checksum: vec![],
security_advisories: vec![],
meta: (),
requirements: [
(
Expand Down Expand Up @@ -703,11 +705,13 @@ fn provided_git_to_hex() {
let hex_package = hexpm::Package {
name: "package".into(),
repository: "local".into(),
advisories: vec![],
releases: vec![hexpm::Release {
version: Version::new(1, 0, 0),
retirement_status: None,
outer_checksum: vec![],
meta: (),
security_advisories: vec![],
requirements: [
(
"req_1".into(),
Expand Down
4 changes: 4 additions & 0 deletions compiler-core/src/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ where
let root = hexpm::Package {
name: root_name.as_str().into(),
repository: "local".into(),
advisories: vec![],
releases: vec![Release {
version: root_version.clone(),
outer_checksum: vec![],
retirement_status: None,
requirements,
security_advisories: vec![],
meta: (),
}],
};
Expand Down Expand Up @@ -1172,6 +1174,7 @@ but it is locked to 0.2.0, which is incompatible."
requirements: all_requirements,
retirement_status: None,
outer_checksum: vec![1, 2, 3],
security_advisories: vec![],
meta: (),
}
}
Expand All @@ -1184,6 +1187,7 @@ but it is locked to 0.2.0, which is incompatible."
Rc::new(hexpm::Package {
name: package.into(),
repository: "hexpm".into(),
advisories: vec![],
releases,
}),
);
Expand Down
4 changes: 3 additions & 1 deletion hexpm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
fn main() {
// prost_build::compile_protos(
// &[
// "proto/signed.proto",
// "proto/names.proto",
// "proto/package.proto",
// "proto/policy.proto",
// "proto/signed.proto",
// "proto/versions.proto",
// ],
// &["proto/"],
Expand Down
9 changes: 9 additions & 0 deletions hexpm/proto/names.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ message Package {

// If set, the name of the package repository (NEVER USED, DEPRECATED)
// string repository = 2;

optional Timestamp updated_at = 3;
}

// Based on google.protobuf.Timestamp
// https://github.com/protocolbuffers/protobuf/blob/v3.15.8/src/google/protobuf/timestamp.proto#L136:L147
message Timestamp {
required int64 seconds = 1;
required int32 nanos = 2;
}
40 changes: 40 additions & 0 deletions hexpm/proto/package.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ message Package {
required string name = 2;
// Name of repository
required string repository = 3;
// All security advisories affecting any release of the package
repeated SecurityAdvisory advisories = 4;
}

message Release {
Expand All @@ -28,6 +30,11 @@ message Release {
// sha256 checksum of outer package tarball
// required when encoding but optional when decoding
optional bytes outer_checksum = 5;
// Indexes into Package.advisories for advisories affecting this release
repeated uint32 advisory_indexes = 6;
// Release published timestamp. Optional for backwards compatibility —
// clients treat absence as "no information".
optional Timestamp published_at = 7;
}

message RetirementStatus {
Expand All @@ -43,6 +50,32 @@ enum RetirementReason {
RETIRED_RENAMED = 4;
}

message SecurityAdvisory {
// Advisory identifier (e.g. GHSA-xxxx-xxxx-xxxx or CVE-xxxx-xxxxx)
required string id = 1;
// Short description of the advisory
required string summary = 2;
// OSV web URL for the advisory
required string html_url = 3;
// Severity of the advisory
optional AdvisorySeverity severity = 4;
// CVSS score (0.0–10.0)
optional float cvss_score = 5;
// OSV API URL for the advisory
required string api_url = 6;
// Other identifiers for the same vulnerability (e.g. a CVE id when the
// primary id is a GHSA id, or vice versa).
repeated string aliases = 7;
}

enum AdvisorySeverity {
SEVERITY_NONE = 0;
SEVERITY_LOW = 1;
SEVERITY_MEDIUM = 2;
SEVERITY_HIGH = 3;
SEVERITY_CRITICAL = 4;
}

message Dependency {
// Package name of dependency
required string package = 1;
Expand All @@ -56,3 +89,10 @@ message Dependency {
// If set, the repository where the dependency is located
optional string repository = 5;
}

// Based on google.protobuf.Timestamp
// https://github.com/protocolbuffers/protobuf/blob/v3.15.8/src/google/protobuf/timestamp.proto#L136:L147
message Timestamp {
required int64 seconds = 1;
required int32 nanos = 2;
}
92 changes: 92 additions & 0 deletions hexpm/proto/policy.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2014 The Hex Team

syntax = "proto2";

package policy;

import "package.proto";

message Policy {
// Name of repository
required string repository = 1;

// Policy name within the repository
// (matches ^[a-z0-9][a-z0-9_\-\.]*[a-z0-9]$, length 3..64)
required string name = 2;

// Optional, free-form description (admin-set, surfaced in CLI/UI)
optional string description = 3;

// Whether the policy is publicly readable or restricted to org members.
// Read at the edge to decide whether to enforce auth on the fetch.
// Adding new Visibility values is a breaking change — old clients will
// treat unknown values as PRIVATE per the fail-closed rule.
required Visibility visibility = 4;

// One entry per repository the policy constrains (in practice "hexpm" and
// the org's own repository). A candidate release is matched to the entry
// whose repository equals the release's repository; a release from a
// repository with no matching entry is unconstrained by this policy.
repeated RepositoryPolicy repositories = 5;
}

enum Visibility {
// PRIVATE is the safe default; unknown enum values must be treated as PRIVATE.
VISIBILITY_PRIVATE = 0;
VISIBILITY_PUBLIC = 1;
}

message RepositoryPolicy {
// Repository this entry applies to (e.g. "hexpm" or the org's repository).
required string repository = 1;

// Baseline limits applied to every release in this repository. Unset = no
// restriction. Restrictions never apply to releases permitted by an ALLOW
// override (those bypass all limits).
optional Restriction restriction = 2;

// Per-package final say, evaluated against each release in this repository.
// An ALLOW override permits the release immediately and bypasses
// `restriction`; a DENY override blocks it. When multiple overrides match a
// release, the one with the most specific requirement wins.
repeated Override overrides = 3;
}

message Restriction {
// Advisory limit. If set, deny any release whose maximum advisory severity
// is at least this value. Unset = no advisory limit.
optional package.AdvisorySeverity advisory_min_severity = 1;

// Retirement limit. If non-empty, deny any release retired with a reason in
// this set. Empty = no retirement limit.
repeated package.RetirementReason retirement_reasons = 2 [packed = true];

// Minimum release age. Same duration grammar as the Hex cooldown config
// ("7d", "2w", "1mo", "0"). Unset or "0" = no minimum age. If multiple
// active policies declare cooldowns, the effective cooldown is the strictest.
optional string cooldown = 3;
}

message PackageRef {
// Package name.
required string package = 1;

// Optional version requirement (e.g. "~> 1.7"). Unset = the whole package.
optional string requirement = 2;
}

message Override {
// Whether this override permits or blocks the matching release.
required OverrideAction action = 1;

// The package (and optional requirement) the override applies to.
required PackageRef ref = 2;
}

enum OverrideAction {
// Permit the release and bypass `restriction`.
OVERRIDE_ACTION_ALLOW = 0;
// Block the release.
OVERRIDE_ACTION_DENY = 1;
}
8 changes: 5 additions & 3 deletions hexpm/proto/versions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ package versions;

message Versions {
// All packages in the repository
repeated VersionsPackage packages = 1;
repeated Package packages = 1;
// Name of repository
required string repository = 2;
}

message VersionsPackage {
message Package {
// Package name
required string name = 1;
// All released versions of the package
repeated string versions = 2;
// Zero-based indexes of retired versions in the versions field, see package.proto
repeated int32 retired = 3 [packed=true];
repeated int32 retired = 3 [packed = true];
// If set, the name of the package repository (NEVER USED, DEPRECATED)
// string repository = 4;
// Zero-based indexes of versions with security advisories in the versions field, see package.proto
repeated int32 with_advisories = 5 [packed = true];
}
Loading
Loading