View logs
Read firewall logs in the dashboard and stream them live from the terminal with the bsfw CLI.
A rule match with logging enabled produces a log entry: who requested which package, through which firewall, which rule fired, and whether the request was blocked. Logs are the place to answer "why did this install fail" and "what would this rule have blocked". They are not a record of every request; see What is logged when below.
The log holds one other kind of entry: an upstream registry the firewall could not get an answer from. Nothing was blocked in those entries, and the request often succeeded through another upstream. See Check for failing upstreams.
In the dashboard
Open Logs on a firewall. Each entry shows the timestamp, the block decision, the execution phase (versions, download, or upload), the package and version, the matched rule, and the user. Users appear by name where the dashboard can resolve them; service tokens and removed users show the raw ID. From a log entry you can create an exception directly, prefilled with the rule and package.
Status filters the table by outcome:
- Blocked: a rule blocked the request.
- Allowed: a rule or an exception matched and the request went through.
- Error: the firewall could not get an answer from an upstream.
The three are exclusive, and an upstream failure outranks a block: an entry that both blocked and recorded a failed upstream is filtered as Error.
An error row carries an amber Error badge instead of Blocked or Allowed, and its rule column says which upstream failed and what came back.
The rule column shows the rule's description when it has one, and its ID when it does not. A description is worth writing for that reason alone: it is what the log reads back to whoever is investigating.
Filtering by a single firewall or a single user drops that column from the table, since every row would repeat the same value.
Select a row to see the complete entry. The detail includes fields not shown as table columns, such as request, interaction, upstream, and, when applicable, the source firewall or exception. For an error row it also lists the endpoint, the exact URL that failed, and the status the upstream returned, or a network error when there was no response.
The newest entries load first. Load more at the bottom of the table fetches the next batch of older entries, so you can page back as far as the retained history goes. New entries arriving while you page do not shift or duplicate the ones already on screen.
From the terminal
The bsfw CLI reads the same log the
dashboard shows. Its table is a compact view built for scanning, so it leaves
out some fields; add -o json or -o ndjson to get complete entries, including
the request, exception, source firewall, and upstream IDs.
One thing to know before the first run: without --all-users, you only see your
own requests. A CI token has no user behind it, so it sees nothing at all unless
you pass --all-users.
export BYTESAFE_ENDPOINT=https://eu-sov-1.bytesafecloud.eu
export BYTESAFE_NAMESPACE="<namespace-id>"
export BYTESAFE_TOKEN=<your token>
bsfw logs --firewall <firewall-id>Filter entries
bsfw logs --all-users --blocked --since 24h
bsfw logs --firewall <firewall-id> --phase download --search lodash--blocked narrows the list to requests the firewall stopped, which is where a reported install failure is usually found. --search matches on user, ecosystem, package, version, and message, so the package name from the error message is a good search term.
--since takes a duration counted back from now (30m, 24h, 168h) or a point in time (2026-08-01, or an RFC 3339 timestamp). There is no day unit, so a week is 168h. See dates and durations.
Stream live
bsfw logs --firewall <firewall-id> --follow--follow keeps the connection open and prints entries as they happen. Useful while testing a new rule: run the install in one terminal and watch the decision in the other. A stream starts from the newest entries and goes forward, so --since and --limit have no effect on it; the other filters do.
Filter by user
bsfw logs --user user-7d2f...
bsfw logs --all-users--user and --all-users are mutually exclusive, and --user takes the raw user ID, not a name or email. Omit both to see your own entries.
Read complete entries
bsfw logs --firewall <firewall-id> --search lodash -o json
bsfw logs --all-users --follow -o ndjson-o json returns the whole response as one document, which suits a saved report. -o ndjson writes one complete entry per line, which is what to use with --follow or when piping into jq or a log collector.
Check for failing upstreams
A firewall fetches packages from its upstream registries, often more than one. When an upstream fails, the firewall answers with what the other upstreams returned, so builds usually keep working. If no upstream could answer, the request fails, and the error names the package with nothing in it about the registry behind it.
Either way the failure itself only shows up here, which makes this the place to find a rate limit, an expired credential, or a registry the firewall cannot reach.
bsfw logs --all-users --kind error --since 24hIn the dashboard, open Logs and set Status to Error. The CLI flag is --kind, not --status; it filters decisions from upstream failures, with no way to ask for blocked entries only.
Each entry names the upstream, the URL that failed, and what came back. The common cases:
- Rate limited (
429): the upstream is throttling the firewall. The other upstreams still answer, but any version held only by this one can go missing until it lets the firewall back in. - Rejected credentials (
401): the stored credential for that upstream is wrong or expired. See Manage upstream credentials. - Server error (
5xx) or no response: the upstream is down, unreachable from the firewall, or its hostname does not resolve.
Only real faults land here. An upstream answering that it has no such package is a normal part of resolution, so this view stays quiet until something is actually wrong. The logs reference lists exactly what is recorded.
Correlate CI runs
Log entries record the interaction ID when the token carries one (<token>::<id>, see Access Tokens). Set it to the pipeline run ID in CI and every package request from that run shares the ID.
What is logged when
- A rule with
log: truewrites an entry on every match, blocked or not. A log-only rule (block: false, log: true) is the standard way to trial a policy before enforcing it. - An exception with
log: truewrites an entry when it lets a request through. The complete entry identifies the exception. - A rule with
log: falsewrites nothing, even when it blocks the request. If an install fails with no entry to show for it, this is the first thing to check. - A failed upstream call writes its own entry, even when no rule matched and even when the request succeeded. Nothing was blocked in those entries. See Check for failing upstreams.
- Other than those upstream failures, a request that matches no rule is not logged at all. An empty log means no rule had anything to say, not that no packages were installed.
To see traffic that no policy rule covers, add a rule matching all packages with { "block": false, "log": true }. That is also the quickest way to confirm a client really is going through the firewall.
See what was actually downloaded
The firewall log answers "which rule decided this", not "what did we download". A successful install that broke no rule leaves nothing behind, by design: the log exists so a developer can find out why something was blocked.
Two ways to get the download record instead:
-
Observations are the ready-made answer. Each row is a package version the firewall has served, with when and how often, built from real traffic rather than from what manifests declare. Nothing to configure.
bsfw observations --period 30d --firewall <firewall-id> -
A match-all log-only rule turns the firewall log itself into a full request trail, at the cost of an entry per request. Use it when you want the log's fields, such as the identity and interaction ID on each request, rather than an inventory.
Neither is the audit log, which records control-plane actions: who changed configuration, policy, tokens, and teams.
Related
- How-to: Investigate a blocked install
- Reference: CLI
Share configuration across firewalls
Let firewalls inherit rules, exceptions, and upstreams from a baseline firewall, so one policy change applies across the organization.
All concepts
The mental models behind the Bytesafe Dependency Firewall, prevention, rules, upstreams, exceptions, access, observability, and deployment.