Metadata-Version: 2.4
Name: g6-alert-core
Version: 1.0.2
Summary: Shared domain layer for the Guardsix Alert SDKs (Standalone + Fleet)
Author: Guardsix Security Team
License-Expression: Apache-2.0
Keywords: guardsix,logpoint,siem,alert,detection,security,sdk
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: pyyaml<7,>=6.0
Requires-Dist: tabulate<1,>=0.9.0
Requires-Dist: werkzeug<4,>=3.1.9
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: ruff==0.15.20; extra == "dev"
Requires-Dist: mypy>=1.9.0; extra == "dev"
Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
Requires-Dist: types-tabulate>=0.9.0; extra == "dev"
Dynamic: license-file

# g6-alert-core

Shared domain layer for the Guardsix Alert SDK (`g6-alert`).

This package provides the pure, transport-agnostic code shared between the
Standalone and Fleet backends:

| Module | Contents |
|--------|----------|
| `transport` | `Target` (frozen dataclass identifying one destination), `Transport` (ABC every backend implements) |
| `auth` | `Auth` (ABC every backend's credential handling implements) |
| `client` | `AlertClient` facade, `TargetResult`, `any_failed`, `all_ok` — the mode-agnostic API `g6-alert` and library callers use |
| `exceptions` | Unified exception hierarchy (`AlertSDKError` base; `FleetAlertSDKError` alias; unified `APIError`) |
| `security` | `validate_yaml_path`, `load_yaml_rule` (no-follow open + `secure_filename`), `open_text_no_follow`, `path_is_within`, `has_traversal` |
| `discovery` | `load_discovery_json`, `find_pool`, `get_nodes_from_pool`, `get_pool_summary` — Fleet's `discovery.json` model |
| `rules` | `validate_yaml_rule`, `normalize_status`, `normalize_repo_field`, `extract_mitre_entries`, `minimum_guardsix_version_violation`, `build_rule_metadata` |
| `packs` | `load_pack_manifest`, `resolve_repo_list_strict` and related repo-resolution helpers |
| `mitre` | Standalone's MITRE ATT&CK CSV map — `~/.g6/mitre_map.csv` if present, else the CSV bundled with this package; Fleet resolves attack tags via its own live API instead |
| `timerange` | `parse_timerange`, `format_timerange` — converts rule YAML's `detection.timerange` (e.g. `"2 hr"`) to/from the Alert API's `timerange_day`/`timerange_hour`/`timerange_minute` fields, of which only one may be non-zero |
| `version` | `parse_version`, `meets_minimum_version` — backs the `minimum_guardsix_version` rule-YAML gate (Fleet only) |
| `formatting` | `format_date`, `truncate_text`, `format_alert_summary`, `tabulate_table`, `print_table` |
| `jinja` | `jinja_from_field_mapping` (parameterised; reproduces both SDK variants byte-for-byte) |

No HTTP or CLI concerns live here — depends only on `pyyaml`, `tabulate`, and
`werkzeug`. `transport`/`auth` define the seam the two backends implement, but
neither module makes network calls itself.

---

## Installation

Installed automatically as a dependency when you install `g6-alert`:

```bash
pip install g6-alert
```

To install this package alone from PyPI:

```bash
pip install g6-alert-core
```

### From source (development)

To install both packages editable from this monorepo:

```bash
pip install -e ./g6_alert_core -e ./g6-alert
```

To install and test this package in isolation:

```bash
pip install -e ".[dev]"
pytest -q
```

See the [`g6-alert` documentation](https://pypi.org/project/g6-alert/) for full SDK and CLI documentation.

---

## Contributing

External contributions are closed for now. This package is distributed through PyPI
(`pip install g6-alert-core`), and is installed automatically with `g6-alert`.

---

## License

Copyright 2026 Guardsix A/S. Licensed under the Apache License, Version 2.0.
See the LICENSE and NOTICE files for the full terms.


# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

This monorepo publishes two packages that version together:

- **g6-alert** — CLI (`g6-alert`) and `AlertClient` facade
- **g6-alert-core** — shared, HTTP-free domain layer

## [1.0.2] - 2026-10-28

### Fixed

- Rule files, pack manifests and backups now load on Windows (g6-alert and
  g6-alert-core). Fleet `create`, `update` and `restore`, and `install-pack`
  and `pack-diff` on both backends, failed there with
  `AttributeError: module 'os' has no attribute 'O_NOFOLLOW'`.
- No more false "readable by other users" warning on Windows (g6-alert).
  Windows has no POSIX mode bits, and the user profile's access control lists
  protect files under `%USERPROFILE%`.
- Fleet config and `auth.json` files are now read as UTF-8 on every platform
  (g6-alert). They were already written as UTF-8.
- Piped or redirected output no longer crashes on Windows (g6-alert). The CLI
  now writes it as UTF-8. When PowerShell pipes the output into another
  command, the CLI's symbols look garbled unless `[Console]::OutputEncoding` is
  UTF-8. A file redirect keeps them intact in PowerShell 7.4 and later. Windows
  PowerShell 5.1 garbles them in a redirected file too.
- A `mitre_map.csv` that starts with a byte-order mark now loads
  (g6-alert-core). Excel's "CSV UTF-8" format adds one.
- On Windows, saving a config, credential, discovery or backup file now
  retries for under a second if another process has the file open, for
  example antivirus or another g6-alert run (g6-alert).
- If a refreshed Fleet token can't be saved, the CLI now prints a warning
  without `-v` (g6-alert). Fleet has already invalidated the old secret, so
  the next command may fail to authenticate.
- A save that fails while setting the temp file's permissions no longer
  leaves the temp file behind on Windows (g6-alert).
- A leading `~` now expands to the home directory in these file paths
  (g6-alert and g6-alert-core): `--config` and `G6_ALERT_CONFIG`,
  `--discovery-file` and `discover -o`, `--backup-file`, `G6_MITRE_MAP_FILE`,
  the rule file given to `create` and `update`, and the `auth_file`,
  `discovery_file` and `mitre_map_file` profile values.
  This matters wherever the shell doesn't expand `~`, such as config files,
  quoted values and Windows shells.
- `restore --backup-file` now prints a short error instead of a Python
  traceback when the file is missing, is a directory or a symlink, or isn't
  valid YAML (g6-alert).
- YAML errors in rule files, pack manifests and backups now give the file's
  path in their location lines, instead of a number (g6-alert-core).

## [1.0.1] - 2026-10-27

### Security

- Raised the minimum `PyJWT` version to 2.15.0 (g6-alert). This clears
  CVE-2026-102265, -102266, -102267, -102268, -102269, -102270, -102271,
  -102272, -102273, -102274, -102275, CVE-2026-101917, -101918 and
  CVE-2026-103001. The SDK only signs tokens with `jwt.encode` and never
  decodes or verifies them, so none of these are reachable from SDK code.
- Raised the minimum `urllib3` version to 2.8.0 (g6-alert). This clears
  CVE-2026-97687, -97688 and -97689. A malicious server could use two of
  them to exhaust memory or hang the client.
- Raised the minimum `werkzeug` version to 3.1.9 (g6-alert and
  g6-alert-core). This clears CVE-2026-102598. The flaw is in `safe_join` on
  Windows, which the SDK does not use.
- Raised the minimum `certifi` version to 2026.10.19 (g6-alert). This clears
  GHSA-6q48-6c7w-9gw2, which has no CVE. Older CA bundles trust the
  emSign ECC Root CA - G3 root, and keys for several of its intermediate CAs
  were compromised. An attacker with one of those keys and a position on the
  network could impersonate a Guardsix server. `certifi` is now a direct
  dependency, because `requests` alone still allows the old versions.
- Upgrade with `pip install -U g6-alert`. On 1.0.0,
  `pip install -U PyJWT urllib3 werkzeug certifi` picks up the same fixes.

## [1.0.0] - 2026-09-03

Initial public release.

- `AlertClient` facade and `g6-alert` CLI working against either a
  **Standalone** Guardsix instance or a **Fleet** console, selected by a typed
  profile.
- Profile-based configuration (`~/.g6/config.yaml`): create, list, show, switch,
  and delete profiles.
- Alert rule lifecycle: create (from YAML), update, list, show, activate, and
  deactivate, for both Standalone and Fleet backends.
- Fleet pool/node discovery (`discovery.json`) and detection-pack installation
  (`install-pack`).
- MITRE ATT&CK attack-tag resolution for Standalone rules via a bundled/local
  technique map.
- Authentication support for Standalone (local self-signed JWT) and Fleet
  (remote Bearer token with refresh), with an `auth.json` credential file
  format shared across backends.
- TLS certificate verification enabled by default; override per run with
  `--tls-verify`/`--no-tls-verify`, per profile with `verify_ssl:`, or via
  `G6_VERIFY_SSL`/`G6_FLEET_VERIFY_SSL` for self-signed hosts.
- Path-security YAML loading, rule/pack-manifest validation, and consistent
  table/JSON output formatting shared via `g6_alert_core`.
- Apache-2.0 licensing.
