Skip to content

v0.2.4

Latest

Choose a tag to compare

@github-actions github-actions released this 16 Jun 09:11
ac79999

Highlights

apic 0.2.4 is a validation and security release. apic validate can now enforce a project-wide contract baseline from .apic/template.json, path handling is hardened against symlink escapes, and command output no longer leaks your home directory path. It also includes an internal visibility cleanup with no change in behavior.

Added

Template conformance in apic validate

apic validate now checks every contract against .apic/template.json, in addition to the existing JSON-schema validation. The template is treated as a partial: only the sections it actually declares are enforced, and a contract may always carry more than the template requires.

What is checked, for each section the template declares:

  • Headers, every header name in the template must be present on the contract. Names are compared case-insensitively, so content-type satisfies Content-Type.
  • url.protocol and url.host, must match the template's values exactly, so every contract shares one base URL.
  • url.path, url.query, url.variable, each declared path segment and each query or variable name must be present on the contract.
  • request and responses schemas, every field name the template declares must be present, descending into nested properties and reported with a dotted path such as data.id. Responses are matched by status code.

Violations are reported per contract on the FAIL line, for example:

FAIL contracts/login.json: missing header `Authorization`; url.host must be `api.example.com` (found `staging.internal`); response 200 schema missing field `data.id`

.apic/ is now excluded from the validate scan, so a partial template is never itself validated as a contract. The template still has its own dedicated check via apic validate --template.

Note: the default seeded .apic/template.json is a full example contract with placeholder values. Trim it down to your real baseline before relying on conformance, otherwise contracts are checked against those placeholders.

Security

Symlink-aware path confinement

Path confinement previously checked only the lexical shape of a path, so a symlinked component pointing outside the working directory could redirect a write. For example, with contracts/link symlinked to a directory outside the project, apic create -f link/escaped.json would create the file outside the configured root.

confine_to_dir now rejects any path whose component is a symlink, closing the bypass for apic create, apic convert --destination, and apic remove, all of which route through it. New files whose final component does not exist yet, the normal create case, are unaffected. This resolves the report in #22.

Home directory hidden in output

Absolute paths printed by apic could disclose your username and full filesystem layout, for example Created /home/alice/work/contracts/auth/login.json. The home directory prefix is now collapsed to ~ across command output, including the Created line and error messages. Paths outside your home directory, such as /tmp, are left intact since they carry no user-identifying information.

Changed

Internal visibility cleanup

Item visibility across the crate was tightened: pub was narrowed to pub(crate), and helpers used within a single module were made private. The unreachable_pub lint is now enabled as a guardrail so over-broad visibility cannot creep back in. This is an internal change with no effect on behavior or the command-line interface.

Documentation

  • README prose now uses commas in place of em-dashes.

Install

From crates.io:

cargo install apic-cli

Or download a prebuilt binary for your platform from the assets below, verify it against the matching .sha256, and place apic on your PATH.

Full changelog

See CHANGELOG.md. Compare against the previous release: v0.2.3...v0.2.4