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
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,26 @@ go test -v ./internal/output/... -run TestHumanFormatter
### Environment Variables

**Authentication:**

- `ARMIS_CLIENT_ID` - Client ID for JWT authentication (recommended)
- `ARMIS_CLIENT_SECRET` - Client secret for JWT authentication
- `ARMIS_API_TOKEN` - API token for Basic authentication (fallback)
- `ARMIS_TENANT_ID` - Tenant identifier (required only with Basic auth; JWT extracts it from token)

**API Configuration:**

- `ARMIS_API_URL` - Override base URL for Armis API (advanced; defaults based on --dev flag)
- `ARMIS_REGION` - Override Armis cloud region (equivalent to `--region`; used for region-aware authentication)
- `ARMIS_LOCAL_S3_ENDPOINT` - Comma-separated list of host:port entries for mock S3 services in local development (e.g., `awsmock-dev:4566,localstack:4566`). **SECURITY:** Only enabled when `ARMIS_API_URL` is localhost or RFC 1918 private IP. Allows HTTP access to configured hosts for SBOM/VEX downloads. Blocked for all remote/cloud endpoints.

**Output Configuration:**

- `ARMIS_FORMAT` - Default output format
- `ARMIS_PAGE_LIMIT` - Results pagination size
- `ARMIS_THEME` - Terminal background theme: auto, dark, light (default: auto)

**Other:**

- `ARMIS_NO_UPDATE_CHECK` - Disable automatic version update checking

When both JWT and Basic credentials are configured, JWT takes precedence.
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,31 @@ armis-cli scan image nginx:latest --pull=always
armis-cli scan image nginx:latest --pull=never
```

### Check Scan Status

Fetch the current status of a scan initiated with `scan repo`, `scan image`, or `scan sbom`.

```bash
armis-cli scan status [scan_id]
```

When no `scan_id` is supplied, the command reuses the most recent scan initiated on this machine for the current tenant. Every successful scan records its `scan_id` locally in `~/.armis/scan-history.json` (created 0600), so re-checking a scan does not require copying an ID.

**Examples:**

```bash
# Look up a specific scan
armis-cli scan status a1b2c3d4-...

# Re-check the most recently initiated scan on this machine
armis-cli scan status

# Machine-readable output
armis-cli scan status --format json
```

`scan status` reports every state the API can return: `PENDING_UPLOAD`, `UPLOADED`, `INITIATED`, `IN_PROGRESS`, `COMPLETED`, `FAILED`, `STOPPED`.

### Other Commands

```bash
Expand Down Expand Up @@ -1019,7 +1044,6 @@ Before users can sign in with SSO, an IT admin registers the tenant's identity p
| `ARMIS_THEME` | Terminal background theme: auto, dark, light (default: auto) |
| `ARMIS_NO_UPDATE_CHECK` | Disable automatic update checking |


---

## Security Considerations
Expand Down
8 changes: 3 additions & 5 deletions docs/SSO-SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ armis-cli auth setup \
--client-secret "$ARMIS_CLIENT_SECRET"
```

The command auto-detects your region and tenant from your credentials,
The command auto-detects your region and tenant from your credentials,
then walks you through the values from Step 1: IdP type,
issuer, client ID, client secret, and group claim.

Expand Down Expand Up @@ -112,8 +112,8 @@ The first Armis command a developer runs then opens the browser for sign-in
## Verifying and updating

Re-running `armis-cli auth setup` fetches the existing configuration, shows the
current values (secrets excluded) and lets you **edit it in place** — for example
to rotate the secret or change a group mapping.
current values (secrets excluded) and lets you **edit it in place** — for example
to rotate the secret or change a group mapping.
This both verifies the registration and is how you update it later.

For an end-to-end check, have a developer run `armis-cli auth login` and confirm
Expand All @@ -126,5 +126,3 @@ sign-in completes with the expected role.
| Setup rejected as unauthorized | Wrong/expired API credentials. Re-copy them from `<base_VIPR_URL>/settings/api-access`. |
| Developer sign-in fails with "access denied" | The user isn't in any mapped group. Add their IdP group under `admin` or `developer` (Step 2). |
| Redirect / callback error during sign-in | The redirect URI in your IdP doesn't match your region host (Step 1). |


8 changes: 8 additions & 0 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ func (c *Client) IsDebug() bool {
return c.debug
}

// BaseURL returns the API base URL the client was configured with. Callers
// use it as the scoping key for per-environment on-disk state (e.g. the
// scan-history store) so a token issued for one Armis environment can never
// look up scans from another.
func (c *Client) BaseURL() string {
return c.baseURL
}

// setAuthHeader sets the Authorization header on a request, but only if the
// request URL uses HTTPS (or localhost for testing). This prevents credential
// exposure over insecure channels.
Expand Down
13 changes: 8 additions & 5 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ var rootCmd = &cobra.Command{
armis-cli scan image nginx:latest

# Scan with specific failure threshold
armis-cli scan repo . --fail-on HIGH,CRITICAL`,
armis-cli scan repo . --fail-on HIGH,CRITICAL

# Re-check the last scan's status (or look up a specific scan_id)
armis-cli scan status`,
Version: version,
SilenceUsage: true,
SilenceErrors: true,
Expand Down Expand Up @@ -280,10 +283,10 @@ func fixedCompletions(values []string, descriptions map[string]string) cobra.Com
// sites to keep them from drifting apart.
func formatCompletions() cobra.CompletionFunc {
return fixedCompletions(validFormats, map[string]string{
"human": "Human-readable terminal output",
"json": "Machine-readable JSON",
"sarif": "SARIF for code-scanning tools",
"junit": "JUnit XML for CI test reports",
statusFormatHuman: "Human-readable terminal output",
statusFormatJSON: "Machine-readable JSON",
"sarif": "SARIF for code-scanning tools",
"junit": "JUnit XML for CI test reports",
})
}

Expand Down
16 changes: 14 additions & 2 deletions internal/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@ var (
outputFile string
)

// Shared constants for the --format value across scan subcommands. `scan
// status` reuses these to keep goconst happy across cmd/ and to make the
// human/json spelling change in exactly one place if it ever needs to.
const (
statusFormatHuman = "human"
statusFormatJSON = "json"
)

// validFormats contains the valid output format strings.
var validFormats = []string{"human", "json", "sarif", "junit"}
var validFormats = []string{statusFormatHuman, statusFormatJSON, "sarif", "junit"}

// validGroupBy contains the valid group-by options.
var validGroupBy = []string{"none", "cwe", "severity", "file"}
Expand All @@ -48,7 +56,11 @@ var scanCmd = &cobra.Command{
armis-cli scan image myapp:latest

# Scan with SBOM generation
armis-cli scan repo . --sbom --sbom-output sbom.json`,
armis-cli scan repo . --sbom --sbom-output sbom.json

# Check the status of the last scan (or a specific scan_id)
armis-cli scan status
armis-cli scan status a1b2c3d4-...`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Call root command's PersistentPreRunE to initialize colors and update checking
// We reference rootCmd directly since cmd.Parent() would return scanCmd for subcommands
Expand Down
Loading
Loading