Guardsix
[!NOTE] This package was previously published as
logpoint_apiand has been renamed toguardsixfollowing the company rebranding.
A stateless implementation of the Guardsix SIEM API Reference. The library is a wrapper around the API reference with the addition of builder patterns for alert rules and notifications. I try to make sure the library stays as true to the API as possible with minor simplifications so it is easier to correlate the lib with the API reference doc.
Installation
def deps do
[
{:guardsix, "~> 1.0.0"}
]
endBasic Usage
Create a universal client that can be used with all functions. This is a simplification over the split in the API design where some endpoints use JWT tokens and others don't.
client = Guardsix.client("https://guardsix.company.com", "admin", "your_secret_key")Search
Search includes all functions from the search API reference and for writing search_param queries please refer to Search Log Data.
alias Guardsix.Core.Search
query = Guardsix.search_params(
"user=*",
"Last 24 hours",
100,
["127.0.0.1:5504"]
)
{:ok, %{"search_id" => search_id}} = Search.get_id(client, query)
{:ok, result} = Search.get_result(client, search_id)Instance Information
alias Guardsix.Core.Search
{:ok, user_prefs} = Search.user_preference(client)
{:ok, repos} = Search.repos(client)
{:ok, devices} = Search.devices(client)Incident Management
The incident module wraps the Incident API.
alias Guardsix.Core.Incident
# List incidents within a time range
{:ok, incidents} = Incident.list(client, 1_714_986_600, 1_715_031_000)
{:ok, states} = Incident.list_states(client, 1_714_986_600, 1_715_031_000)
# Get a specific incident where both the incident_obj_id and incident_id
# is needed to get the unique incident.
{:ok, incident} = Incident.get(client, "incident_obj_id", "incident_id")
# Add comments
comments = [Guardsix.comment("incident_id_1", "This needs attention")]
{:ok, _} = Incident.add_comments(client, comments)
# Assign and update states
{:ok, _} = Incident.assign(client, ["incident_id_1"], "user_id")
{:ok, _} = Incident.resolve(client, ["incident_id_1"])
{:ok, _} = Incident.close(client, ["incident_id_2"])
{:ok, _} = Incident.reopen(client, ["incident_id_3"])
# Get users
{:ok, users} = Incident.get_users(client)Alert Rules
AlertRule wraps the Alert Rules API. All parameters for alert rule creation are defined but please refer to the alert rule builder for a composable structure for building rules.
alias Guardsix.Core.AlertRule
{:ok, rules} = AlertRule.list(client)
{:ok, rule} = AlertRule.get(client, "rule-id")
{:ok, _} = AlertRule.activate(client, ["id1", "id2"])
{:ok, _} = AlertRule.deactivate(client, ["id1"])
{:ok, _} = AlertRule.delete(client, ["id1"])
{:ok, notif} = AlertRule.get_notification(client, "rule-id", :email)Alert Rule Builder
Compose alert rules to be used with the create alert rule endpoint.
alias Guardsix.Data.Rule
rule =
Guardsix.rule("Brute Force Detection")
|> Rule.description("Detects brute force login attempts")
|> Rule.query("error_code=4625")
|> Rule.time_range(1, :day)
|> Rule.repos(["10.0.0.1"])
|> Rule.limit(100)
|> Rule.threshold(:greaterthan, 5)
|> Rule.risk_level("high")
|> Rule.mitre_tags(["T1110"])
{:ok, _} = AlertRule.create(client, rule)Notification Builders
Compose notifications for alert rules.
alias Guardsix.Data.EmailNotification
alias Guardsix.Data.HttpNotification
# Email notification
notif =
Guardsix.email_notification(["rule-1"], "admin@example.com")
|> EmailNotification.subject("Alert: {{ rule_name }}")
|> EmailNotification.template("<p>Details</p>")
{:ok, _} = AlertRule.create_email_notification(client, notif)
# HTTP notification with bearer auth
webhook =
Guardsix.http_notification(["rule-1"], "https://hooks.slack.com/abc", :post)
|> HttpNotification.body(~s({"text": "{{ rule_name }}"}))
|> HttpNotification.bearer_auth("my-token")
{:ok, _} = AlertRule.create_http_notification(client, webhook)
# Other auth types: no_auth/1, api_token_auth/3, basic_auth/3
webhook
|> HttpNotification.api_token_auth("X-API-Key", "secret123")
|> HttpNotification.basic_auth("user", "pass")Guardsix Repos and User-Defined Lists
alias Guardsix.Core.GuardsixRepo
alias Guardsix.Core.UserDefinedList
{:ok, repos} = GuardsixRepo.list(client)
{:ok, lists} = UserDefinedList.list(client)SSL Configuration
Pass ssl_verify: false to disable SSL verification (e.g. for self-signed certificates):
client = Guardsix.client("https://192.168.1.100", "admin", "your_secret_key", ssl_verify: false)Error Handling
All functions return {:ok, result} or {:error, reason} tuples:
alias Guardsix.Core.Search
case Search.get_id(client, query) do
{:ok, %{"search_id" => search_id}} ->
IO.puts("Search started: #{search_id}")
{:error, reason} ->
IO.puts("Search failed: #{inspect(reason)}")
endContributing
Please refer to CONTRIBUTING.md for development guidelines.
License
This project is licensed under the MIT License - see the LICENSE file for details.