diff --git a/docs/1-getting-started/core-concepts.md b/docs/1-getting-started/core-concepts.md index 918a41b8b..868b80d88 100644 --- a/docs/1-getting-started/core-concepts.md +++ b/docs/1-getting-started/core-concepts.md @@ -4,52 +4,54 @@ ### Endpoint Agents -The LimaCharlie endpoint agent is a cross platform endpoint Sensor. It is a low-level, light-weight sensor which executes detection and response functionality in real-time. +The LimaCharlie endpoint agent is a cross platform sensor. The sensor is small, runs at a low level, and does detection and response in real time. -The sensor provides a wide range of advanced capability. +The sensor has many capabilities. -- Flight Data Recorder (FDR) type functionality like Processes, Network Connections, Domain Name requests etc. -- Host isolation, automated response rules, intelligent local caching of events for in-depth Incident Response (IR) as well as some forensic features like dumping memory. +- Flight Data Recorder (FDR) functions such as processes, network connections, and domain name requests. +- Host isolation, automated response rules, and a local cache of events for Incident Response (IR). Forensic functions such as memory dumps are also available. -Sensors are designed to limit the potential for abuse resulting from unauthorized access to the LimaCharlie platform. This is achieved by limiting open-ended commands which might enable an attacker to covertly upload malicious software to your hosts. This means the LimaCharlie sensor is extremely powerful but also keeps its "read-only" qualities on your infrastructure. Of course, all access and interactions with the hosts are also logged for audit both within the cloud and tamper-proof forwarding to your own infrastructure. +Sensors limit the damage that an attacker can do with unauthorized access to the LimaCharlie platform. The sensor does not accept open-ended commands. An attacker therefore cannot use the sensor to upload malicious software to your hosts in secret. The sensor keeps its "read-only" qualities on your infrastructure. The cloud logs all access to the hosts and all interaction with them for audit. It also forwards these logs to your own infrastructure in a tamper-proof form. -Full commands list is in the [Endpoint Agent Commands](../8-reference/endpoint-commands.md) section. +The [Endpoint Agent Commands](../8-reference/endpoint-commands.md) section gives the full list of commands. ### Adapters -The LimaCharlie Adapter allows for real-time ingestion of any structured data, such as logs or telemetry, into the LimaCharlie platform, treating it as a first-class data source. This enables users to apply detection and response rules or send data to other outputs. Adapters support formats like JSON, Syslog, and CEFL, and can be deployed on-premise or cloud-to-cloud, either with or without the EDR sensor. For known sources like cloud platforms or Windows Event Logs, built-in mappings simplify data ingestion. Text-based Adapters allow for custom mapping and automation of any structured text. Additionally, pre-defined Adapters offer guided setups for common data sources like AWS CloudTrail and GuardDuty, while specialized connectors like Office 365 and Slack are supported with detailed configuration guidance. Some cloud-to-cloud Adapters, such as AWS S3, delete data after ingestion, so dedicated buckets with proper permissions are recommended. +The LimaCharlie Adapter ingests any structured data, such as logs or telemetry, into the LimaCharlie platform in real time. The platform treats this data like any other data source. You can then apply detection and response rules to the data, or send the data to other outputs. Adapters support formats such as JSON, Syslog, and CEFL. You can deploy an adapter on-premise or cloud-to-cloud, with or without the EDR sensor. + +Built-in mappings make ingestion more simple for known sources such as cloud platforms or Windows Event Logs. Text-based Adapters support custom mappings and automation for any structured text. Pre-defined Adapters give guided setups for common data sources such as AWS CloudTrail and GuardDuty. LimaCharlie also supports specialized adapters such as Office 365 and Slack, with detailed configuration instructions. Some cloud-to-cloud Adapters, such as AWS S3, delete the data after ingestion. Use a dedicated bucket with the correct permissions for these adapters. ## Installation Keys -Installation Keys are used to install a sensor. By specifying a key during installation the sensor can cryptographically be tied to your account. +You use an Installation Key to install a sensor. The key ties the sensor cryptographically to your account. -Get more details in the [Installation Keys section](../2-sensors-deployment/installation-keys.md). +The [Installation Keys section](../2-sensors-deployment/installation-keys.md) gives more details. ## Tags -Sensors can have Tags associated with them. Tags are added during creation or dynamically through the UI, API or Detection & Response Rules. +Sensors can have Tags. You add a Tag when you create the sensor. You can also add a Tag later with the web app, the API, or Detection & Response Rules. -Get more information in the [Sensor tags section](../2-sensors-deployment/sensor-tags.md). +The [Sensor tags section](../2-sensors-deployment/sensor-tags.md) gives more information. ## Detection & Response Rules -The Detection & Response Rules act as an automation engine. The Detection component is a rule that either matches an event or not. If the Detection component matches, the Response component of the rule is actioned. This can be used to automatically investigate, mitigate or apply Tags. +Detection & Response Rules are an automation engine. The Detection component matches an event, or it does not match. If the Detection component matches, LimaCharlie runs the Response component of the rule. The Response component can investigate, mitigate, or apply Tags automatically. -Detailed explanation in the [Detection & Response section](../3-detection-response/index.md). +The [Detection & Response section](../3-detection-response/index.md) gives a detailed explanation. ## Insight -Insight is our built-in data retention and search feature. It is enabled by default and included within our 2 sensor free tier as well. +Insight is the built-in feature for data retention and search. It is enabled by default, and it is included in the free tier of 2 sensors. -We configure everything for you so that you get access to one year of your data for visualization and searching. +LimaCharlie configures Insight for you. You get access to one year of your data to visualize and query. -You don't *have to* use the built-in data retention; you can forward data directly to your infrastructure if preferred. However, it is generally much simpler and a better experience to use Insight. If you do disable Insight, any data already collected will remain stored and searchable for the original retention period. If you prefer not to use Insight, go through the next section (Outputs). +You do not *have to* use the built-in data retention. You can send data directly to your infrastructure instead. But Insight is usually more simple to use. If you disable Insight, the data that LimaCharlie already collected stays stored and searchable for the original retention period. If you do not want to use Insight, read the next section (Outputs). ## Outputs -If you are using Insight (data retention) this section is optional. +If you use Insight (data retention), this section is optional. -LimaCharlie can relay the data somewhere for longer term storage and analysis. Where that data is sent depends on which Outputs are activated. You can have as many Output modules active as you want, so you can send it to multiple syslog destinations using the Syslog Output module and then send it to some cold storage over an Scp Output module. +LimaCharlie can send the data to another location for long-term storage and analysis. The Outputs that you activate control the destination of the data. You can activate as many Output modules as you want. For example, you can send the data to several syslog destinations with the Syslog Output module, and also send it to cold storage with the Scp Output module. Output is also split between four categories: @@ -58,13 +60,13 @@ Output is also split between four categories: - audit - deployment -Selecting a Stream when creating an Output will select the relevant type of data to flow through it. +When you create an Output, select a Stream. The Stream sets the type of data that moves through the Output. -More details and exact configuration possibilities in the [Outputs section](../5-integrations/outputs/index.md). +The [Outputs section](../5-integrations/outputs/index.md) gives more details and the exact configuration options. ## LimaCharlie Data Structures -Understanding the core data structures in LimaCharlie is essential for working with Detection & Response rules, LCQL queries, and outputs. All data in LimaCharlie flows through one of four primary structures. +You must know the core data structures in LimaCharlie to work with Detection & Response rules, LCQL queries, and outputs. All data in LimaCharlie moves through one of four primary structures. ### The Four Core Structures @@ -74,7 +76,7 @@ Understanding the core data structures in LimaCharlie is essential for working w **Structure**: Two top-level objects - `routing` (metadata) and `event` (event-specific data) **Examples**: Process execution (NEW_PROCESS), DNS queries (DNS_REQUEST), network connections (NETWORK_CONNECTIONS), Windows Event Logs (WEL) -Events are the foundation of LimaCharlie. They capture what's happening on your endpoints and in your infrastructure. Every event includes: +Events are the foundation of LimaCharlie. They record what happens on your endpoints and in your infrastructure. Every event includes: - `routing` object: Consistent metadata like sensor ID, timestamp, hostname, platform - `event` object: Event-type-specific data like file paths, command lines, network addresses @@ -87,10 +89,10 @@ Events are the foundation of LimaCharlie. They capture what's happening on your **Structure**: Includes original event's `routing`, the triggering `detect` (event data), plus detection metadata **Key Fields**: `cat` (detection name), `source`, `detect_id`, `priority`, `detect_mtd` (metadata), `detect_data` (extracted IOCs) -When a D&R rule matches an event, LimaCharlie creates a Detection. Detections inherit the event's routing information and add: +When a D&R rule matches an event, LimaCharlie creates a Detection. A Detection inherits the routing information of the event and adds: - Detection metadata: rule name, author, priority, tags -- Extracted data: Structured IOCs pulled from the event +- Extracted data: Structured IOCs taken from the event - Links: References to documentation or playbooks [See complete Detection Structure Reference](../3-detection-response/tutorials/writing-testing-rules.md) @@ -101,10 +103,10 @@ When a D&R rule matches an event, LimaCharlie creates a Detection. Detections in **Structure**: Flat object with `oid`, `ts` (timestamp), and audit-specific fields **Examples**: Configuration changes, user actions, API calls, sensor deployments -Audit logs track what happens in your LimaCharlie organization: +Audit logs record what happens in your LimaCharlie organization: -- Who performed actions (`ident` - identity) -- What was affected (`entity` - object) +- Who did the actions (`ident` - identity) +- What the action affected (`entity` - object) - Action characteristics (`mtd` - metadata) - Error messages (`component`, `error`) @@ -118,27 +120,27 @@ Audit logs track what happens in your LimaCharlie organization: #### For D&R Rules -D&R rules operate on Events and produce Detections. Understanding the Event structure helps you: +D&R rules operate on Events and produce Detections. Knowledge of the Event structure helps you to: - Access the right fields with `event/` and `routing/` paths - Filter by event type, platform, or sensor -- Correlate related events using `routing/this` and `routing/parent` +- Correlate related events with `routing/this` and `routing/parent` #### For LCQL Queries -LCQL can query all three primary streams (event, detect, audit). Knowing the structure helps you: +LCQL can query all three primary streams (event, detect, audit). Knowledge of the structure helps you to: - Select the right fields for investigation - Join data across streams -- Filter efficiently using the correct field paths +- Filter efficiently with the correct field paths #### For Outputs -Each output stream type has a different structure. Understanding this helps you: +Each output stream type has a different structure. Knowledge of the structure helps you to: - Configure the right stream for your destination - Build parsers for external systems -- Filter data before sending it +- Filter data before you send it ### Data Flow: Event → Detection @@ -177,7 +179,7 @@ All LimaCharlie structures use consistent path patterns: ## API Keys -The API keys are represented as UUIDs. They are linked to your specific organization and enable you to programmatically acquire authorization tokens that can be used on our REST API. See the [API key section](../7-administration/access/api-keys.md) for more details. +API keys are UUIDs. Each key is linked to one organization. You use a key to get authorization tokens for the REST API from your programs. The [API key section](../7-administration/access/api-keys.md) gives more details. --- diff --git a/docs/1-getting-started/index.md b/docs/1-getting-started/index.md index 26127760e..7e7beb74a 100644 --- a/docs/1-getting-started/index.md +++ b/docs/1-getting-started/index.md @@ -5,5 +5,5 @@ Get started with LimaCharlie. ## Documentation - [What is LimaCharlie?](what-is-limacharlie.md) - Platform overview -- [Quickstart](quickstart.md) - Get up and running quickly +- [Quickstart](quickstart.md) - First steps with the platform - [Core Concepts](core-concepts.md) - Fundamental platform concepts diff --git a/docs/1-getting-started/quickstart.md b/docs/1-getting-started/quickstart.md index 1ee9b0fe9..457234602 100644 --- a/docs/1-getting-started/quickstart.md +++ b/docs/1-getting-started/quickstart.md @@ -1,87 +1,85 @@ # Quickstart -LimaCharlie is infrastructure to connect sources of security data, automate activity based on what's being observed, and forward data to where you need it. There's no *correct* way to use it - every environment is different. +LimaCharlie is infrastructure that connects sources of security data, automates actions on the data that it sees, and sends the data where you need it. There is no *correct* way to use it, because every environment is different. -That said, the majority of LimaCharlie users require basic endpoint detection and response (EDR) capabilities. This guide will cover: +Most LimaCharlie users need basic endpoint detection and response (EDR) capabilities. This guide covers these tasks: -1. Creating a new [Organization](#creating-an-organization) -2. Deploying a [Sensor](#deploying-a-sensor) to the Organization -3. Adding [Sigma rules](#adding-sigma-rules) to detect suspicious activity -4. Forwarding detections to an external destination as an [Output](#output) +1. Create a new [Organization](#creating-an-organization) +2. Deploy a [Sensor](#deploying-a-sensor) to the Organization +3. Add [Sigma rules](#adding-sigma-rules) to detect suspicious activity +4. Forward detections to an external destination as an [Output](#output) -All of this can be done within our free tier, which offers full platform functionality for up to two (2) sensors. If you haven't already signed up for a free account, please do so at [app.limacharlie.io](https://app.limacharlie.io). - -Let's get started! +You can do all of these tasks in the free tier. The free tier gives full platform functionality for a maximum of two (2) sensors. If you do not have a free account, sign up at [app.limacharlie.io](https://app.limacharlie.io). ## Creating an Organization -LimaCharlie organizations are isolated tenants in the cloud, conceptually equivalent to "projects". They can be configured to suit the needs of each deployment. +LimaCharlie organizations are isolated tenants in the cloud. They are equivalent to "projects". You can configure each organization for the needs of its deployment. -After accepting the initial Terms of Service, you'll be offered a prompt to create an organization in a selected `Region` with a globally unique `Name`. +After you accept the initial Terms of Service, a prompt asks you to create an organization. Select a `Region` and give a globally unique `Name`. Region Selection -The region that you select for an organization is permanent. Please also consider regulatory requirements for you and/or your customers' data. +The region that you select for an organization is permanent. Also consider the regulatory requirements for your data and for the data of your customers. -Once the organization is created, you'll be forwarded to our initial dashboard and Sensor list, which will be empty and ready for the next step. +After LimaCharlie creates the organization, it shows the initial dashboard and the Sensor list. The list is empty and ready for the next step. ## Deploying a Sensor -From the Sensors page in your new organization, click `Add Sensor` to open the setup flow for new sensors. Generally speaking, Sensors are executables that install on hosts and connect them to the LimaCharlie cloud to send telemetry, receive commands, and other capabilities. +On the Sensors page of your new organization, click `Add Sensor`. This opens the setup flow for new sensors. Sensors are executables that install on hosts. They connect the hosts to the LimaCharlie cloud to send telemetry, receive commands, and give other capabilities. Sensors Overview -For a full overview of types of sensors and their capabilities, check out Sensors. +For a full overview of the types of sensors and their capabilities, see Sensors. -The setup flow should make this process straightforward. For example's sake, let's say we're installing a sensor on a Windows 10 (64 bit) machine we have in front of us. +This example installs a sensor on a Windows 10 (64 bit) machine. -- Choose the Windows sensor type -- Create an Installation Key - this registers the executable to communicate securely with your organization -- Choose the `64 bit (.exe)` installer -- Follow the on-screen instructions to execute the installer properly -- See immediate feedback when the sensor registers successfully with the cloud +1. Choose the Windows sensor type. +2. Create an Installation Key. The key registers the executable to communicate securely with your organization. +3. Choose the `64 bit (.exe)` installer. +4. Obey the on-screen instructions to run the installer correctly. +5. See the immediate feedback when the sensor registers with the cloud. Potential Issues -Since sensors are executables that talk to the cloud, antivirus software and networking layers may interfere with installation. If you run into an issue, take a look at troubleshooting. +Sensors are executables that communicate with the cloud. Antivirus software and network layers can interfere with the installation. If you get an issue, see troubleshooting. -With a Windows sensor connected to the cloud, you should gain a lot of visibility into the endpoint. If we view the new sensor inside the web application, we'll have access to views such as: +A Windows sensor that is connected to the cloud gives you much visibility into the endpoint. When you open the new sensor in the web app, you get views such as: -- `Timeline`: the viewer for telemetry events being collected from the endpoint -- `Processes`: the list of processes running on the endpoint, their level of network activity, and commands to manipulate processes (i.e. kill / pause / resume process, or view modules) -- `File System`: an explorer for the endpoint's file system, right in the browser -- `Console`: a safe shell-like environment for issuing commands -- `Live Feed`: a running view of the live output of all the sensor's events +- `Timeline`: the viewer for the telemetry events that LimaCharlie collects from the endpoint +- `Processes`: the list of processes that run on the endpoint, their level of network activity, and commands to control processes (i.e. kill / pause / resume process, or view modules) +- `File System`: an explorer for the file system of the endpoint, in the browser +- `Console`: a safe shell-like environment to send commands +- `Live Feed`: a live view of all the events of the sensor -With telemetry coming in from the cloud, let's add rules to detect potentially malicious activity. +Telemetry now comes in through the cloud. The next step adds rules to detect possible malicious activity. ## Adding Sigma Rules -Writing security rules and automations from scratch is a huge effort. To set an open, baseline standard of coverage, LimaCharlie maintains a `sigma` add-on which can be enabled for free, and is kept up to date with the [openly maintained threat signatures](https://github.com/SigmaHQ/sigma). +It takes much work to write security rules and automations from the start. LimaCharlie maintains a `sigma` add-on to give an open baseline of coverage. You can enable the add-on for free. LimaCharlie keeps it up to date with the [openly maintained threat signatures](https://github.com/SigmaHQ/sigma). -Enabling the Sigma add-on will automatically apply rules to your organization to match these threat signatures so we can begin to see Detections on incoming endpoint telemetry. +When you enable the Sigma add-on, LimaCharlie applies rules to your organization automatically. These rules match the threat signatures, and they make Detections on the endpoint telemetry that comes in. Writing Detection and Response rules -Writing your own rules is outside the scope of this guide, but we do encourage checking out [Detection & Response](../3-detection-response/tutorials/writing-testing-rules.md) when you're finished. +This guide does not explain how to write your own rules. After you finish this guide, read [Detection & Response](../3-detection-response/tutorials/writing-testing-rules.md). ## Output -Security data generated from sensors is yours to do with as you wish. For example's sake, let's say we want to forward detections to an [Amazon S3 bucket](https://aws.amazon.com/s3/) for longer-lived storage of detections. +The security data from your sensors is yours, and you can do what you want with it. This example sends detections to an [Amazon S3 bucket](https://aws.amazon.com/s3/) for longer storage of detections. -From the Outputs page in your organization, click `Add Output` to open the setup flow for new outputs. Again, the setup flow should make this process straightforward. +On the Outputs page of your organization, click `Add Output`. This opens the setup flow for new outputs. -- Choose the Detections stream -- Choose the Amazon S3 destination -- Configure the Output and ensure it connects securely to the correct bucket: - - Output Name - - Bucket Name - - Key ID - - Secret Key - - Region -- Optionally, you can view samples of the detection stream's data (assuming recent detections have occurred) +1. Choose the Detections stream. +2. Choose the Amazon S3 destination. +3. Configure the Output. Make sure that it connects securely to the correct bucket: + - Output Name + - Bucket Name + - Key ID + - Secret Key + - Region +4. Optionally, look at samples of the data in the detection stream. Samples are available only if there are recent detections. -With this output in place you can extend the life of your detections beyond the 1 year LimaCharlie retains them, and stage them for any tool that can pull from S3. +With this output in place, you can keep your detections for more than the 1 year that LimaCharlie retains them. You can also stage them for any tool that can pull from S3. --- diff --git a/docs/1-getting-started/use-cases/adversary-techniques.md b/docs/1-getting-started/use-cases/adversary-techniques.md index 7fec65a4c..c2f297aaf 100644 --- a/docs/1-getting-started/use-cases/adversary-techniques.md +++ b/docs/1-getting-started/use-cases/adversary-techniques.md @@ -1,23 +1,23 @@ # Uncovering Adversary Techniques -LimaCharlie's Agentic SecOps Workspace provides a comprehensive approach to combating ransomware, focusing on early detection during the reconnaissance stage and rapid response in the event of a detonation. By gathering telemetry from a wide range of sources, enabling widespread deployment, and leveraging real-time response capabilities, LimaCharlie empowers organizations to effectively detect, stop, and mitigate ransomware attacks, minimizing damage and ensuring business continuity. +The LimaCharlie Agentic SecOps Workspace fights ransomware in two ways. It detects the attack early, in the reconnaissance stage, and it responds quickly if the ransomware detonates. LimaCharlie collects telemetry from many sources, deploys everywhere, and responds in real time. Organizations can therefore detect, stop, and mitigate ransomware attacks. This limits the damage and keeps the business in operation. ## Problems with uncovering adversary techniques -Ransomware attacks have become increasingly sophisticated and targeted, posing a significant threat to organizations of all sizes. The challenges in effectively combating ransomware include: +Ransomware attacks are more and more sophisticated and targeted. They are a significant threat to organizations of all sizes. To fight ransomware, you must solve these problems: -- **Extended dwell time:** Ransomware attacks often involve weeks or months of reconnaissance, during which malicious actors seek to identify optimal detonation points. Detecting and stopping the attack during this stage is crucial but challenging. -- **Difficulty in correlating data:** Malicious actors often move around and attempt to hide their presence, making it difficult to identify and correlate their activities across various systems and data sources. -- **Rapid spread and damage:** In the event of a successful ransomware detonation, the malware can spread rapidly, encrypting files and causing significant damage before security teams can respond. +- **Extended dwell time:** A ransomware attack often includes weeks or months of reconnaissance. During this time, the malicious actors look for the best points to detonate the ransomware. It is important to detect and stop the attack in this stage, but it is difficult. +- **Difficulty in correlating data:** Malicious actors move between systems and try to hide their presence. It is difficult to identify their activities and to correlate those activities across different systems and data sources. +- **Rapid spread and damage:** If the ransomware detonates, the malware can spread quickly. It encrypts files and causes significant damage before the security team can respond. ## LimaCharlie's solution -LimaCharlie's Agentic SecOps Workspace offers a comprehensive approach to combating ransomware, focusing on early detection during the reconnaissance stage and rapid response in the event of a detonation: +The LimaCharlie Agentic SecOps Workspace fights ransomware with early detection in the reconnaissance stage and with rapid response if the ransomware detonates: -- **Comprehensive telemetry gathering:** LimaCharlie gathers telemetry and external artifacts from a wide range of sources, including endpoints, networks, and cloud environments. By normalizing all data to JSON and processing it through the Agentic SecOps Workspace's detection, automation, and response engine, LimaCharlie gains a global view of the organization's security posture, enabling it to identify suspicious activities and correlations that may indicate a ransomware attack in progress. -- **Early detection through widespread deployment:** LimaCharlie's ability to deploy everywhere allows it to detect intruders faster than the competition, often before malicious actors can lay an effective trap. By monitoring everything from one place and leveraging advanced detection logic, LimaCharlie can identify and stop ransomware attacks during the crucial reconnaissance stage. -- **Real-time response with semi-persistent TLS connection:** In the event of a ransomware detonation, LimaCharlie's real-time, semi-persistent TLS connection with endpoints enables an unparalleled response capability. If detection logic is in place to catch a ransomware event, response actions can be taken across the entire fleet in real-time. This allows security teams to instantly isolate affected machines from the network while maintaining command and control through LimaCharlie, minimizing further damage and data exfiltration. -- **Advanced threat hunting and remediation:** With LimaCharlie, analysts responding to a ransomware event have access to all affected machines and a full year's history of telemetry. This enables them to run remediation scripts on the endpoints, kill process trees, and hunt for any malicious presence. By leveraging advanced indicators, such as FILE_TYPE_ACCESSED events, security teams can detect ransomware detonation events before the malware proliferates, significantly reducing the impact of the attack. +- **Comprehensive telemetry gathering:** LimaCharlie collects telemetry and external artifacts from many sources, such as endpoints, networks, and cloud environments. It normalizes all data to JSON and processes the data through the detection, automation, and response engine of the Agentic SecOps Workspace. LimaCharlie therefore gets a global view of the security posture of the organization. This view shows suspicious activities and correlations that can be a ransomware attack in progress. +- **Early detection through widespread deployment:** LimaCharlie can deploy everywhere, so it detects intruders faster than the competition. It often detects them before the malicious actors can set an effective trap. LimaCharlie monitors everything from one place and uses advanced detection logic. It can identify and stop ransomware attacks in the critical reconnaissance stage. +- **Real-time response with semi-persistent TLS connection:** If ransomware detonates, the real-time, semi-persistent TLS connection between LimaCharlie and the endpoints gives an unparalleled response capability. If detection logic is in place to catch a ransomware event, LimaCharlie can do response actions across the full fleet in real time. The security team can isolate the affected machines from the network immediately and keep command and control through LimaCharlie. This limits more damage and more data exfiltration. +- **Advanced threat hunting and remediation:** With LimaCharlie, an analyst who responds to a ransomware event has access to all affected machines and to a full year of telemetry history. The analyst can run remediation scripts on the endpoints, kill process trees, and hunt for a malicious presence. Advanced indicators, such as FILE_TYPE_ACCESSED events, let the security team detect ransomware detonation events before the malware spreads. This reduces the impact of the attack significantly. ## What's Next diff --git a/docs/1-getting-started/use-cases/building-products.md b/docs/1-getting-started/use-cases/building-products.md index b13613ded..140673a8b 100644 --- a/docs/1-getting-started/use-cases/building-products.md +++ b/docs/1-getting-started/use-cases/building-products.md @@ -2,13 +2,13 @@ The LimaCharlie Agentic SecOps Workspace (ASW) is a unified platform for modern cybersecurity operations. -The ASW delivers core cybersecurity capabilities and infrastructure via a public cloud model: on-demand, pay-per-use, and API-first. For the cybersecurity industry, this is a paradigm shift comparable to how the IT public cloud revolutionized IT. +The ASW supplies core cybersecurity capabilities and infrastructure with a public cloud model: on-demand, pay-per-use, and API-first. For the cybersecurity industry, this change is as large as the change that the IT public cloud made to IT. -For cybersecurity startups and builders, the Agentic SecOps Workspace offers a robust foundation to create valuable products and services. The ASW helps innovators get to market faster, build genuinely independent businesses, increase their probability of success, and scale successful offerings with ease. +For cybersecurity startups and builders, the Agentic SecOps Workspace is a foundation for new products and services. The ASW helps innovators to get to market faster, to build independent businesses, to increase their probability of success, and to scale successful offerings. ## 3 ways to go to market more effectively -The Agentic SecOps Workspace provides the tools and infrastructure needed to secure any given organization—and is designed to be flexible and highly customizable. Because of this, the ASW enables many different types of solutions. Individual builders' use cases can vary significantly. Nevertheless, all startups and product developers using the platform will benefit from the following three recommendations: +The Agentic SecOps Workspace supplies the tools and infrastructure to secure an organization. It is flexible, and you can customize it. The ASW therefore supports many different types of solutions. The use cases of individual builders are very different. But these three recommendations help all startups and product developers that use the platform: - Focus on Your Core Value - Reduce Up-front Costs @@ -16,56 +16,65 @@ The Agentic SecOps Workspace provides the tools and infrastructure needed to sec ### Focus on Your Core Value -The Agentic SecOps Workspace delivers foundational, well-understood security technologies as capabilities: as open, cloud-native primitives instead of black-box tools. Here's how builders can use this fact to create better products and service offerings: +The Agentic SecOps Workspace supplies basic, well-understood security technologies as capabilities. They are open, cloud-native primitives, not black-box tools. Builders can use these capabilities to make better products and services: -**Clarify your differentiators.** In a crowded marketplace where buyers are already wary of tool sprawl, it's difficult to stand out—and challenging to convince buyers to take on another vendor. To succeed, startups must demonstrate clear value and differentiate themselves. Determine what sets you apart, and where you can deliver the greatest value to customers. This is where your internal engineering resources should be focused. +**Clarify your differentiators.** The marketplace is crowded, and buyers are already careful about too many tools. It is difficult to be different, and difficult to persuade a buyer to accept one more vendor. To succeed, a startup must show clear value and must be different from the competition. Find what makes you different, and find where you can give the most value to customers. Use your internal engineering resources on that work. -**Offload infrastructure work.** The Agentic SecOps Workspace offers the kinds of mature cybersecurity capabilities that teams used to have to develop themselves or purchase as part of a product. This includes things like: Deploying endpoint capabilities via a multiplatform agent, alerting and correlating logs from any source, automating real-time analysis and response regardless of the environment, routing telemetry data to any destination, performing historical threat hunts, isolating endpoints from a network remotely, and many more. +**Offload infrastructure work.** The Agentic SecOps Workspace supplies mature cybersecurity capabilities. In the past, a team had to develop these capabilities or buy them as part of a product. The capabilities include: -In short, cybersecurity builders no longer need to "reinvent the wheel" in order to get to market. Here again, the clear analogy is to the IT public cloud. Most software developers today wouldn't invest in physical servers or develop complex, in-house solutions to handle application deployment and scaling. They would simply leverage cloud-based services like AWS Lambda or Azure Functions and run their applications without ever worrying about the underlying infrastructure. +- Deployment of endpoint capabilities with a multiplatform agent +- Alerts and correlation for logs from any source +- Automated real-time analysis and response in any environment +- Telemetry data sent to any destination +- Historical threat hunts +- Remote isolation of endpoints from a network -Similarly, by using the infrastructure capabilities of the ASW, cybersecurity builders can spend their time and resources on their core value proposition—thereby reducing maintenance and integration challenges, eliminating external dependencies, and avoiding the risk that comes from building on someone else's product. +There are many more capabilities. -**Work with ASW engineers to develop custom integrations.** The Agentic SecOps Workspace is a vendor-neutral provider of tooling and infrastructure for the cybersecurity industry. It is not a potential competitor. +Cybersecurity builders therefore do not need to build these capabilities again to get to market. The IT public cloud is a clear analogy. Most software developers today do not buy physical servers, and they do not develop complex in-house solutions to deploy and scale an application. They use cloud services such as AWS Lambda or Azure Functions, and they run their applications without work on the infrastructure below. -As you develop on the ASW, reach out to LimaCharlie engineers for support in creating customized integrations, advice on best practices for a configurations or deployments, or feature requests that you'd like to see in the development roadmap. The ASW's public cloud business model means that the platform succeeds when its users succeed, so someone will always be on hand to help. +In the same way, the infrastructure capabilities of the ASW let cybersecurity builders spend their time and resources on their core value. This reduces maintenance and integration work, removes external dependencies, and removes the risk to build on the product of another company. -By building on a public cloud for cybersecurity, startups can focus on what they do best without having to develop and maintain DIY solutions—and without putting their business in the hands of a traditional vendor. +**Work with ASW engineers to develop custom integrations.** The Agentic SecOps Workspace supplies vendor-neutral tools and infrastructure for the cybersecurity industry. It is not a possible competitor. + +When you develop on the ASW, contact the LimaCharlie engineers. They give support for custom integrations, advice about the best practices for a configuration or a deployment, and a channel for the feature requests that you want on the development roadmap. With the public cloud business model of the ASW, the platform succeeds when its users succeed. Help is therefore always available. + +A public cloud for cybersecurity lets a startup give attention to its own strengths. The startup does not develop and maintain DIY solutions, and it does not put its business in the hands of a traditional vendor. ### Reduce up-front costs -The Agentic SecOps Workspace has a transparent, pay-per-use pricing model and delivers all capabilities on demand. In addition, the platform offers a number of valuable free resources. This helps builders to cut costs and reduce initial investment in several ways: +The Agentic SecOps Workspace has a transparent, pay-per-use pricing model, and it supplies all capabilities on demand. The platform also gives many free resources. Builders can therefore cut costs and reduce the initial investment in several ways: -**Conduct research and develop a prototype for free.** The ASW gives all users access to a fully featured free tier that includes two sensors. There is thus zero up-front cost to begin researching the platform, testing your idea, or even developing a prototype. Start by seeing if the ASW is the right choice for your project. Then, save money on early-stage development work once you begin. +**Conduct research and develop a prototype for free.** The ASW gives all users a free tier with full features and two sensors. There is no up-front cost to research the platform, to test your idea, or to develop a prototype. First, decide if the ASW is the correct choice for your project. Then save money on the early development work. -**Build without lock-in.** The ASW's pricing model means you only pay for what you need, for as long as you use it. You don't have to deal with mandatory minimums, long-term contracts, complex licensing, or termination fees. This enables you to create on the platform secure in the knowledge that you are not committed to a given level of spending before your growth justifies it—and that you aren't locked into your infrastructure provider. +**Build without lock-in.** With the pricing model of the ASW, you pay only for what you need, and only for the time that you use it. There are no mandatory minimums, long-term contracts, complex licenses, or termination fees. You can therefore build on the platform with no commitment to a level of spend before your growth needs it. You are also not locked to your infrastructure provider. -**Use available ASW resources to save money.** Building on the ASW also offers several direct and indirect ways to lower costs during development. +**Use available ASW resources to save money.** The ASW gives several direct and indirect ways to lower costs during development. -The Agentic SecOps Workspace is designed to be as user-friendly and easy to master as possible. In addition, the ASW is supported by extensive documentation, an active community forum of users, and a learning library full of tutorials and walkthroughs. This means developers will spend less time learning a new technology—and more time building. +The Agentic SecOps Workspace is designed to be user-friendly and quick to master. The ASW also has extensive documentation, an active community forum of users, and a learning library with tutorials and walkthroughs. Developers therefore spend less time on a new technology and more time on their product. -In addition, you can make use of more direct forms of assistance. Users can reach out to ASW engineers at any time for help. Qualified builders can also apply for a $1000 platform credit through the platform's Cybersecurity Infrastructure Grant Program. Leverage these resources to reduce your development costs and ensure that your engineers are spending their time on tasks that add the most value. +More direct help is also available. A user can contact the ASW engineers at any time. A qualified builder can apply for a $1000 platform credit through the Cybersecurity Infrastructure Grant Program of the platform. Use these resources to reduce your development costs and to make sure that your engineers work on the tasks with the most value. -**Meet compliance needs with free storage.** All telemetry data brought into the ASW is stored for the cost of ingestion for one full year. If your project has data retention or compliance needs, leverage the ASW's default storage capability to help keep your data storage costs down. +**Meet compliance needs with free storage.** The ASW stores all telemetry data that comes into it for one full year, for the cost of ingestion. If your project has data retention or compliance needs, use the default storage of the ASW to keep your storage costs low. -**Take advantage of discounted pricing.** If you've decided to build with the ASW for the foreseeable future—or if your product or service has started to see significant uptake—use discounted pricing options to save money as you grow. The Agentic SecOps Workspace provides volume-based discounts to help you improve your savings as usage increases, as well as annual or multi-year discounts for those ready to commit to longer-term platform usage. +**Take advantage of discounted pricing.** Use the discount options to save money when you grow. These options apply if you decide to build with the ASW for a long time, or if your product or service gets significant uptake. The Agentic SecOps Workspace gives volume-based discounts that increase your savings when your usage increases. It also gives annual and multi-year discounts if you can commit to longer use of the platform. -The ASW gives cybersecurity builders many of the competitive advantages the IT public cloud offers to startups in other verticals—and a high degree of direct assistance and support as well. +The ASW gives cybersecurity builders many of the competitive advantages that the IT public cloud gives to startups in other verticals. It also gives much direct help and support. ### Build to scale -The Agentic SecOps Workspace enables scalable cybersecurity operations. Here's how developers can benefit from building on such a platform: +The Agentic SecOps Workspace makes cybersecurity operations scalable. Developers get these benefits when they build on the platform: -**Future-proof your infrastructure.** Cybersecurity startups often turn to open-source or custom-built infrastructure to save money and stay independent. But while this approach may work early on, its limitations become apparent over time. It's possible to build performant and successful cybersecurity projects on open-source or DIY technologies. +**Future-proof your infrastructure.** Cybersecurity startups often use open-source or custom-built infrastructure to save money and to stay independent. This approach can work at the start, but its limits become clear with time. It is possible to build fast and successful cybersecurity projects on open-source or DIY technologies. -However, many businesses that take this route experience difficulties when they grow. The complexity, integration challenges, and troubleshooting work that are manageable with a small user base can quickly become untenable at scale. Before basing a part of your project on a custom or open-source solution, consider the challenges you will encounter later on if you are successful. You may be better served by using the ASW for that aspect of your offering. +But many businesses that use this method get difficulties when they grow. A small user base keeps the complexity, the integration work, and the troubleshooting controllable. At a large scale, the same work becomes impossible. Before you build a part of your project on a custom or open-source solution, think about the problems that success brings later. The ASW can be a better choice for that part of your offering. -**Build on a scalable platform.** The Agentic SecOps Workspace is designed to help organizations scale their security operations. Basic assumptions of the platform include things like multitenancy, flexibility, open APIs, and rich automation capabilities. Builders should plan to scale from the outset—leveraging the ASW's engineering-centric approach to support future growth by developing architectures, integrations, and workflows that will enable scaling without limits. +**Build on a scalable platform.** The Agentic SecOps Workspace helps organizations to scale their security operations. The basic assumptions of the platform include multitenancy, flexibility, open APIs, and many automation capabilities. Plan for scale from the start. Use the engineering-centric approach of the ASW to support future growth, and develop architectures, integrations, and workflows that scale without limits. -Any successful cybersecurity business will encounter challenges as it attempts to increase its customer support or its development work. However, building on an engineering-centric platform enables startups to plan for the future from day one—and makes growth easier and more trouble-free. +Each successful cybersecurity business gets problems when it increases its customer support or its development work. But an engineering-centric platform lets a startup plan for the future from the first day. Growth then causes fewer problems. -**Scale with your revenue.** A major problem for early-stage cybersecurity startups is that they must spend money on fixed infrastructure costs without having enough users for that to be profitable. If funding runs out before a product–market fit is found, the business fails. +**Scale with your revenue.** An early-stage cybersecurity startup must pay fixed infrastructure costs, but it does not have enough users to make a profit. If the funding stops before the startup finds a product–market fit, the business fails. -The Agentic SecOps Workspace offers an alternative route. Leverage the ASW's pay-per-use pricing to scale your infrastructure spending with your revenue. Even if you start off with a small customer base, you won't be losing money on infrastructure costs. Conserve your resources and allocate your spending to development, marketing, and sales efforts instead. +The Agentic SecOps Workspace gives a different method. Use the pay-per-use pricing of the ASW to scale your infrastructure spend with your revenue. If you start with a small customer base, you do not lose money on infrastructure costs. Keep your resources, and spend them on development, marketing, and sales. -The ASW offers builders a firm foundation for success. It provides a platform that is built to scale—and its pay-as-you-go pricing helps startups extend their runway and grow gradually and safely. +The ASW is a firm foundation for the success of a builder. The platform is built to scale. Its pay-as-you-go pricing helps a startup to extend its runway and to grow slowly and safely. diff --git a/docs/1-getting-started/use-cases/chromeos-support.md b/docs/1-getting-started/use-cases/chromeos-support.md index dabef2e71..62b50388f 100644 --- a/docs/1-getting-started/use-cases/chromeos-support.md +++ b/docs/1-getting-started/use-cases/chromeos-support.md @@ -1,17 +1,17 @@ # ChromeOS Support -Gain visibility in your Chrome fleet and enhance ChromeOS security to unify endpoint protection across your organization with LimaCharlie's comprehensive, centralized, and adaptable platform. +Get visibility into your Chrome fleet and increase ChromeOS security. The centralized and adaptable LimaCharlie platform unifies endpoint protection across your organization. ## ChromeOS support problems -- **Growing in popularity:** Chrome books are the fastest growing segment of personal computers and are being adopted by organizations and schools en masse. Despite this, there is very little security coverage (other than that which is conferred by the platform) and without LimaCharlie, visibility requires an SSL proxy. -- **Visibility gap:** Managing and monitoring ChromeOS devices within traditional security infrastructures is challenging due to compatibility limitations and lack of centralized visibility, especially in enterprise environments. -- **Chromebook threats rising:** ChromeOS vulnerabilities and zero-day exploits are victim to targeted attacks, demanding a robust and adaptable security solution. +- **Growing in popularity:** Chrome books are the fastest growing segment of personal computers, and many organizations and schools now use them. But there is very little security coverage, other than the coverage that the platform itself gives. Without LimaCharlie, visibility needs an SSL proxy. +- **Visibility gap:** It is difficult to manage and monitor ChromeOS devices in a traditional security infrastructure. Compatibility limits and the absence of centralized visibility cause this problem, especially in enterprise environments. +- **Chromebook threats rising:** Targeted attacks use ChromeOS vulnerabilities and zero-day exploits. These attacks need an adaptable security solution. ## LimaCharlie's solution -- **Comprehensive endpoint protection:** LimaCharlie's Chrome Sensor delivers endpoint detection and response (EDR) capabilities directly on Chromebooks and for ChromeOS, providing deep visibility into network activity, installed packages, and downloaded files. -- **Centralized management and insights:** Integrate ChromeOS devices seamlessly into your existing security ecosystem, gain centralized telemetry and threat detection across all endpoints, and simplify management through policies and rules. -- **Advanced detection and threat hunting:** Utilize LimaCharlie's advanced analytics and threat intelligence to proactively identify suspicious activities, hunt for hidden threats, and respond effectively to evolving cyber threats. +- **Comprehensive endpoint protection:** The LimaCharlie Chrome Sensor gives endpoint detection and response (EDR) capabilities on Chromebooks and for ChromeOS. It gives deep visibility into network activity, installed packages, and downloaded files. +- **Centralized management and insights:** Integrate ChromeOS devices into your existing security ecosystem. Get centralized telemetry and threat detection across all endpoints. Manage the devices with policies and rules. +- **Advanced detection and threat hunting:** Use the advanced analytics and threat intelligence of LimaCharlie to identify suspicious activities. Hunt for hidden threats, and respond to new cyber threats. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Like agents, Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. diff --git a/docs/1-getting-started/use-cases/cloud-security.md b/docs/1-getting-started/use-cases/cloud-security.md index 3798bf3d5..d1d58dab4 100644 --- a/docs/1-getting-started/use-cases/cloud-security.md +++ b/docs/1-getting-started/use-cases/cloud-security.md @@ -1,19 +1,19 @@ # Cloud Security -The Agentic SecOps Workspace simplifies the difficult task of securing cloud resources and managing complex cloud-based or hybrid infrastructure. LimaCharlie brings better visibility, robust interoperability, and better options for storing data to cloud and hybrid environments. +The Agentic SecOps Workspace helps you secure cloud resources. It also helps you manage cloud-based and hybrid infrastructure. LimaCharlie adds visibility, interoperability, and more options to store data in cloud and hybrid environments. ## Cloud security problems -Organizations are increasingly embracing the benefits of cloud services and solutions. As your business infrastructure integrates with cloud resources securing your environment becomes more complex, leading to: +More organizations use cloud services and solutions. When your business infrastructure connects to cloud resources, your environment becomes more difficult to secure. This causes these problems: -- **Visibility challenges:** Cloud environments suffer from a lack of visibility that makes it difficult to secure their complex infrastructure. -- **Data volume challenges:** Cloud environments can generate a high volume of logs forcing security teams to make trade-offs when it comes to data ingest cost and visibility. -- **Multi-cloud challenges:** Many organizations use multiple cloud platforms causing visibility challenges across platforms. +- **Visibility challenges:** Cloud environments do not give enough visibility. This makes their infrastructure difficult to secure. +- **Data volume challenges:** Cloud environments can generate many logs. Security teams must then accept trade-offs between the cost to ingest data and visibility. +- **Multi-cloud challenges:** Many organizations use more than one cloud platform. This makes visibility across the platforms difficult. ## LimaCharlie's solution -LimaCharlie simplifies management of cloud and multi-cloud environments by unifying them on a single platform. In addition to making integrations easier and bringing scalability to security operations, the Agentic SecOps Workspace offers: +LimaCharlie unifies cloud and multi-cloud environments on a single platform, which makes them easier to manage. The Agentic SecOps Workspace also makes integrations easier, adds scale to security operations, and gives you: -- **Centralized monitoring:** The LimaCharlie Agentic SecOps Workspace offers a unified view across cloud environments that gives users granular visibility into their operation and current state. -- **Highly efficient storage:** LimaCharlie's proprietary high performance storage reduces the complexity and cost associated with long term data retention. All data ingested and alerts generated include a full year of searchable data retention to meet regulatory compliance and security requirements. -- **Platform-independence:** LimaCharlie is platform-independent and can ingest log data from any cloud platform or SaaS application with log retention often cheaper than the cloud vendors themselves. +- **Centralized monitoring:** The LimaCharlie Agentic SecOps Workspace gives one view across cloud environments. Users see the operation and the current state of each environment in detail. +- **Highly efficient storage:** The proprietary high-performance storage of LimaCharlie decreases the complexity and cost of long-term data retention. All data that you ingest and all alerts that LimaCharlie generates include one full year of searchable retention. This retention meets regulatory compliance and security needs. +- **Platform-independence:** LimaCharlie is platform-independent. It can ingest log data from any cloud platform or SaaS application. Log retention is often cheaper than retention from the cloud vendors. diff --git a/docs/1-getting-started/use-cases/cost-effective-siem.md b/docs/1-getting-started/use-cases/cost-effective-siem.md index 4a1621c51..bcbe9487a 100644 --- a/docs/1-getting-started/use-cases/cost-effective-siem.md +++ b/docs/1-getting-started/use-cases/cost-effective-siem.md @@ -1,20 +1,20 @@ # Cost Effective SIEM Alternative -LimaCharlie's Agentic SecOps Workspace provides a cost-effective and flexible alternative or supplement to traditional Security Information and Event Management (SIEM) offering essential capabilities while addressing the challenges of high costs, vendor lock-in, and complexity. By leveraging LimaCharlie's interoperability, automation, and detection and response () capabilities, security teams can optimize their operations and maintain a robust posture without the high costs and limitations of legacy SIEM solutions. +The Agentic SecOps Workspace is a low-cost and flexible alternative or supplement to a traditional Security Information and Event Management (SIEM) system. It gives the necessary capabilities, but avoids high costs, vendor lock-in, and complexity. With the interoperability, automation, and detection and response capabilities of LimaCharlie, security teams can improve their operations. They keep a strong security posture without the costs and limits of legacy SIEM solutions. ## SIEM problems -The capabilities of SIEM solutions are essential for managing logs, correlating events, monitoring and alerting, and storing telemetry data. However, traditional SIEMs often present several challenges for organizations: +The capabilities of a SIEM solution are necessary to manage logs, correlate events, monitor and alert, and store telemetry data. But traditional SIEMs cause several problems for organizations: -- **High costs:** SIEMs are typically very expensive to implement and maintain, with costs escalating as data volumes grow and additional features are required. -- **Vendor lock-in:** Many SIEMs are proprietary, closed systems that make it difficult for organizations to switch providers or integrate with other security tools. -- **Complexity:** SIEMs can be complex to set up and manage, requiring specialized skills and resources that may strain already overburdened security teams. +- **High costs:** SIEMs are usually expensive to set up and to maintain. The costs increase as data volumes grow and as you need more features. +- **Vendor lock-in:** Many SIEMs are proprietary, closed systems. They make it difficult for an organization to change providers or to integrate other security tools. +- **Complexity:** SIEMs can be difficult to set up and manage. They need special skills and resources, which can strain a security team that is already overloaded. ## LimaCharlie's solution -LimaCharlie's Agentic SecOps Workspace offers a cost-effective alternative to traditional SIEMs, providing essential capabilities while addressing the challenges of high costs, vendor lock-in, and complexity: +The Agentic SecOps Workspace is a low-cost alternative to a traditional SIEM. It gives the necessary capabilities, but avoids high costs, vendor lock-in, and complexity: -- **Cost savings through flexible data management:** LimaCharlie provides one year of free telemetry storage in a fully searchable format, reducing the need to store all data in expensive SIEMs. The platform's ability to classify, filter, and route telemetry data intelligently allows organizations to send only critical data to their SIEM, further reducing costs. -- **Interoperability and customization:** Built with interoperability in mind, LimaCharlie seamlessly integrates with a wide range of security tools and platforms, enabling organizations to create custom workflows and avoid vendor lock-in. The platform's open architecture and extensive API support make it easy to integrate with existing security infrastructure. -- **Automation and ease of use:** LimaCharlie's Detection, Automation, and Response Engine enables security teams to create sophisticated detection rulesets and automate response actions, reducing alert fatigue and simplifying security operations. The Agentic SecOps Workspace's powerful query language (LCQL) makes it easy for security professionals to access and analyze telemetry data without the complexity of traditional SIEMs. -- **Advanced capabilities:** LimaCharlie offers advanced threat hunting and integration with third-party threat intelligence platforms, providing security teams with the context and insights they need to identify and respond to threats effectively. +- **Cost savings through flexible data management:** LimaCharlie gives one year of free telemetry storage in a fully searchable format. You do not have to keep all data in an expensive SIEM. The platform can classify, filter, and route telemetry data, so an organization sends only critical data to its SIEM. This decreases costs more. +- **Interoperability and customization:** LimaCharlie is built for interoperability and integrates with many security tools and platforms. An organization can build custom workflows and avoid vendor lock-in. The open architecture and the API support of the platform make integration with existing security infrastructure easier. +- **Automation and ease of use:** The Detection, Automation, and Response Engine lets security teams write detection rulesets and automate response actions. This decreases alert fatigue and makes security operations less complex. The query language of the Agentic SecOps Workspace (LCQL) lets security professionals access and analyze telemetry data without the complexity of a traditional SIEM. +- **Advanced capabilities:** LimaCharlie supplies threat hunting and integration with third-party threat intelligence platforms. Security teams get the context and the information that they need to identify threats and respond to them. diff --git a/docs/1-getting-started/use-cases/cti-capabilities.md b/docs/1-getting-started/use-cases/cti-capabilities.md index 488113a9f..439b4376d 100644 --- a/docs/1-getting-started/use-cases/cti-capabilities.md +++ b/docs/1-getting-started/use-cases/cti-capabilities.md @@ -1,16 +1,16 @@ # Build CTI Capabilities -Ready to ditch the data silos and blind spots? LimaCharlie empowers you with a centralized intelligence hub, seamless integrations, BinLib, your own private VirusTotal-like solution, and the unparalleled precision of YARA scanning. Gain a comprehensive understanding of the threat landscape, proactively hunt for hidden attackers, and build a resilient security posture that leaves no stone unturned in the fight against malware**.** +LimaCharlie gives you a central intelligence hub, integrations, and BinLib, which is your own private solution similar to VirusTotal. It also gives you YARA scanning with high precision. With these capabilities you can understand the threat landscape, hunt for hidden attackers, and build a strong security posture against malware. ## Cyber threat intelligence (CTI) gathering problems -- **Fragmented and siloed data:** Security teams often struggle to gain a holistic understanding of threats due to siloed data from disparate security tools and sensors. This fragmented intelligence hinders effective threat detection, investigation, and response. -- **Manual correlation:** Manually correlating data points from diverse sources is time-consuming and error-prone, making it difficult to identify emerging threats and uncover hidden connections. -- **Visibility gaps:** Unknown malware and suspicious binaries often fly under the radar of traditional antivirus solutions, leaving organizations vulnerable to zero-day attacks and advanced threats. +- **Fragmented and siloed data:** Security teams find it difficult to understand threats fully, because the data is siloed in separate security tools and sensors. This fragmented intelligence makes threat detection, investigation, and response less effective. +- **Manual correlation:** Manual correlation of data points from different sources takes much time and causes errors. This makes it difficult to identify new threats and to find hidden connections. +- **Visibility gaps:** Traditional antivirus solutions often do not detect unknown malware and suspicious binaries. This leaves organizations vulnerable to zero-day attacks and advanced threats. ## LimaCharlie's solution -- **Data consolidation:** Aggregate telemetry from all your security tools, endpoints, and network sources into a single platform. LimaCharlie's comprehensive data ingestion capabilities break down data silos and unify your threat intelligence landscape. -- **Seamless integrations:** Leverage LimaCharlie's robust API integrations to seamlessly connect with external threat feeds, threat intelligence platforms, and security tools. Enrich your internal data with external insights for a broader view of the threat landscape. -- **Private binary library:** Analyze unknown binaries and suspicious files with LimaCharlie's built-in Binary Library. This private VirusTotal-like environment leverages community and internal threat intelligence to rapidly identify malware, even zero-day variants, and assess associated risks. -- **Utilize YARA rules:** Conduct enterprise-wide malware scanning with LimaCharlie's integrated YARA engine. Utilize your own or community-developed YARA rules to detect specific malware families, variants, and even customized threats tailored to your environment, leaving no malicious code undetected. +- **Data consolidation:** Collect telemetry from all your security tools, endpoints, and network sources into one platform. The data ingestion capabilities of LimaCharlie remove data silos and unify your threat intelligence. +- **Integrations:** Use the API integrations of LimaCharlie to connect to external threat feeds, threat intelligence platforms, and security tools. Enrich your internal data with external information for a wider view of the threat landscape. +- **Private binary library:** Analyze unknown binaries and suspicious files with the built-in Binary Library. This private environment is similar to VirusTotal. It uses community and internal threat intelligence to identify malware quickly, including zero-day variants, and to assess the related risks. +- **Use YARA rules:** Scan for malware across the enterprise with the integrated YARA engine of LimaCharlie. Use your own YARA rules or community rules to detect specific malware families, variants, and threats that are specific to your environment. diff --git a/docs/1-getting-started/use-cases/devops-security.md b/docs/1-getting-started/use-cases/devops-security.md index e4ad0ef61..8b70f93a9 100644 --- a/docs/1-getting-started/use-cases/devops-security.md +++ b/docs/1-getting-started/use-cases/devops-security.md @@ -1,18 +1,18 @@ # Security Monitoring for DevOps -Ditch the data silos and sluggish response – LimaCharlie illuminates your DevOps pipeline, automates threat detection and response, and fosters real-time collaboration, empowering you to build secure and resilient software at record speed. +LimaCharlie gives visibility into your DevOps pipeline, automates threat detection and response, and supports collaboration in real time. With this data you can build secure and resilient software quickly. ## Problems monitoring DevOps security -- **Blind Spots in the Pipeline:** Siloed DevOps data from code repositories, third-party tools, and SaaS platforms leaves security teams in the dark, unable to detect threats hidden within routine operations. -- **Reactive Response, Slowed Agility:** Manual security checks and sluggish incident response hinder DevOps agility, creating vulnerable gaps between development and deployment. -- **DevSecOps Disconnect:** Disparate tools and fragmented communication between security and operations teams lead to inefficient incident response and missed opportunities for proactive mitigation. +- **Blind Spots in the Pipeline:** DevOps data stays siloed in code repositories, third-party tools, and SaaS platforms. Security teams cannot see this data, so they do not detect the threats that hide in routine operations. +- **Reactive Response, Slowed Agility:** Manual security checks and slow incident response decrease DevOps agility. They also create vulnerable gaps between development and deployment. +- **DevSecOps Disconnect:** Security teams and operations teams use different tools and do not communicate well. This makes incident response inefficient and causes missed opportunities to mitigate threats early. ## LimaCharlie's solution -- **Unified Visibility Across the Flow:** LimaCharlie's architecture effortlessly ingests telemetry from all your DevOps data sources, providing a unified view of your entire pipeline from code commits to production deployments. -- **Automated Threat Detection and Response:** Leverage LimaCharlie's pre-built and custom detection rules to automatically identify suspicious activities within your DevOps data. Trigger instant alerts and pre-defined response actions, including stopping deployments, rolling back changes, or notifying teams. -- **Centralized Collaboration for Faster Response:** Break down silos with LimaCharlie's collaborative platform. Security and operations teams can visualize incidents across the pipeline, analyze threats jointly, and orchestrate coordinated responses in real-time. +- **Unified Visibility Across the Flow:** The architecture of LimaCharlie ingests telemetry from all your DevOps data sources. It gives one view of the full pipeline, from code commits to production deployments. +- **Automated Threat Detection and Response:** Use the pre-built and custom detection rules of LimaCharlie to identify suspicious activity in your DevOps data automatically. The rules send immediate alerts and start pre-defined response actions. These actions can stop a deployment, roll back changes, or notify teams. +- **Centralized Collaboration for Faster Response:** Remove silos with the collaborative platform of LimaCharlie. Security teams and operations teams can see incidents across the pipeline, analyze threats together, and coordinate their response in real time. ## What's Next diff --git a/docs/1-getting-started/use-cases/edr.md b/docs/1-getting-started/use-cases/edr.md index 786305619..59a99e766 100644 --- a/docs/1-getting-started/use-cases/edr.md +++ b/docs/1-getting-started/use-cases/edr.md @@ -1,19 +1,19 @@ # Endpoint Detection and Response (EDR) -The Agentic SecOps Workspace, revolutionizes endpoint security by providing true real-time visibility, versatile detection capabilities, integration with open-source and managed rulesets, and vendor-agnostic telemetry ingestion. By leveraging LimaCharlie's API-first approach, flexible billing model, and seamless integration with your existing security stack, security teams can effectively detect, investigate, and respond to threats while avoiding the limitations of traditional EDR solutions. +The Agentic SecOps Workspace gives true real-time visibility, many detection capabilities, integration with open-source and managed rulesets, and vendor-agnostic telemetry ingestion. LimaCharlie uses an API-first approach and a flexible billing model, and it integrates with your existing security stack. With these capabilities, security teams can detect, investigate, and respond to threats without the limits of a traditional EDR solution. ## EDR problems -Endpoint Detection and Response (EDR) solutions are crucial for organizations to detect, investigate, and respond to threats on endpoints. However, traditional EDR solutions often present several challenges: +Endpoint Detection and Response (EDR) solutions let an organization detect, investigate, and respond to threats on endpoints. But traditional EDR solutions cause several problems: -- **Lack of real-time visibility:** Many EDR solutions rely on periodic scans or delayed data collection, making it difficult to detect and respond to threats in real-time. -- **Limited customization and flexibility:** Traditional EDRs often use proprietary detection languages or rulesets, limiting the ability of security teams to create custom detections tailored to their unique environments. -- **Vendor lock-in and high costs:** Legacy EDR solutions often require long-term contracts, have high minimum commitments, and can be expensive to scale, leading to vendor lock-in and budget constraints. +- **Lack of real-time visibility:** Many EDR solutions use periodic scans or collect data with a delay. This makes it difficult to detect threats and to respond to them in real time. +- **Limited customization and flexibility:** Traditional EDRs often use proprietary detection languages or rulesets. This limits the ability of a security team to write custom detections for its own environment. +- **Vendor lock-in and high costs:** Legacy EDR solutions often need long-term contracts and high minimum commitments. They can be expensive to scale, which causes vendor lock-in and budget constraints. ## LimaCharlie's solution -- **True real-time EDR:** LimaCharlie provides true real-time visibility by streaming verbose telemetry from the endpoint sensor to the cloud over a semi-persistent TLS connection. This enables response actions to be taken on the endpoint within 100ms of the triggering action or behavior, drastically reducing the time to detect and respond to threats. -- **Versatile detection syntax:** LimaCharlie uses a YAML-based detection syntax that allows security teams to create highly sophisticated detections, including the ability to track state and build multi-step detection logic. This versatile syntax empowers security teams to create custom detections tailored to their specific needs and environment. -- **Integration with open-source and managed rulesets:** Leverage detections created by best-in-class security professionals using managed and open-source rulesets. With one-click access to sources like SOC Prime, Soteria, Sigma, and YARA, teams can gain unparalleled cost efficiencies and stay ahead of emerging threats. -- **Reduced mean time to respond (MTTR):** LimaCharlie allows security teams to execute a full suite of remediation responses, such as triggering memory dumps or killing process trees. By simplifying the process of activating rulesets and building custom rules, LimaCharlie significantly reduces MTTR. -- **Vendor-agnostic telemetry ingestion:** Ingest data from any source, including existing EDR solutions, in real-time. This allows security teams to avoid vendor lock-in and leverage the ASW's powerful Detection, Automation, and Response Engine on all of their telemetry, regardless of the source. +- **True real-time EDR:** LimaCharlie streams verbose telemetry from the endpoint sensor to the cloud over a semi-persistent TLS connection. This gives true real-time visibility. The endpoint can do a response action within 100ms of the action or behavior that triggers it. This decreases the time to detect threats and to respond to them. +- **Versatile detection syntax:** LimaCharlie uses a detection syntax that is based on YAML. Security teams can write complex detections, track state, and build detection logic with multiple steps. With this syntax, a team writes custom detections for its own needs and environment. +- **Integration with open-source and managed rulesets:** Use the detections that security professionals write in managed and open-source rulesets. Sources such as SOC Prime, Soteria, Sigma, and YARA are available with one click. Teams decrease their costs and respond to new threats sooner. +- **Reduced mean time to respond (MTTR):** Security teams can run a full set of remediation responses with LimaCharlie. Examples are a memory dump and a kill of a process tree. LimaCharlie makes it easier to activate rulesets and to build custom rules, which decreases MTTR. +- **Vendor-agnostic telemetry ingestion:** Ingest data from any source in real time, including existing EDR solutions. Security teams avoid vendor lock-in. They can use the Detection, Automation, and Response Engine of the ASW on all of their telemetry, from any source. diff --git a/docs/1-getting-started/use-cases/enterprises.md b/docs/1-getting-started/use-cases/enterprises.md index d6480ed90..61e8c7a93 100644 --- a/docs/1-getting-started/use-cases/enterprises.md +++ b/docs/1-getting-started/use-cases/enterprises.md @@ -2,54 +2,56 @@ The LimaCharlie Agentic SecOps Workspace (ASW) is a unified platform for modern cybersecurity operations. -The ASW delivers core cybersecurity capabilities and infrastructure via a public cloud model: on-demand, pay-per-use, and API-first. For the cybersecurity industry, this is a paradigm shift comparable to how the IT public cloud revolutionized IT. +The ASW supplies core cybersecurity capabilities and infrastructure through a public cloud model: on-demand, pay-per-use, and API-first. For the cybersecurity industry, this is a large change, comparable to the change that the IT public cloud made in IT. -For enterprises and other large organizations, the Agentic SecOps Workspace is a powerful way to take control of security posture and scale operations. The ASW can help teams gain visibility into their environments, eliminate coverage gaps, solve integration challenges, reduce spending on high-cost tools, free themselves from vendor lock-in, and build custom security solutions to meet their organization's unique needs. +For enterprises and other large organizations, the Agentic SecOps Workspace is a way to control security posture and to scale operations. The ASW helps teams see their environments, remove coverage gaps, and solve integration problems. It also helps them decrease spending on high-cost tools, avoid vendor lock-in, and build custom security solutions for their organization. ## 3 implementation plans for immediate value -The Agentic SecOps Workspace is a comprehensive platform for cybersecurity operations—but it doesn't have to be implemented all at once. The ASW's public cloud-like delivery model eliminates adoption hurdles for enterprises. Easily scaled and API-first, the ASW enables teams to integrate the platform into their security operations gradually, leveraging its capabilities progressively as they go. Here are three recommended first steps to help enterprises realize value from the ASW quickly. +The Agentic SecOps Workspace is a platform for cybersecurity operations, but you do not have to set up all of it at one time. The delivery model of the ASW is similar to a public cloud, which removes the barriers to adoption for an enterprise. The ASW scales and is API-first. Teams can therefore integrate the platform into their security operations in stages, and use more of its capabilities with time. These are three recommended first steps that help an enterprise get value from the ASW quickly. ### 1. Centralize telemetry data to improve visibility and streamline operations -The Agentic SecOps Workspace allows enterprises to bring all of their telemetry data into one place—improving visibility, eliminating coverage gaps, and enabling streamlined SecOps workflows. Here is a general outline of what that looks like: +The Agentic SecOps Workspace lets an enterprise bring all of its telemetry data into one place. This improves visibility, removes coverage gaps, and makes SecOps workflows more efficient. This is a general outline of the process: -**Bring your telemetry data into the ASW.** The Agentic SecOps Workspace allows enterprise teams to ingest data from any source. The platform's endpoint detection and response (EDR)-type sensors can be deployed directly on Windows, Mac, and Linux endpoints with full feature parity across these OSes. These sensors allow security teams to capture system events and other telemetry data in real time—or import event data from third-party EDR tools such as VMWare Carbon Black, CrowdStrike, SentinelOne, or Microsoft Defender. There are also browser-based EDR sensors to support Chrome and Edge deployments. +**Bring your telemetry data into the ASW.** The Agentic SecOps Workspace lets enterprise teams ingest data from any source. You can deploy the endpoint detection and response (EDR) sensors of the platform on Windows, Mac, and Linux endpoints with full feature parity. With these sensors, security teams capture system events and other telemetry data in real time. Teams can also import event data from third-party EDR tools such as VMWare Carbon Black, CrowdStrike, SentinelOne, or Microsoft Defender. Browser-based EDR sensors are also available for Chrome and Edge deployments. -Log-type data can also be brought into the ASW using a system of adapters or via webhook. Supported log data sources include O365, 1Password, AWS CloudTrail, Google Cloud Platform (GCP), Slack Audit logs, and many more. For a comprehensive list, refer to the ASW documentation. +You can also bring log data into the ASW with a system of adapters or through a webhook. Supported log data sources include O365, 1Password, AWS CloudTrail, Google Cloud Platform (GCP), Slack Audit logs, and many more. For a full list, refer to the ASW documentation. -**Visualize and manage your telemetry data under a single plane.** Telemetry data brought into the ASW is normalized to a common JSON format and explorable through a single interface. The immediate advantage for security teams is improved visibility—and an end to coverage gaps that can jeopardize organizational security and compliance. In addition, the ability to manipulate data through a single UI helps teams eliminate integration challenges caused by other solutions and streamline their internal workflows. +**Visualize and manage your telemetry data under a single plane.** The ASW normalizes the telemetry data to a common JSON format, and you explore the data through one interface. The immediate advantage for security teams is better visibility and an end to the coverage gaps that put organizational security and compliance at risk. One interface to manipulate data also helps teams remove the integration problems that other solutions cause and make their internal workflows more efficient. -**Go beyond observability.** The Agentic SecOps Workspace's data-routing capabilities mean that it can be used as a simple observability point solution if you choose. But the ASW is capable of far more than this. All telemetry data brought into the platform can be run through an advanced detection and response engine, and wire-speed response actions can be taken on endpoints via the multiplatform ASW agent. From day one, security teams using the ASW for centralization and observability can also apply their own custom detection and response (D&R) logic to all telemetry data brought into the platform, leverage curated rulesets like Sigma, Soteria, or SOC Prime rules for the same purpose, or run historical threat hunts against data stored in the ASW. +**Go beyond observability.** The data-routing capabilities of the Agentic SecOps Workspace let you use it as an observability point solution, but the ASW can do much more. All telemetry data in the platform can go through an advanced detection and response engine. The multiplatform ASW sensor also does response actions on endpoints at wire speed. -The Agentic SecOps Workspace helps enterprises improve visibility, eliminate coverage gaps, solve integration challenges, and make their workflows more efficient—and this is just the first step in what teams can achieve with the platform. +From the first day, security teams can use the ASW for centralization and observability. They can also apply their own custom detection and response (D&R) logic to all telemetry data in the platform. They can use curated rulesets such as Sigma, Soteria, or SOC Prime rules for the same purpose. They can also run historical threat hunts against the data that the ASW stores. + +The Agentic SecOps Workspace helps an enterprise improve visibility, remove coverage gaps, solve integration problems, and make workflows more efficient. This is only the first step of what a team can do with the platform. #### 2. Reduce spending on SIEMs and other high-cost solutions -Because the ASW lets security teams bring in data from any source and export it to any destination, the platform can also be used as a pass-through to observe, transform, enrich, and anonymize data in-flight and route it to different destinations in a fine-grained way. This strategy can significantly reduce the costs of security information and event management (SIEM) tools and other expensive third-party solutions. +The ASW lets security teams bring in data from any source and export it to any destination. You can therefore use the platform as a pass-through to observe, transform, enrich, and anonymize data in flight. You can also route the data to different destinations in detail. This strategy can decrease the costs of security information and event management (SIEM) tools and other expensive third-party solutions. -**Identify inefficiencies in your current data flow.** Many organizations simply send 100% of their telemetry data to their SIEM. They only use a fraction of that data, but they pay for all of it. Conduct a thorough review of how you are currently routing your telemetry data. Determine what data truly needs to be sent to your highest-cost tools—and what can be retained in lower-cost storage. +**Identify inefficiencies in your current data flow.** Many organizations send 100% of their telemetry data to their SIEM. They use only a fraction of that data, but they pay for all of it. Review how you route your telemetry data now. Decide which data must go to your highest-cost tools, and which data can stay in lower-cost storage. -**Use the ASW's output controls to optimize your data routing.** Your options here are highly flexible and customizable: +**Use the ASW's output controls to optimize your data routing.** The options are flexible and customizable: -Telemetry data can be sent to Splunk, Humio, Elastic, Amazon S3 buckets, Azure Event Hubs, Google Cloud Storage, and many other destinations. +You can send telemetry data to Splunk, Humio, Elastic, Amazon S3 buckets, Azure Event Hubs, Google Cloud Storage, and many other destinations. -Data can also be streamed to your destination(s) of choice with different degrees of granularity. On the more verbose end of the spectrum, it is possible to send all data events from a sensor to a given destination. But you can also create a tailored stream that sends only specific events to your output destination. +You can also stream data to your destinations with different levels of granularity. At the most verbose level, you send all data events from a sensor to one destination. You can also create a stream that sends only specific events to your output destination. -Enterprise teams can thus route their data for optimal cost savings. For example, a team might send only high-priority detections and failed 1Password login attempts to Splunk, a secondary tranche of log data and events to an Amazon S3 bucket, and retain everything else in low-cost cold storage. +Enterprise teams can thus route their data for the best cost savings. For example, a team can send only high-priority detections and failed 1Password login attempts to Splunk. It can send a second set of log data and events to an Amazon S3 bucket, and keep all other data in low-cost cold storage. -**Use free storage and transparent pricing for compliance and additional savings.** The ASW offers one year of free storage of all telemetry data for the cost of ingestion. Pricing is transparent and easy to calculate, making it simple to determine the most cost-effective data flow and storage sites for your telemetry. All telemetry data is retained for one year by default in a fully searchable and explorable format, so you don't have to worry about losing data that you may need later on. Because the total cost of storage in the ASW cloud is often far more affordable than traditional data lakes, many organizations will be able to use the platform's built-in storage to address compliance requirements and reduce costs. +**Use free storage and transparent pricing for compliance and additional savings.** The ASW gives one year of free storage of all telemetry data for the cost of ingestion. The pricing is transparent and easy to calculate, so you can find the most cost-effective data flow and storage sites for your telemetry. By default, the ASW keeps all telemetry data for one year in a fully searchable and explorable format. The total cost of storage in the ASW cloud is often much lower than the cost of a traditional data lake. Many organizations can therefore use the built-in storage of the platform to meet compliance requirements and decrease costs. -The ASW's data routing capabilities put enterprise teams in full control of their telemetry data, allowing them to cut spending on high-cost solutions while ensuring access to critical data in order to meet compliance and operational needs. +The data routing capabilities of the ASW give enterprise teams full control of their telemetry data. Teams decrease spending on high-cost solutions and keep access to the critical data that compliance and operations need. #### 3. Simplify tooling and control your infrastructure -The Agentic SecOps Workspace delivers the core components required to secure and monitor any organization. Over time, enterprises can leverage the ASW's numerous capabilities to develop a custom security infrastructure that they control completely. And while that is clearly a long-term project, enterprises that adopt the ASW can begin using the platform to simplify their stack right away: +The Agentic SecOps Workspace supplies the core components that secure and monitor an organization. With time, an enterprise can use the many capabilities of the ASW to build a custom security infrastructure that it controls fully. That is a long-term project, but an enterprise that adopts the ASW can start to make its stack simpler immediately: -**Replace one-off solutions.** The increasing specialization of cybersecurity products means most enterprise teams rely on a patchwork of solutions—and are sometimes forced to buy a tool to satisfy one, extremely narrow use case. Teams should begin by identifying their one-off tools and vendors and determining how they can be replaced with an ASW solution. The Agentic SecOps Workspace offers a rich ecosystem of 100+ cybersecurity capabilities and integrations and a marketplace of add-ons to extend the platform. In many cases, teams will find that it is possible to replace single-use vendors with an ASW solution that offers equal or better performance, reducing tool sprawl and improving security operations at the same time. +**Replace one-off solutions.** Cybersecurity products become more specialized, so most enterprise teams use a patchwork of solutions and sometimes buy a tool for one narrow use case. First, identify your one-off tools and vendors. Then decide how an ASW solution can replace each one. The Agentic SecOps Workspace has an ecosystem of more than 100 cybersecurity capabilities and integrations, and a marketplace of add-ons that extend the platform. In many cases, an ASW solution replaces a single-use vendor with equal or better performance, which decreases tool sprawl and improves security operations. -**Upgrade existing tools or features.** The fragmentation of the current cybersecurity vendor space means that many enterprise teams end up using tools that excel in one arena but fall short in others. Instead of simply accepting the unsatisfactory parts of their stack, teams can use the ASW to augment or replace underperforming tools and features with best-in-breed alternatives. +**Upgrade existing tools or features.** The cybersecurity vendor space is fragmented, so many enterprise teams use tools that are good in one area but weak in others. Do not accept the weak parts of your stack. Use the ASW to supplement or replace the tools and features that perform badly. -**Begin your transition to infrastructure independence.** After teams shed one-off and redundant tools, they should begin to think strategically about how to leverage the ASW to free themselves from vendor lock-in once and for all. Look for vendor contracts due to expire or products nearing end-of-life and work with LimaCharlie engineers to develop, validate, and deploy a custom replacement ahead of time. +**Begin your transition to infrastructure independence.** After a team removes its one-off and redundant tools, it must plan how to use the ASW to end vendor lock-in. Look for vendor contracts that expire soon and for products that are near end-of-life. Work with LimaCharlie engineers to build, validate, and deploy a custom replacement before that date. -In the near term, the Agentic SecOps Workspace lets enterprises simplify their deployments significantly. In the long term, it allows organizations to take full control of their tooling, infrastructure, and security posture. +In the near term, the Agentic SecOps Workspace lets an enterprise make its deployments much simpler. In the long term, it lets an organization take full control of its tooling, infrastructure, and security posture. diff --git a/docs/1-getting-started/use-cases/fim.md b/docs/1-getting-started/use-cases/fim.md index 3d7b7d813..3b94b96f0 100644 --- a/docs/1-getting-started/use-cases/fim.md +++ b/docs/1-getting-started/use-cases/fim.md @@ -1,17 +1,17 @@ # File and Registry Integrity Monitoring (FIM) Deployments -Use the Agentic SecOps Workspace to gain comprehensive visibility, control, and proactive protection for sensitive files and registry keys with LimaCharlie's robust FIM capabilities. +Use the Agentic SecOps Workspace and the FIM capabilities of LimaCharlie to monitor sensitive files and registry keys. You get visibility into these objects, control of them, and early protection. ## FIM deployment problems -- **Undetected unauthorized changes:** Malicious actors often target sensitive files and registry keys to install malware, exfiltrate data, or disrupt operations, often evading traditional security measures. -- **Challenges of manual monitoring:** Manually tracking changes to critical files and registry entries across large environments is time-consuming, error-prone, and often reactive rather than proactive. -- **Limited visibility into past events:** Traditional FIM tools might lack comprehensive historical data storage, hindering investigations and threat hunting efforts. -- **Fragmented solutions:** File and registry integrity monitoring can be siloed in separate platforms or integrated with data loss prevention (DLP) tools, lacking the comprehensive visibility and detection capabilities of a unified security platform. +- **Undetected unauthorized changes:** Malicious actors often attack sensitive files and registry keys to install malware, exfiltrate data, or interrupt operations. Traditional security measures often do not detect these changes. +- **Challenges of manual monitoring:** Manual tracking of changes to critical files and registry entries across a large environment takes much time and causes errors. The work is also reactive, not proactive. +- **Limited visibility into past events:** Traditional FIM tools can store too little historical data. This makes investigations and threat hunting difficult. +- **Fragmented solutions:** File and registry integrity monitoring can be siloed in a separate platform or integrated with a data loss prevention (DLP) tool. These tools do not give the visibility and the detection capabilities of one unified security platform. ## LimaCharlie's solution -- **Unified Visibility and Response:** Consolidate FIM with other endpoint detection and response (EDR) capabilities within LimaCharlie, eliminating the need for separate platforms and streamlining security operations. -- **Continuous Monitoring and Alerting:** LimaCharlie's FIM capability continuously monitors designated files and registry keys for any modifications, generating real-time alerts to security teams for immediate action. -- **Granular Configuration and Rules:** Define specific files, directories, and registry paths to monitor based on your unique security needs, ensuring focused protection for critical assets. -- **Historical Data Storage and Analysis:** LimaCharlie stores one year of historical FIM data, enabling in-depth investigations, threat hunting, and identification of potential attack patterns that might have been missed initially. +- **Unified Visibility and Response:** Combine FIM with the other endpoint detection and response (EDR) capabilities in LimaCharlie. You do not need a separate platform, and your security operations become more efficient. +- **Continuous Monitoring and Alerting:** The FIM capability of LimaCharlie monitors the selected files and registry keys for changes. It sends real-time alerts to security teams, who can then act immediately. +- **Granular Configuration and Rules:** Select the files, directories, and registry paths to monitor for your own security needs. This keeps the protection on your critical assets. +- **Historical Data Storage and Analysis:** LimaCharlie stores one year of historical FIM data. With this data you can do detailed investigations, hunt for threats, and identify the attack patterns that you did not detect at first. diff --git a/docs/1-getting-started/use-cases/incident-response.md b/docs/1-getting-started/use-cases/incident-response.md index 75fe985fc..4c24d1c70 100644 --- a/docs/1-getting-started/use-cases/incident-response.md +++ b/docs/1-getting-started/use-cases/incident-response.md @@ -1,21 +1,21 @@ # Incident Response -LimaCharlie provides incident response teams with a powerful, centralized solution that unifies threat visibility across diverse data sources, streamlines detection capabilities, enhances threat hunting and analysis, and enables instant deployment. IR teams can respond to incidents with unparalleled speed, accuracy, and effectiveness. +LimaCharlie gives incident response teams one centralized solution. It unifies threat visibility across different data sources, makes detection easier, improves threat hunting and analysis, and deploys immediately. IR teams can respond to incidents with speed and accuracy. ## Incident response problems -- **Limited visibility and data correlation:** Incident response teams often face incomplete or fragmented data from clients, hindering their ability to grasp the full extent of an incident and make informed analysis. -- **Time-consuming manual analysis:** Manually sifting through large volumes of logs, alerts, and endpoint data can be time-consuming and prone to human error, delaying incident response and remediation. -- **Lack of centralized threat hunting capabilities:** Traditional IR toolkits often lack advanced analytics and threat hunting features, making it challenging to proactively uncover hidden threats or investigate complex attack patterns. -- **Slow infrastructure deployment:** Setting up traditional incident response infrastructure can take hours or even days, leaving critical time gaps where attackers have the upper hand. +- **Limited visibility and data correlation:** Incident response teams often get incomplete or fragmented data from clients. The teams cannot then see the full extent of an incident or make an informed analysis. +- **Time-consuming manual analysis:** Manual examination of large volumes of logs, alerts, and endpoint data takes much time and causes human errors. This delays incident response and remediation. +- **Lack of centralized threat hunting capabilities:** Traditional IR toolkits often have no advanced analytics or threat hunting features. It is then difficult to find hidden threats early or to investigate complex attack patterns. +- **Slow infrastructure deployment:** Setup of traditional incident response infrastructure can take hours or days. During this time, the attacker has the advantage. ## LimaCharlie's solution -- **Unified Threat Visibility:** LimaCharlie aggregates data from diverse sources (endpoints, networks, cloud environments, security tools), providing incident response teams with centralized visibility and context for swift analysis. -- **Streamlined Detection Capabilities:** The platform's powerful detection and response capabilities allow IR teams to quickly pinpoint relevant data, identify patterns, and correlate events across multiple impacted systems. -- **Enhanced Threat Hunting and Analysis:** LimaCharlie's advanced analytics and threat intelligence feeds enable IR teams to proactively hunt for hidden threats, investigate attack chains, and attribute attacks with greater confidence. -- **Instant Deployment:** Launch LimaCharlie in seconds, not hours, gaining immediate visibility and control over the compromised environment to outpace attacker timelines and minimize damage. +- **Unified Threat Visibility:** LimaCharlie collects data from different sources: endpoints, networks, cloud environments, and security tools. Incident response teams get centralized visibility and context for a fast analysis. +- **Streamlined Detection Capabilities:** The detection and response capabilities of the platform let IR teams find the relevant data quickly. Teams identify patterns and correlate events across each system that the incident touches. +- **Enhanced Threat Hunting and Analysis:** The advanced analytics and threat intelligence feeds of LimaCharlie let IR teams hunt for hidden threats early. Teams investigate attack chains and attribute attacks with more confidence. +- **Instant Deployment:** Start LimaCharlie in seconds, not hours. You get immediate visibility into the compromised environment and control of it, so you act faster than the attacker and decrease the damage. ### Related Resources -- [Investigation Guide](investigation-guide.md) - Best practices for documenting investigations with MITRE ATT&CK mapping and standardized tagging +- [Investigation Guide](investigation-guide.md) - Best practices to document investigations with MITRE ATT&CK mapping and standard tagging diff --git a/docs/1-getting-started/use-cases/investigation-guide.md b/docs/1-getting-started/use-cases/investigation-guide.md index 5243eba76..8670f5b5e 100644 --- a/docs/1-getting-started/use-cases/investigation-guide.md +++ b/docs/1-getting-started/use-cases/investigation-guide.md @@ -1,14 +1,14 @@ # Investigation Guide -This guide provides opinionated best practices for SOC analysts using LimaCharlie Investigations to document and encode security investigations. By following these conventions, you enable attack chain visualization, cross-investigation analysis, and consistent reporting. +This guide gives best practices for SOC analysts who use LimaCharlie Investigations to document and encode security investigations. These conventions make attack chain visualization, cross-investigation analysis, and consistent reports possible. ## Tag Format Specification -Use colon-separated tags to categorize events, detections, and entities within your timeline. This section defines the format patterns - actual values are either format-based (you define them) or fetched dynamically from authoritative sources. +Use colon-separated tags to categorize events, detections, and entities in your timeline. This section defines the format patterns. The values are either format-based, and you define them, or the tool reads them from authoritative sources at runtime. ### MITRE ATT&CK Tags (Dynamic) -MITRE ATT&CK tags should be validated against the authoritative MITRE STIX data rather than hardcoded lists. +Validate MITRE ATT&CK tags against the authoritative MITRE STIX data. Do not use hardcoded lists. **Authoritative Source:** @@ -19,7 +19,7 @@ MITRE ATT&CK tags should be validated against the authoritative MITRE STIX data | `phase:{tactic-name}` | Attack phase aligned with MITRE tactic | `phase:initial-access` | | `mitre:{technique-id}` | Specific MITRE ATT&CK technique | `mitre:T1566` | -**Fetching Valid Values at Runtime:** +**Get Valid Values at Runtime:** ```yaml URL: https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/enterprise-attack/enterprise-attack.json @@ -35,7 +35,7 @@ Parsing: ### Operational Tags (Format-Based) -These tags follow a consistent format pattern. You define the values based on your investigation context. +These tags use a consistent format pattern. You define the values from your investigation context. | Category | Format | Description | Examples | |----------|--------|-------------|----------| @@ -54,7 +54,7 @@ These tags follow a consistent format pattern. You define the values based on yo ## Attack Chain Visualization -Use `phase:` tags chronologically to visualize attack progression through MITRE ATT&CK tactics: +Use `phase:` tags in time order to show how the attack moves through MITRE ATT&CK tactics: ```text [phase:initial-access] → [phase:execution] → [phase:persistence] → [phase:credential-access] → [phase:lateral-movement] → [phase:exfiltration] @@ -68,7 +68,7 @@ Apply timing tags to key events: |-----|---------------| | `timing:first-observed` | Earliest confirmed malicious activity | | `timing:pivot-point` | Critical decision points in the attack chain | -| `timing:detection-trigger` | Event/detection that initiated the investigation | +| `timing:detection-trigger` | The event or detection that started the investigation | ### Example: Attack Chain Tags @@ -100,7 +100,7 @@ Apply timing tags to key events: ### IOC Provenance -Document how entities were discovered and validated in the `context` field: +In the `context` field, record how you found and validated each entity: **Pattern:** `Provenance: [how discovered]. Validation: [how confirmed]. Attribution: [threat intel correlation].` @@ -120,9 +120,9 @@ Document how entities were discovered and validated in the `context` field: | Verdict | Criteria | |---------|----------| | `malicious` | Confirmed IOC match, known-bad behavior, validated threat | -| `suspicious` | Anomalous but not definitively malicious, requires review | +| `suspicious` | Anomalous but not definitely malicious. Needs review | | `benign` | Cleared by investigation, legitimate activity | -| `unknown` | Insufficient context, further analysis needed | +| `unknown` | Not enough context. Needs more analysis | ### Entity Context Templates @@ -221,10 +221,10 @@ Defense gaps: [what failed] | Status | When to Use | |--------|-------------| -| `new` | Timeline just created, investigation not started | -| `in_progress` | Active investigation underway | -| `pending_review` | Analyst completed, awaiting peer review | -| `escalated` | Requires senior analyst or management attention | +| `new` | The timeline is created. The investigation is not started | +| `in_progress` | The investigation is active | +| `pending_review` | The analyst is finished. Peer review is pending | +| `escalated` | Needs the attention of a senior analyst or a manager | | `closed_false_positive` | Confirmed benign, documented rationale | | `closed_true_positive` | Confirmed incident, remediation complete | @@ -234,7 +234,7 @@ Defense gaps: [what failed] - [ ] Benign explanation documented in conclusion - [ ] Finding note with FP rationale -- [ ] Consider FP rule if pattern is common +- [ ] Decide if an FP rule is necessary, if the pattern is common **For `closed_true_positive`:** @@ -269,7 +269,7 @@ Attribution: Financially-motivated actor (medium confidence). ### Conclusion Field (Technical Closure) -Document technical determination: +Record the technical determination: ```text CLASSIFICATION: [true positive/false positive] - [incident type] @@ -284,7 +284,7 @@ CONTAINMENT: [status and date] ## Example: Complete Tagged Timeline -*Note: MITRE technique IDs shown are illustrative. Validate against the authoritative STIX source.* +*The MITRE technique IDs in this example are illustrative. Validate them against the authoritative STIX source.* ```json { @@ -370,7 +370,7 @@ CONTAINMENT: [status and date] ## Cross-Timeline Analysis -Consistent tagging enables searching across multiple investigations: +Consistent tags let you query across multiple investigations: | Search Goal | Tag Pattern to Query | |-------------|---------------------| diff --git a/docs/1-getting-started/use-cases/ma-due-diligence.md b/docs/1-getting-started/use-cases/ma-due-diligence.md index 921314f2b..0aeebcdd8 100644 --- a/docs/1-getting-started/use-cases/ma-due-diligence.md +++ b/docs/1-getting-started/use-cases/ma-due-diligence.md @@ -1,16 +1,16 @@ # M&A Cyber Due Diligence -LimaCharlie makes merger and acquisition (M&A) cyber due diligence cost-effective and easy to deploy, allowing you to only pay for the resources you need. However, our extensible platform allows you to add as many tools as needed, all within a single agent, streamlining the assessment process. +LimaCharlie makes cyber due diligence for a merger and acquisition (M&A) low in cost and quick to deploy. You pay only for the resources that you need. LimaCharlie is extensible, so you can add the tools that you need in one sensor. This reduces the work of the assessment. ## M&A problems -- **Inefficiencies in evaluating risks and vulnerabilities:** During the M&A process, it's crucial to identify and assess the cybersecurity risks associated with the target company's digital assets, including intellectual property, customer data, and financial information. -- **Complex infrastructures:** Merging two organizations' IT infrastructures can be a complex and time-consuming process which requires a smooth and secure integration of the acquired company's network into the parent company's infrastructure. -- **Limited visibility and control:** After the M&A process is complete, it's essential to continuously monitor and manage the merged organization's cybersecurity posture. +- **Inefficiencies in evaluating risks and vulnerabilities:** During the M&A process, you must find and assess the cybersecurity risks of the digital assets of the target company. These assets include intellectual property, customer data, and financial information. +- **Complex infrastructures:** A merger of the IT infrastructures of two organizations is complex and slow. The network of the acquired company must integrate securely into the infrastructure of the parent company. +- **Limited visibility and control:** After the M&A process is complete, you must monitor and manage the cybersecurity posture of the merged organization continuously. ## LimaCharlie's solution -- **Cost-effective and scalable:** LimaCharlie allows you to be a cost-effective, scalable solution to perform a compromise assessment on to-be-acquired networks, and evaluate pre-existing threats. -- **Continuous visibility and control:** Automated, detection-as-code integration with powerful rulesets like Sigma and YARA rules provide continuous visibility into the merged organization's infrastructure, enabling you to detect and respond to potential threats in real-time. -- **Integrate with any tool:** Our extensible platform allows you to customize your additional tools, all through a single agent, achieving maximum performance with minimal footprint. -- **Centralized telemetry:** LimaCharlie's centralized platform provides a single pane of glass for monitoring and managing the merged infrastructure, simplifying the integration process and reducing the risk of security gaps. +- **Cost-effective and scalable:** Use LimaCharlie to do a compromise assessment on the networks of a company that you plan to acquire. The assessment evaluates the threats that are already present. The cost is low and the assessment scales. +- **Continuous visibility and control:** Detection-as-code integrates automatically with rulesets such as Sigma and YARA. These rulesets give continuous visibility into the infrastructure of the merged organization. You can detect and respond to threats in real time. +- **Integrate with any tool:** LimaCharlie is extensible. You can add and configure more tools through one sensor, with high performance and a small footprint. +- **Centralized telemetry:** LimaCharlie gives one interface to monitor and manage the merged infrastructure. This makes the integration less complex and lowers the risk of gaps in security. diff --git a/docs/1-getting-started/use-cases/mssp-msp-mdr.md b/docs/1-getting-started/use-cases/mssp-msp-mdr.md index d3aa5c01d..e51f88b97 100644 --- a/docs/1-getting-started/use-cases/mssp-msp-mdr.md +++ b/docs/1-getting-started/use-cases/mssp-msp-mdr.md @@ -1,65 +1,65 @@ # Security Service Providers (MSSP, MSP, MDR) -The LimaCharlie Agentic SecOps Workspace (ASW) is a unified platform for modern cybersecurity operations. +The LimaCharlie Agentic SecOps Workspace (ASW) is a single platform for cybersecurity operations. -The ASW delivers core cybersecurity capabilities and infrastructure via a public cloud model: on-demand, pay-per-use, and API-first. For the cybersecurity industry, this is a paradigm shift comparable to how the IT public cloud revolutionized IT. +The ASW supplies cybersecurity capabilities and infrastructure through a public cloud model. The model is on-demand, pay-per-use, and API-first. For the cybersecurity industry, this change is comparable to the effect of the public cloud on IT. -For managed security services providers (MSSPs), managed detection and response (MDR) firms, and all those involved in digital forensics and incident response (DFIR), the Agentic SecOps Workspace is a powerful way to improve security operations and compete more effectively. With the ASW, service providers can deliver security services at scale, control costs, consolidate and customize security tooling, take on new businesses with confidence, and much more. +Managed security services providers (MSSPs), managed detection and response (MDR) firms, and digital forensics and incident response (DFIR) teams use the Agentic SecOps Workspace. It improves their security operations and helps them to compete. With the ASW, a service provider can deliver security services at scale and control costs. The provider can also consolidate and customize security tools, and take on new clients with confidence. -The platform's public cloud-like delivery model also helps service providers integrate the ASW into their operations gradually and safely. Flexible pay-as-you-go pricing means you only pay for the capabilities you need, and only for as long as you use them—without long-term contracts, complex licensing, capacity planning, price modeling, or termination fees. +The delivery model of the ASW is similar to a public cloud. This model lets a service provider integrate the ASW into its operations one step at a time and with low risk. With pay-as-you-go pricing, you pay only for the capabilities that you need, and only while you use them. There are no long-term contracts, no complex licensing, no capacity planning, no price modeling, and no termination fees. ## Implementation strategies for quick wins -The Agentic SecOps Workspace contains numerous capabilities and is designed to be highly flexible and customizable. Nevertheless, there are some common implementation strategies that MSSP users have found to be good starting points with the platform. Here are three easy ways that the ASW can help service providers improve security operations and expand their businesses immediately: +The Agentic SecOps Workspace has many capabilities and is flexible and customizable. MSSP users report that some strategies are good start points with the platform. This section describes three ways that the ASW helps a service provider to improve security operations and grow its business immediately: ### Gain greater visibility into client environments -The ASW can help service providers gain greater visibility into client environments—and bring telemetry data under a single plane for a more unified view. This is one of the first realizations of value for service providers using the ASW platform. Here's an outline of what this looks like: +The ASW gives a service provider more visibility into client environments. It also brings telemetry data under a single plane for one view. This is one of the first benefits for a service provider that uses the ASW. The following paragraphs give an outline: -**Decide what telemetry data you need to support security operations.** Your options here are extensive. In the ASW, there are two main sources of telemetry: +**Decide what telemetry data you need to support security operations.** You have many options. The ASW has two primary sources of telemetry: -First, there are the platform's endpoint detection and response (EDR)-type sensors, which can be deployed directly on Windows, Mac, and Linux endpoints with full feature parity across these OSes to capture system events and other telemetry data. There are also browser-based sensors for Chrome and Edge. Sensors stream telemetry data and artifacts into the ASW in real time (and can also be used to take response actions on endpoints). Importing event data from third-party EDR tools such as VMWare Carbon Black, CrowdStrike, and Microsoft Defender is also possible. +The first source is the endpoint detection and response (EDR) sensors of the platform. You can deploy these sensors on Windows, Mac, and Linux endpoints, with the same features on each operating system. The sensors capture system events and other telemetry data. Browser-based sensors are also available for Chrome and Edge. The sensors stream telemetry data and artifacts into the ASW in real time, and you can also use them to do response actions on endpoints. You can also import event data from third-party EDR tools such as VMWare Carbon Black, CrowdStrike, and Microsoft Defender. -The second source of telemetry data can be classed as log-type data. This data can be brought into the ASW using a system of adapters or via webhook. The options are too numerous to list here in full, but supported log data sources include O365, 1Password, AWS CloudTrail, Google Cloud Platform (GCP), Slack Audit logs, and more. For a more comprehensive list, refer to the ASW documentation. +The second source is log data. Adapters or a webhook bring this data into the ASW. The supported log data sources include O365, 1Password, AWS CloudTrail, Google Cloud Platform (GCP), and Slack Audit logs. There are more sources than this text can list. For the full list, see the ASW documentation. -**Configure client organizations to provide the required visibility.** The ASW web interface makes this as simple as making a few clicks to set up the required installation keys. More advanced configuration management options using a REST API or a command-line interface (CLI) are also available. After setup, your client organizations' configurations—including what telemetry you want to bring into the Agentic SecOps Workspace—will be stored as simple YAML files. Note here that it's possible to use the ASW's multitenancy and organization management features to make configuration changes to multiple organizations at the same time. For a more detailed example of what this might look like, see this demo MSSP setup. +**Configure client organizations to provide the required visibility.** In the ASW web interface, a few clicks set up the necessary installation keys. A REST API and a command-line interface (CLI) give more advanced control of the configuration. After setup, the ASW stores the configuration of each client organization as YAML files. The configuration includes the telemetry that you bring into the Agentic SecOps Workspace. The multitenancy and organization management features of the ASW change the configuration of many organizations at the same time. For a more detailed example, see the demo MSSP setup. -**Bring your data under a single plane.** All telemetry data brought into the ASW is normalized to a common JSON format and explorable through a single interface. In itself, this represents a huge step forward for many service providers because they will no longer have to deal with a fragmented jumble of UIs or competing data formats in order to view and act on their telemetry data. +**Bring your data under a single plane.** The ASW normalizes all telemetry data to a common JSON format. You explore the data through one interface. Many service providers no longer need to use separate web interfaces or different data formats to see and act on their telemetry data. -**Operationalize your telemetry data.** Seeing into your clients' environments is an essential first step—but this is only the beginning of what is possible with the Agentic SecOps Workspace. The ASW's advanced detection and response engine can act on every piece of telemetry brought into the platform, making it possible to apply sophisticated detection and response () logic to telemetry data. Applying D&R logic can be as tailored or as simple as you choose, from using custom detections that you write yourself to leveraging curated rulesets like Sigma, Soteria, or SOC Prime rules—or a combination of both approaches. +**Operationalize your telemetry data.** Visibility into client environments is an essential first step, but the Agentic SecOps Workspace can do more. The detection and response engine of the ASW acts on each event that enters the platform. You can apply detection and response (D&R) logic to telemetry data. Write your own custom detections, use curated rulesets such as Sigma, Soteria, or SOC Prime rules, or use both methods. -It's impossible to protect what you can't see. The ASW makes it possible to gain full visibility into a client environment, visualize that telemetry in a single interface and data format, and take action on telemetry data via a powerful detection, automation, and response engine. +You cannot protect what you cannot see. With the ASW, you get full visibility into a client environment. You see that telemetry in one interface and one data format. You act on the telemetry data with the detection, automation, and response engine. ### Implement scalable SecOps and simplified client management -The Agentic SecOps Workspace is multitenant by design, offers fine-grained role-based access control (RBAC), and supports an Infrastructure-as-Code (IaC) approach to configuration management. These core aspects of the ASW enable service providers to practice modern cybersecurity operations at scale. +The Agentic SecOps Workspace is multitenant by design. It has fine-grained role-based access control (RBAC). It also supports an Infrastructure-as-Code (IaC) approach to configuration management. These features let a service provider do cybersecurity operations at scale. -**Separate client environments intelligently.** The multitenancy of the ASW allows service providers to create a logical boundary between their client organizations' data while still being able to view and manage everything from a single platform. Multitenancy makes it easier to avoid commingling client data—and comply with regional regulatory requirements such as data residency rules. +**Separate client environments intelligently.** The multitenancy of the ASW puts a logical boundary between the data of each client organization. You still see and manage all organizations from one platform. Multitenancy helps you keep client data separate and obey regional regulations such as data residency rules. -**Manage access and permissions more effectively.** RBAC allows you to grant users the access to organizations and the permissions that they need. You can give individual users permissions on a per-organization basis if you choose. But for more efficient access management, you can use Organization Groups, which are groupings of client organizations, permissions, and users. +**Manage access and permissions more effectively.** RBAC lets you give each user the access to organizations and the permissions that the user needs. You can give permissions to one user for each organization. For more efficient management of access, use Organization Groups. An Organization Group is a set of client organizations, permissions, and users. -Organization Groups give the same permissions and organizational access to any user added to the group. Typically, Organization Groups are set up by job function. For example, you might create an Organization Group for security engineers that allows members to edit telemetry ingestion configurations for all of your client organizations, and a separate Organization Group for non-technical roles that provides read-only access or the ability to view general organizational information. +An Organization Group gives the same permissions and the same access to each user that you add to the group. Most Organization Groups are set up by job function. For example, create one Organization Group for security engineers. Its members can edit the configuration for telemetry ingestion in all of your client organizations. Create a second Organization Group for non-technical roles with read-only access, or with access to general information about the organization. -**Build SecOps workflows that scale.** The Agentic SecOps Workspace enables service providers to take an infrastructure-as-code approach to security operations. All of your client organizations' security configurations—from D&R rules to data forwarding and output settings—can be stored and managed as simple YAML files. +**Build SecOps workflows that scale.** The Agentic SecOps Workspace lets a service provider use an infrastructure-as-code approach to security operations. You store and manage the security configuration of each client organization as YAML files. The configuration includes D&R rules, data forwarding, and output settings. -Create new organizations quickly by cloning an existing organization's configurations or using a configuration template. Maintain a global set of configuration settings for all client organizations and then add per-client config files as needed. If you need to make changes to multiple client organizations, this is as simple as editing a global configuration file via CLI or web UI and pushing out the change to all of your organizations at scale. +To create a new organization quickly, clone the configuration of an existing organization or use a configuration template. Keep one global set of configuration settings for all client organizations. Add a configuration file for each client when it is necessary. To change many client organizations, edit the global configuration file with the CLI or the web app. Then push the change to all of your organizations at scale. -The Agentic SecOps Workspace helps service providers adopt a truly modern and scalable approach to cybersecurity operations. For a more detailed look at how these ASW concepts work in practice, watch Setting Up an MSSP with LimaCharlie. +The Agentic SecOps Workspace helps a service provider use a scalable approach to cybersecurity operations. For a more detailed example of these ASW concepts, watch Setting Up an MSSP with LimaCharlie. ### Improve incident response times and offer unbeatable service-level agreements -The Agentic SecOps Workspace can be tremendously valuable for service providers doing incident response (IR) work. Here are some of the most significant capabilities for IR teams: +The Agentic SecOps Workspace is valuable for a service provider that does incident response (IR) work. The primary capabilities for IR teams are as follows: -**Begin IR engagements without delay.** The on-demand nature of the Agentic SecOps Workspace means you will never need to talk to a vendor sales representative or renegotiate a contract before starting an IR engagement. With the ASW, you log into your account, use a credit card or increase your existing sensor quota, and begin. +**Begin IR engagements without delay.** The Agentic SecOps Workspace is on-demand. You do not need to speak to a vendor sales representative or change a contract before you start an IR engagement. With the ASW, log in to your account, use a credit card or increase your sensor quota, and start. -In addition, it's possible to preconfigure tenants ahead of an IR engagement. Set up your desired ASW IR configuration using custom D&R rulesets, curated rulesets, memory dump capabilities, YARA scanning, and more. Then, export the configuration files for your IR tenant and reuse them whenever you have a new IR engagement to hit the ground running. +You can also configure tenants before an IR engagement. Set up your IR configuration in the ASW with custom D&R rulesets, curated rulesets, memory dumps, YARA scans, and other capabilities. Then export the configuration files for your IR tenant. Reuse the files at the start of each new IR engagement. -**Take the fight to the adversary.** During IR engagements with an active attacker in the environment, the Agentic SecOps Workspace gives you a robust response capability on your client's endpoints. +**Take the fight to the adversary.** During an IR engagement with an active attacker, the Agentic SecOps Workspace gives you a response capability on the endpoints of your client. -Mass-deploy ASW sensors using an enterprise deployment tool. Then, use those sensors to gather real-time event data, run shell commands and executables on endpoints, deploy security tools and remediation packages at scale, or isolate compromised machines from the network—all with minimal impact on the client's operations and mission-critical IT infrastructure. +Deploy ASW sensors in bulk with an enterprise deployment tool. Then use those sensors to collect event data in real time. You can also run shell commands and executables on endpoints, deploy security tools and remediation packages at scale, or isolate compromised machines from the network. These actions have little effect on the operations and the mission-critical IT infrastructure of the client. -**Use security intelligence as soon as you have it.** The ASW's IaC approach means you don't have to rely on a vendor to update a tool or publish an indicator of compromise (IoC) in an emergency. For example, imagine a scenario in which you're dealing with a 0-day compromise. If you have early access to an IoC via an information-sharing network or a colleague, you can literally copy-paste the relevant IoC data from a Slack message into a new ASW D&R rule, update the relevant config file, and push out the change to your client's environment—while the all of the vendor-dependent service providers are still waiting on someone else to act. +**Use security intelligence as soon as you have it.** The ASW uses an IaC approach. In an emergency, you do not depend on a vendor to update a tool or to publish an indicator of compromise (IoC). For example, a 0-day compromise occurs, and you get early access to an IoC through an information-sharing network or a colleague. Copy the IoC data from a Slack message into a new ASW D&R rule. Update the configuration file, and push the change to the environment of your client. Service providers that depend on a vendor must wait for that vendor to act. -**Build a true rapid-response capability.** LimaCharlie sensors can be pre-deployed to client environments in "sleeper" mode: i.e., with the telemetry collection settings tuned down to a bare minimum to keep costs to just pennies per month. If an incident occurs, the sensors are already there, ready and waiting on the endpoints, and can turned on for an immediate response. This use case has allowed ASW service provider partners to offer service-level agreements of as little as 20 minutes—a considerable advantage when it comes to pitching (and closing) new MDR or MSSP clients. +**Build a true rapid-response capability.** Deploy LimaCharlie sensors to client environments in "sleeper" mode before an incident. In this mode, the settings for telemetry collection are at a minimum, and the cost is a few cents each month. If an incident occurs, the sensors are already on the endpoints. Turn the sensors on for an immediate response. Service provider partners that use this method offer service-level agreements of as little as 20 minutes. This is a considerable advantage when they sell to new MDR or MSSP clients. -IR work is high-stakes and high-pressure—and, unfortunately, is far too often complicated by the cumbersome sales processes and technical limitations of legacy cybersecurity vendors. The ASW allows incident responders to take action quickly and independently during an incident. It also lets cybersecurity service providers improve their overall response capabilities, enabling attractive service-level agreements that can help win over prospective clients. +IR work has high stakes and high pressure. The slow sales processes and the technical limits of legacy cybersecurity vendors often make the work more difficult. The ASW lets an incident responder act quickly and independently during an incident. It also lets a cybersecurity service provider improve its response capabilities and offer attractive service-level agreements to prospective clients. diff --git a/docs/1-getting-started/use-cases/network-monitoring.md b/docs/1-getting-started/use-cases/network-monitoring.md index de62b0c68..724161fd0 100644 --- a/docs/1-getting-started/use-cases/network-monitoring.md +++ b/docs/1-getting-started/use-cases/network-monitoring.md @@ -1,16 +1,16 @@ # Network Monitoring -LimaCharlie's Agentic SecOps Workspace, through its integration with Zeek, revolutionizes network security monitoring by providing scalable semantic analysis, seamless artifact ingestion, and powerful detection and response capabilities. By automating threat detection and enabling efficient incident investigation and response, LimaCharlie helps organizations stay ahead of evolving network threats and maintain a robust security posture. +The LimaCharlie Agentic SecOps Workspace integrates with Zeek for network security monitoring. The integration gives semantic analysis at scale, artifact ingestion, and detection and response capabilities. It automates threat detection and makes incident investigation and response efficient. This helps an organization to keep pace with new network threats and to maintain its security posture. ## Network monitoring problems -- **Scalability issues:** Traditional monitoring tools struggle to keep up with the increased volume and variety of network traffic, leading to performance bottlenecks and reduced visibility. -- **Lack of semantic analysis:** Many network monitoring solutions focus primarily on capturing and storing network traffic data without providing deep, semantic analysis of the content, making it difficult to identify and understand sophisticated threats. -- **Limited automation and response capabilities:** Monitoring tools often lack advanced detection, automation, and response features, requiring manual intervention and slowing down incident response times. +- **Scalability issues:** Traditional monitoring tools cannot process the increased volume and variety of network traffic. The result is low performance and less visibility. +- **Lack of semantic analysis:** Many network monitoring solutions only capture and store network traffic data. They do not do a semantic analysis of the content. This makes it difficult to find and understand sophisticated threats. +- **Limited automation and response capabilities:** Many monitoring tools do not have advanced detection, automation, and response features. An operator must act manually, and incident response is slower. ### LimaCharlie's solution -- **Scalable semantic security monitoring:** By leveraging Zeek's robust platform, LimaCharlie enables organizations to perform semantic security monitoring at scale. The Zeek service automatically analyzes ingested PCAP files, extracting rich, structured data that provides deep insights into network activity and potential security threats. -- **Seamless integration with Artifact Ingestion:** LimaCharlie's Zeek extension seamlessly integrates with the platform's Artifact Ingestion system. As PCAP files are ingested, the Zeek service automatically processes them, generating detailed log files that are then re-ingested into the Artifact Ingestion system for further analysis and action. -- **Customizable Detection & Response (D&R) rules:** With the Zeek log files available as artifacts within LimaCharlie, security teams can create sophisticated D&R rules to automate threat detection and response. These rules can be customized to match an organization's specific security requirements, enabling rapid identification and mitigation of potential threats. -- **Efficient incident investigation and response:** LimaCharlie's integration with Zeek empowers security teams to perform efficient incident investigations by providing rich, contextual data about network activity. The platform's powerful search capabilities allow security teams to quickly identify relevant artifacts and take appropriate actions to contain and remediate threats. +- **Scalable semantic security monitoring:** LimaCharlie uses the Zeek platform to do semantic security monitoring at scale. The Zeek service analyzes ingested PCAP files automatically. It extracts structured data about network activity and possible security threats. +- **Seamless integration with Artifact Ingestion:** The LimaCharlie Zeek extension integrates with the Artifact Ingestion system. When the system ingests a PCAP file, the Zeek service processes it and creates detailed log files. The Artifact Ingestion system then ingests those log files for more analysis and action. +- **Customizable Detection & Response (D&R) rules:** The Zeek log files are artifacts in LimaCharlie. A security team can write D&R rules against these artifacts to automate threat detection and response. Customize the rules for the security requirements of your organization to find and mitigate threats quickly. +- **Efficient incident investigation and response:** The integration with Zeek gives a security team contextual data about network activity for efficient incident investigations. The query capabilities of LimaCharlie find the relevant artifacts quickly. The team can then contain and remediate the threats. diff --git a/docs/1-getting-started/use-cases/observability-pipeline.md b/docs/1-getting-started/use-cases/observability-pipeline.md index 10a1ad5b0..ae2685eba 100644 --- a/docs/1-getting-started/use-cases/observability-pipeline.md +++ b/docs/1-getting-started/use-cases/observability-pipeline.md @@ -1,23 +1,23 @@ # Observability Pipeline -The Agentic SecOps Workspace (ASW) creates a scalable, versatile, and actionable observability pipeline by collecting and standardizing telemetry from the full security stack. Stream data from any input, route it to any output. The ASW provides visibility into telemetry sources and empowers users to create automated responses to actionable events in the pipeline. +The Agentic SecOps Workspace (ASW) collects and standardizes telemetry from the full security stack. This makes an observability pipeline that is scalable, versatile, and actionable. Stream data from any input and route it to any output. The ASW gives visibility into telemetry sources. You can also create automated responses to actionable events in the pipeline. ## Observability pipeline problems -Creating an observability pipeline can be a daunting task as users try to integrate a complex and diverse technological environment into a single pipeline solution. When successful, ingesting, managing, and storing data can create significant costs, including: +An observability pipeline is difficult to build, because you must integrate a complex and diverse technological environment into one pipeline. After the pipeline operates, the ingestion, the management, and the storage of data cause significant costs: -- **Data costs:** Collecting and storing telemetry can be extremely expensive. As your business grows, so does its data, leading to escalating data storage costs as well. -- **Infrastructure demands:** Creating, managing, and monitoring the infrastructure required to operate an observability pipeline requires system engineers. As this infrastructure grows to accommodate your business, so does the headcount needed to maintain operations. -- **Delayed responsiveness:** Traditional observability pipelines collect and route data.If something appears in the pipeline that warrants concern, it must be routed to a destination for further analysis before action occurs. -- **High SIEM costs:** Data ingestion adds considerable costs to SIEM operations. As an organization expands its digital footprint these costs can increase rapidly. -- **Vendor lock-in constraints:** Many organizations find themselves trapped with security vendors who deliberately create dependencies through restrictive contracts, proprietary data formats, and closed ecosystems — limiting flexibility, driving up costs, and forcing security decisions based on vendor limitations rather than actual security needs. +- **Data costs:** The collection and the storage of telemetry are expensive. When your business grows, its data also grows, and the cost of data storage increases. +- **Infrastructure demands:** System engineers must build, manage, and monitor the infrastructure for an observability pipeline. When this infrastructure grows with your business, you need more staff to maintain the operation. +- **Delayed responsiveness:** Traditional observability pipelines collect and route data. If a concern occurs in the pipeline, the pipeline must route it to a destination for more analysis before an action occurs. +- **High SIEM costs:** Data ingestion adds considerable cost to SIEM operations. When an organization expands its digital footprint, these costs increase quickly. +- **Vendor lock-in constraints:** Many organizations cannot leave a security vendor. The vendor creates dependencies with restrictive contracts, proprietary data formats, and closed ecosystems. These dependencies limit flexibility, increase costs, and make security decisions depend on the limits of the vendor and not on the security needs. ### LimaCharlie's solutions -The Agentic SecOps Workspace unifies telemetry collection by using an API-first approach for integrating the security stack. It creates a natural observability pipeline that scales without limit, facilitates automated responses, and greatly reduces data costs across the board. With the ASW you get a fully interactive observability pipeline that can facilitate countless other critical security operations as well. +The Agentic SecOps Workspace uses an API-first approach to integrate the security stack and to unify telemetry collection. It creates an observability pipeline that scales without limit, supports automated responses, and reduces data costs. The pipeline is interactive and supports many other critical security operations. - **Free data retention:** LimaCharlie offers a rolling year of free data storage. -- **Infrastructure-as-a-Service:** LimaCharlie provides a scalable, cloud-native infrastructure on an API-first platform. This gives our users maximum flexibility, scalability, and integration capabilities across the full security stack, including the observability pipeline. -- **Instant, bi-directional response:** LimaCharlie supports bi-directionality which allows automated responses sent directly to the source of a detection. For example, if the Agentic SecOps Workspace receives a suspicious login alert from O365 it can immediately send a response to suspend the account before telemetry is sent for further processing. -- **Reduce SIEM spend:** LimaCharlie makes it easy to send only relevant telemetry to your SIEM, while still retaining all of your data in storage. This instantly reduces the costs of operating your SIEM while also accommodating any regulatory compliance requirements involving your data. -- **No vendor lock-in:** The API-first nature of LimaCharlie allows you to integrate and use whatever security solutions, services, and resources you prefer. There are no contracts or artificial barriers put in place to restrict your choices. +- **Infrastructure-as-a-Service:** LimaCharlie supplies a scalable, cloud-native infrastructure on an API-first platform. This gives users flexibility, scalability, and integration capabilities across the full security stack, and in the observability pipeline. +- **Instant, bi-directional response:** LimaCharlie is bi-directional, so it sends automated responses directly to the source of a detection. For example, the Agentic SecOps Workspace receives a suspicious login alert from O365. It immediately sends a response to suspend the account, before it sends the telemetry for more processing. +- **Reduce SIEM spend:** Send only the relevant telemetry to your SIEM, and keep all of your data in storage. This reduces the cost to operate your SIEM and keeps your data for regulatory compliance requirements. +- **No vendor lock-in:** LimaCharlie is API-first, so you can integrate and use the security solutions, services, and resources that you prefer. There are no contracts or artificial barriers that restrict your choices. diff --git a/docs/1-getting-started/use-cases/purple-teaming.md b/docs/1-getting-started/use-cases/purple-teaming.md index e67f16fec..666de09a1 100644 --- a/docs/1-getting-started/use-cases/purple-teaming.md +++ b/docs/1-getting-started/use-cases/purple-teaming.md @@ -1,17 +1,17 @@ # Purple Teaming -LimaCharlie introduces a dynamic, continuous approach to purple teaming. Experience rapid deployment, centralized visibility, flexible outputs, and automated validation to keep your security posture agile and adaptable in the face of ever-changing threats. +LimaCharlie gives a dynamic, continuous approach to purple teaming. It supplies rapid deployment, centralized visibility, flexible outputs, and automated validation. These capabilities keep your security posture agile and adaptable when threats change. ## Purple teaming problems -- **Slow and cumbersome purple teaming exercises:** Traditional purple teaming setups involve deploying complex infrastructure, manually configuring attack simulations, and waiting for results, hindering the frequency and efficiency of security validation. -- **Limited visibility and control:** Siloed security tools often lack centralized visibility into both red and blue team activities, making it difficult to measure the effectiveness of implemented controls and identify gaps in defense strategy. -- **Inaccessible validation results:** Sharing and analyzing purple teaming outputs across different platforms and teams can be tedious and time-consuming, hampering efficient collaboration and feedback loops. -- **Static security posture:** Traditional setups rarely provide continuous validation, leaving organizations vulnerable to evolving threats and undetected weaknesses between infrequent purple teaming exercises. +- **Slow and cumbersome purple teaming exercises:** A traditional purple teaming setup needs complex infrastructure. You must configure the attack simulations manually and then wait for the results. This lowers the frequency and the efficiency of security validation. +- **Limited visibility and control:** Siloed security tools do not give centralized visibility into the activities of the red team and the blue team. This makes it difficult to measure the effect of the controls that you use and to find gaps in the defense strategy. +- **Inaccessible validation results:** It is tedious and slow to share and analyze purple teaming outputs across different platforms and teams. This makes collaboration and feedback loops less efficient. +- **Static security posture:** Traditional setups rarely give continuous validation. Between infrequent purple teaming exercises, an organization stays vulnerable to new threats and to weaknesses that no one detects. ## LimaCharlie's solution -- **Rapid deployment and execution:** Leverage LimaCharlie's multi-platform, full-parity Sensors and pre-built Atomic Red Team integrations to launch sophisticated attack simulations instantly across your entire infrastructure. No need for time-consuming manual setups or specialized red team expertise. -- **Unified visibility and control:** Gain a single pane of glass view into both red and blue team activities within LimaCharlie. Monitor attack simulations, analyze responses from your security tools, and identify areas for improvement with ease. -- **Flexible output destinations:** Seamlessly send purple teaming outputs to any destination you choose – SIEMs, security dashboards, incident response platforms, or even custom tools. Streamline collaboration, facilitate data analysis, and accelerate the validation process. -- **Continuous feedback loop:** Integrate LimaCharlie into your security workflow for ongoing validation. Conduct automated purple teaming exercises at regular intervals, continuously testing your defenses against the latest threats and adapting your security posture based on feedback. +- **Rapid deployment and execution:** Use the multi-platform, full-parity Sensors of LimaCharlie and the pre-built Atomic Red Team integrations. Start sophisticated attack simulations across your full infrastructure immediately. You do not need a slow manual setup or specialized red team expertise. +- **Unified visibility and control:** Get one view of the activities of the red team and the blue team in LimaCharlie. Monitor the attack simulations, analyze the responses from your security tools, and find the areas to improve. +- **Flexible output destinations:** Send purple teaming outputs to any destination that you choose: a SIEM, a security dashboard, an incident response platform, or a custom tool. This improves collaboration, helps data analysis, and makes the validation process faster. +- **Continuous feedback loop:** Integrate LimaCharlie into your security workflow for continuous validation. Do automated purple teaming exercises at regular intervals. The exercises test your defenses against the latest threats. Adapt your security posture from the feedback. diff --git a/docs/1-getting-started/use-cases/secops-development.md b/docs/1-getting-started/use-cases/secops-development.md index ba11953e9..c4576284a 100644 --- a/docs/1-getting-started/use-cases/secops-development.md +++ b/docs/1-getting-started/use-cases/secops-development.md @@ -1,21 +1,21 @@ # SecOps Development -The Agentic SecOps Workspace accelerates building, customizing, integrating, and scaling security operations. By handling the infrastructure-intensive aspects of security engineering, LimaCharlie takes on the heavy lifting making it easy for developers to focus on their core projects. +The Agentic SecOps Workspace makes it faster to build, customize, integrate, and scale security operations. LimaCharlie operates the infrastructure that security engineering needs. Developers can then give their time to their own projects. ## SecOps development problems -Innovating new security products and modifying existing ones is crucial for protecting organizations from evolving cyberthreats. Unfortunately, the process of building better cybersecurity solutions is often hampered by: +New security products and changes to existing ones protect organizations against cyberthreats that change. These problems slow down the work to build better cybersecurity solutions: -- **Time consuming infrastructure management:** Developers spend too much time building, maintaining, and updating infrastructure instead of working on projects. -- **Integration headaches:** Valuable time is lost to solving integration issues between the tools, services, and platforms critical to a project's success. -- **Scalability issues:** While your solution works well at a small scale there are serious concerns over whether it can scale effectively as your business grows. -- **Lack of control:** Your project relies on third-party or open source tooling that lacks the flexibility you need to succeed. +- **Time spent on infrastructure management:** Developers spend too much time to build, maintain, and update infrastructure instead of work on projects. +- **Integration problems:** Time is lost to integration problems between the tools, services, and platforms that a project needs. +- **Scalability problems:** A solution that works at a small scale can fail to scale as the business grows. +- **Lack of control:** A project depends on third-party or open source tools that do not give the necessary flexibility. ## LimaCharlie's solution -The Agentic SecOps Workspace delivers core security capabilities in the form of "primitives" that can be modified to accommodate specific needs. It offers infrastructure-as-code and other resources that can improve a developer's mean-time-to-market, including: +The Agentic SecOps Workspace supplies core security capabilities as "primitives" that you can change for your own needs. It supplies infrastructure-as-code and other resources that shorten a developer's mean-time-to-market: -- **Infrastructure-as-a-service:** LimaCharlie delivers security-oriented cloud-primitives that provide scalable infrastructure and critical resources for your project development. Think AWS, but for security. -- **API-first foundation:** The Agentic SecOps Workspace (ASW) is built upon an API-first foundation. Information normalized and shared via API, freeing you from vendor lock-in and giving you maximum flexibility. -- **Seamless scalability:** The ASW is a cloud platform, and scales effortlessly with the growth of your company. -- **Maximum flexibility:** The ASW offers full transparency and granular management of the resources you choose to incorporate. Where third-party tools or open source solutions offer roadblocks, the ASW provides the capability to customize, innovate, and create needed capabilities. +- **Infrastructure-as-a-service:** LimaCharlie supplies cloud primitives for security. These primitives give scalable infrastructure and resources for your project. They are similar to AWS, but for security. +- **API-first foundation:** The Agentic SecOps Workspace (ASW) is built on an API-first foundation. The API normalizes and shares the information. You are free of vendor lock-in and keep maximum flexibility. +- **Scalability:** The ASW is a cloud platform, and it scales as your company grows. +- **Maximum flexibility:** The ASW gives full transparency and granular management of the resources that you use. Where third-party tools or open source solutions block you, the ASW lets you customize, innovate, and create the capabilities that you need. diff --git a/docs/1-getting-started/use-cases/sleeper-mode.md b/docs/1-getting-started/use-cases/sleeper-mode.md index 71199a5e8..e1109d927 100644 --- a/docs/1-getting-started/use-cases/sleeper-mode.md +++ b/docs/1-getting-started/use-cases/sleeper-mode.md @@ -1,22 +1,22 @@ # Sleeper Mode -LimaCharlie's sleeper mode is not just about cost-efficiency; it's about transforming your entire network into a dynamic, responsive security infrastructure. By pre-deploying sensors and strategically activating them during incidents, you gain the element of surprise, optimize resource allocation, and ultimately, mitigate the impact of cyberattacks with unmatched agility. +Sleeper mode lowers cost, but it also changes your network into a responsive security infrastructure. You deploy sensors before an incident and activate them during the incident. You keep the element of surprise, use your resources better, and limit the effect of a cyberattack. ## Traditional sensor deployment problems -Traditional IR relies on reactive deployment of sensors, leaving critical blind spots during early stages of an incident. Delays in gaining visibility slow down response times and increase damage potential. +Traditional IR deploys sensors only after an incident starts. This leaves blind spots in the early stages of the incident. A delay in visibility slows the response and increases the possible damage. -- **Limited visibility:** Lack of visibility during the early stages of an incident due to the absence of pre-deployed sensors. -- **Manual processes:** Delayed response times caused by the need to manually deploy sensors after an incident has been detected. -- **Delayed response:** Increased potential for damage and lateral movement of threats while waiting for sensor deployment and data collection. +- **Limited visibility:** There is no visibility in the early stages of an incident, because no sensor is deployed. +- **Manual processes:** The response is slow, because you must deploy the sensors manually after the detection of an incident. +- **Delayed response:** The possible damage and the lateral movement of a threat increase while you wait for the sensors and the data. ### LimaCharlie's solution -Sleeper mode transforms your entire network into a pre-wired security grid. Sensors sit silently, consuming minimal resources while collecting basic system information and detecting critical events. This provides: +Sleeper mode changes your network into a security grid that is prepared in advance. The sensors stay silent and use few resources. They collect basic system information and detect critical events. Sleeper mode gives you these capabilities: -- **Instant Activation, Rapid Response:** Need deep process monitoring or memory forensic capabilities? Instantly activate sleepers within the affected area, gaining full-fledged EDR visibility for targeted investigation and containment. No more waiting for manual installation during critical moments. -- **Surgical Precision:** Focus resources where they matter most. Activate sleepers only on specific endpoints or clusters suspected of involvement, reducing unnecessary data collection and analysis overload. This streamlines investigations and saves valuable time. -- **Critical Assets Under Cover:** Pre-deploy sensors in sleeper mode on high-value servers, executive machines, or sensitive data repositories. When an incident strikes, instant activation grants immediate visibility and control, safeguarding your most crucial assets. -- **Targeted Threat Hunting:** Identify potential targets based on threat intelligence or internal red teaming exercises. Pre-emptively activate sleepers in these areas, creating a proactive surveillance network to catch early signs of malicious activity. -- **Isolate and Contain:** Sleeper mode empowers swift containment. Upon detecting suspicious activity, activate neighboring sleepers to cordon off the affected area, preventing lateral movement and limiting damage. -- **Deep Dive Forensics:** Need detailed forensic disk or memory analysis? Activate the relevant sleeper for comprehensive forensic investigation, dissecting the incident and identifying root causes for future prevention. +- **Instant Activation, Rapid Response:** Activate the sleepers in the affected area when you need deep monitoring of processes or memory forensics. You then get full EDR visibility for the investigation and the containment. You do not wait for a manual installation at a critical moment. +- **Surgical Precision:** Put your resources where they are most necessary. Activate the sleepers only on the endpoints or clusters that you suspect. This collects less data, lowers the analysis load, and saves time in the investigation. +- **Critical Assets Under Cover:** Deploy sensors in sleeper mode on high-value servers, executive machines, or repositories of sensitive data. When an incident starts, instant activation gives immediate visibility and control of your most important assets. +- **Targeted Threat Hunting:** Identify the possible targets from threat intelligence or from internal red team exercises. Activate the sleepers in these areas in advance. This makes a surveillance network that catches the early signs of malicious activity. +- **Isolate and Contain:** Sleeper mode gives fast containment. After you detect suspicious activity, activate the adjacent sleepers to close off the affected area. This stops lateral movement and limits the damage. +- **Deep Dive Forensics:** Activate the applicable sleeper when you need a detailed forensic analysis of a disk or of memory. You can then examine the incident and find the root causes to stop a recurrence. diff --git a/docs/1-getting-started/use-cases/soar-automation.md b/docs/1-getting-started/use-cases/soar-automation.md index bc0ce8590..5d0b2031e 100644 --- a/docs/1-getting-started/use-cases/soar-automation.md +++ b/docs/1-getting-started/use-cases/soar-automation.md @@ -1,21 +1,21 @@ # SOAR / Automation -The Agentic SecOps Workspace makes building, modifying, or streamlining your security orchestration, automation, and response (SOAR) operations simple. Lower your costs and increase your response time by aggregating SOAR tooling, integrating resources, and normalizing telemetry with the Agentic SecOps Workspace. +The Agentic SecOps Workspace helps you build, change, or streamline your security orchestration, automation, and response (SOAR) operations. It collects SOAR tooling in one place, integrates resources, and normalizes telemetry. This lowers your costs and increases your response time. ## SOAR/Automation problems -Security orchestration, automation, and response (SOAR) solutions play a key role in detecting and responding to cyber threats. However, adopting a standalone SOAR solution may also create new challenges including: +Security orchestration, automation, and response (SOAR) solutions have a key part in the detection of, and the response to, cyber threats. But a standalone SOAR solution can also create new problems: -- **Alert fatigue:** Security analysts receive and evaluate countless alerts before uncovering and responding to legitimate issues. -- **High data costs:** Sending telemetry data to a SIEM can be an expensive, resource-intensive process that only increases as businesses grow, resulting in new endpoints and data sources. -- **Unnecessary detection friction:** Security tools detect suspicious activity and send events to the SIEM, generating an alert for the analyst to investigate. After investigation, various manual procedures are invoked to remediate the alert. -- **Inefficient manual processes:** Critical time is lost as analysts coordinate transferring crucial information into various tools and performing response actions. +- **Alert fatigue:** Security analysts receive and evaluate many alerts before they find and respond to a real problem. +- **High data costs:** To send telemetry data to a SIEM is expensive and uses many resources. The cost increases as a business grows and adds endpoints and data sources. +- **Unnecessary detection friction:** Security tools detect suspicious activity and send events to the SIEM. The SIEM generates an alert, and the analyst investigates it. After the investigation, the analyst starts manual procedures to remediate the alert. +- **Inefficient manual processes:** Analysts lose time when they copy information into different tools and do the response actions. ## LimaCharlie's solutions -The Agentic SecOps Workspace consolidates and integrates SOAR tooling in a single place. It offers a more efficient, customizable way to implement SOAR by integrating the security stack, normalizing data, and expanding automation capabilities. +The Agentic SecOps Workspace collects and integrates SOAR tooling in one place. It integrates the security stack, normalizes data, and adds automation capabilities. This is a more efficient and customizable way to build SOAR. -- **Data normalization, collection, false positive rules, and filtering:** The LimaCharlie Agentic SecOps Workspace collects and normalizes telemetry making it easy to filter out noise, share information between resources, and detect real problems. -- **Reduced data costs:** All events, telemetry, and detections within LimaCharlie are stored online and searchable for one year. This allows users to keep everything instead of aggregating and having to choose which data is important. -- **Bi-directionality:** LimaCharlie supports bi-directionality which allows automated responses to be sent directly to the source of a detection. For example, if the Agentic SecOps Workspace receives a suspicious login alert from O365 it can send a direct automated response to suspend the account. This eliminates a persistence method for attackers. -- **API-first foundation:** LimaCharlie can perform critical response actions for any asset in your security stack via API. Automated responses can trigger remediation actions and send telemetry to security tooling without (comparatively slow) human intervention. Python playbooks allow you to automatically perform standard, repetitive tasks, reducing mean time to resolve, and allowing analysts to focus on higher priority alerts. +- **Data normalization, collection, false positive rules, and filtering:** The LimaCharlie Agentic SecOps Workspace collects and normalizes telemetry. You can then filter out the noise, share information between resources, and detect real problems. +- **Reduced data costs:** LimaCharlie keeps all events, telemetry, and detections online and searchable for one year. You can keep everything instead of a selection of the data that you think is important. +- **Bi-directionality:** LimaCharlie supports bi-directionality, which sends an automated response directly to the source of a detection. For example, if the Agentic SecOps Workspace receives a suspicious login alert from O365, it can send an automated response to suspend the account. This removes a persistence method for attackers. +- **API-first foundation:** LimaCharlie can do critical response actions for any asset in your security stack through the API. An automated response can start a remediation action and send telemetry to security tooling without human intervention, which is slower. Python playbooks do standard, repetitive tasks automatically. This lowers the mean time to resolve and lets analysts work on alerts with a higher priority. diff --git a/docs/1-getting-started/use-cases/table-top-exercises.md b/docs/1-getting-started/use-cases/table-top-exercises.md index 1b93a447a..08b8afde9 100644 --- a/docs/1-getting-started/use-cases/table-top-exercises.md +++ b/docs/1-getting-started/use-cases/table-top-exercises.md @@ -1,17 +1,17 @@ # Table Top Exercises -Enhance your security preparedness table-top exercises with LimaCharlie. Conduct realistic multi-platform simulations, optimize incident response procedures, and empower your team to face evolving cyber threats with confidence. +Use LimaCharlie to improve the table-top exercises that prepare your security team. Run realistic simulations on many platforms, improve your incident response procedures, and prepare your team for cyber threats that change. ## Problems with table top exercises -- **Costly and time-consuming setup:**Traditional tabletop exercises (TTX) often require dedicated infrastructure, extensive preparation, and significant resource investment, making them infrequent and burdensome. -- **Limited platform capabilities:** Many TTX platforms lack cross-platform support, realistic attack simulations, and comprehensive reporting, hindering effective incident response training. -- **Fragmented security awareness:** Traditional scenarios might not encompass multi-platform environments and evolving attack vectors, leaving security teams unprepared for real-world threats. +- **Costly and time-consuming setup:** Traditional tabletop exercises (TTX) need dedicated infrastructure, long preparation, and many resources. Teams therefore run them rarely. +- **Limited platform capabilities:** Many TTX platforms have no support for multiple platforms, no realistic attack simulations, and no full reporting. This limits the value of the incident response training. +- **Fragmented security awareness:** A traditional scenario can omit environments with multiple platforms and new attack vectors. The security team is then not prepared for real threats. ## LimaCharlie's solution -- **Pay-as-you-go platform:** Access LimaCharlie's fully featured capabilities with flexible, pay-as-you-go pricing. Conduct exercises as needed without costly upfront investments or long-term contracts. -- **Rapid deployment and customization:** Get started with LimaCharlie's quickly and easily. Launch realistic cyber attack simulations within minutes, tailored to your specific environment and security concerns. -- **Comprehensive multi-platform simulations:** Test your team's response to complex attack scenarios across Windows, macOS, Linux, and cloud environments, mimicking real-world threats. Leverage LimaCharlie's API to integrate your existing security tools, creating a truly holistic response simulation. -- **Detailed reporting and insights:** Gain valuable insights from post-exercise reports that analyze team performance, identify skill gaps, and offer actionable recommendations for improving your incident response procedures. -- **Customizable attack libraries:** Utilize pre-built or customize attack scenarios, based on Atomic Red Team, to run your training exercises. Based on your specific industry, threat landscape, and vulnerabilities, ensure you conduct relevant and valuable training exercises. +- **Pay-as-you-go platform:** Use all LimaCharlie capabilities with pay-as-you-go pricing. Run an exercise when you need one, with no cost in advance and no long-term contract. +- **Rapid deployment and customization:** Start with LimaCharlie in a short time. Start realistic simulations of cyber attacks in minutes, adapted to your environment and your security concerns. +- **Multi-platform simulations:** Test the response of your team to complex attack scenarios on Windows, macOS, Linux, and cloud environments that copy real threats. Use the LimaCharlie API to integrate your existing security tools into one response simulation. +- **Detailed reporting and insights:** Read the reports that the platform makes after an exercise. The reports analyze the performance of the team, show gaps in skills, and give recommendations to improve your incident response procedures. +- **Customizable attack libraries:** Use the supplied attack scenarios, which are based on Atomic Red Team, or customize them for your training exercises. Adapt each exercise to your industry, your threat landscape, and your vulnerabilities to keep the training relevant. diff --git a/docs/1-getting-started/use-cases/threat-hunting.md b/docs/1-getting-started/use-cases/threat-hunting.md index ba25ff7f6..ee30066cb 100644 --- a/docs/1-getting-started/use-cases/threat-hunting.md +++ b/docs/1-getting-started/use-cases/threat-hunting.md @@ -1,16 +1,16 @@ # Threat Hunting -Stop settling for static defenses – become a threat hunting powerhouse with LimaCharlie! One-year historical data, intuitive exploration, and seamless rule creation empower you to uncover hidden threats, predict future attacks, and continuously optimize your security posture for maximum resilience. +LimaCharlie gives you more than static defenses for threat hunting. It keeps one year of historical data, lets you explore that data, and lets you create rules from what you find. You can find hidden threats, predict future attacks, and improve your security posture. ## Threat hunting problems -- **Limited visibility into past activity:** Traditional security solutions focus on real-time threats, leaving hidden attacker footprints and lingering malware remnants undetected in historical data. -- **Cumbersome historical data analysis:** Complex log aggregation and analysis tools hinder efficient threat hunting investigations across vast datasets, delaying threat discovery and response. -- **Static detection and response:** The disconnect between reactive threat hunts and proactive defense leaves organizations vulnerable to future attacks from similar tactics, techniques, and procedures (TTPs). +- **Limited visibility into past activity:** Traditional security solutions look only at threats in real time. The traces of an attacker and the remnants of malware stay undetected in the historical data. +- **Cumbersome historical data analysis:** Complex tools for the aggregation and the analysis of logs make a hunt across large datasets slow. This delays the discovery of a threat and the response to it. +- **Static detection and response:** A reactive threat hunt is separate from proactive defense. The organization stays open to future attacks that use the same tactics, techniques, and procedures (TTPs). ### LimaCharlie's solution -- **Deep Dive into One Year of Data:** Explore past events, analyze suspicious activities, and uncover hidden threats with LimaCharlie's one-year historical data storage. Don't let potential attacker footprints remain invisible. -- **Effortless Exploration with Intuitive Queries:** Utilize LimaCharlie's powerful search engine and pre-built queries to navigate historical data with ease. Find connections, identify anomalies, and conduct in-depth investigations without cumbersome tools. -- **From Hunt to Rule—Seamless Transformation:** Easily convert your threat hunting discoveries into actionable detection and response rules within LimaCharlie. Automate future defense against similar attacks by leveraging insights from your historical investigations, closing the loop between reactive hunting and proactive prevention. -- **Continuous Optimization—A Cycle of Resilience:** Re-run historical threat hunts with evolving queries and filters to adapt your detection and response rules as the threat landscape changes. Continuously refine your defenses based on new insights and stay ahead of adversaries. +- **Deep Dive into One Year of Data:** Examine past events, analyze suspicious activity, and find hidden threats in the one year of historical data that LimaCharlie stores. The traces of an attacker do not stay invisible. +- **Exploration with Intuitive Queries:** Use the LimaCharlie search engine and the supplied queries to move through the historical data. Find connections, identify anomalies, and do detailed investigations without complex tools. +- **From Hunt to Rule—Direct Transformation:** Convert what you find in a hunt into detection and response rules in LimaCharlie. The rules then defend against similar attacks automatically. This connects a reactive hunt to proactive prevention. +- **Continuous Optimization—A Cycle of Resilience:** Run a historical threat hunt again with new queries and filters as the threat landscape changes. Adapt your detection and response rules to each new result to stay in front of the adversary. diff --git a/docs/1-getting-started/use-cases/wel-monitoring.md b/docs/1-getting-started/use-cases/wel-monitoring.md index e6e77cca2..4fa4b836f 100644 --- a/docs/1-getting-started/use-cases/wel-monitoring.md +++ b/docs/1-getting-started/use-cases/wel-monitoring.md @@ -1,21 +1,21 @@ # WEL Monitoring -LimaCharlie's Agentic SecOps Workspace transforms Windows Event Log monitoring by providing real-time visibility, streamlined infrastructure, and powerful detection and response capabilities. Effectively monitor and protect your Windows environments, ensuring rapid detection and response to potential security incidents. +The LimaCharlie Agentic SecOps Workspace changes how you monitor the Windows Event Log. It gives visibility in real time, simpler infrastructure, and detection and response capabilities. You can monitor and protect your Windows environments and respond quickly to a security incident. ## WEL monitoring problems -- **Limited real-time visibility:** Traditional WEL monitoring solutions often rely on periodic log collection, resulting in delayed visibility into potential security incidents, limiting real-time visibility. -- **Complex and costly infrastructure:** Forwarding WEL data to a centralized monitoring system typically requires additional infrastructure, such as log collectors and forwarders, which can be complex to set up and maintain, as well as costly to scale. -- **Difficulty in creating custom detection rules:** Writing custom rules to detect malicious behavior in WEL data can be challenging, especially when dealing with large volumes of logs and a lack of standardized formats. +- **Limited real-time visibility:** Traditional WEL monitoring solutions collect logs at intervals. Visibility into a possible security incident is therefore delayed, and there is little visibility in real time. +- **Complex and costly infrastructure:** To send WEL data to a central monitoring system, you need more infrastructure, such as log collectors and forwarders. This infrastructure is difficult to set up and maintain, and expensive to scale. +- **Difficulty in creating custom detection rules:** Custom rules that detect malicious behavior in WEL data are difficult to write. Large volumes of logs and the absence of a standard format add to the difficulty. ### LimaCharlie's solution -- **Real-time WEL ingestion:** LimaCharlie's Sensor enables direct, real-time importation of WEL data, eliminating the need for complex forwarding infrastructure and reducing costs and management overhead. -- **Powerful Detection & Response (****) engine**: Ingested WEL data is automatically indexed against common indicators of compromise (IoCs) and processed through LimaCharlie's advanced Detection and Response engine, enabling rapid detection of malicious activity. -- **Flexible and customizable rule creation:** With WEL data structured as JSON, security teams can easily create custom D&R rules to detect and respond to specific Windows events as they occur, tailoring the monitoring process to their unique needs and environment. -- **Historical log analysis:** Import historical event log data from disk, empowering teams to conduct in-depth investigations and gain valuable context around endpoint activity. +- **Real-time WEL ingestion:** The LimaCharlie Sensor imports WEL data directly and in real time. You do not need a complex forwarding infrastructure, so costs and management work are lower. +- **Detection & Response (****) engine**: LimaCharlie indexes the ingested WEL data against common indicators of compromise (IoCs). It then sends the data through the Detection and Response engine, which detects malicious activity quickly. +- **Flexible and customizable rule creation:** WEL data is structured as JSON. Security teams can create custom D&R rules that detect and respond to specific Windows events when the events occur. Each team adapts the monitoring to its own environment. +- **Historical log analysis:** Import historical event log data from disk. Teams can then do detailed investigations and get context about the activity on an endpoint. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Like agents, Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. ## What's Next diff --git a/docs/1-getting-started/what-is-limacharlie.md b/docs/1-getting-started/what-is-limacharlie.md index c1f5dc0f7..05f202de1 100644 --- a/docs/1-getting-started/what-is-limacharlie.md +++ b/docs/1-getting-started/what-is-limacharlie.md @@ -1,16 +1,16 @@ # What is LimaCharlie? -LimaCharlie is the **Agentic SecOps Workspace** - delivering security operations for the modern era. +LimaCharlie is the **Agentic SecOps Workspace** - a platform for modern security operations. -LimaCharlie's Agentic SecOps Workspace provides you with comprehensive enterprise protection that brings together critical cybersecurity capabilities and eliminates integration challenges and security gaps for more effective protection against today's threats. +The LimaCharlie Agentic SecOps Workspace combines cybersecurity capabilities in one platform for the enterprise. The single platform removes the work to integrate separate tools and the gaps in security between them. It protects you against current threats. -The Agentic SecOps Workspace offers a unified platform where you can build customized solutions effortlessly. With open APIs, centralized telemetry, and automated detection and response mechanisms, it's time cybersecurity moves into the modern era. +The Agentic SecOps Workspace is one platform on which you build customized solutions. It has open APIs, central telemetry, and automated mechanisms for detection and response. -Simplifying procurement, deployment and integration of best-of-breed cybersecurity solutions, the Agentic SecOps Workspace delivers complete protection tailored to each organization's specific needs, much in the same way IT Clouds have supported enterprises for years. +The Agentic SecOps Workspace makes the procurement, the deployment, and the integration of cybersecurity solutions simpler. It gives complete protection that is adapted to the needs of each organization, in the same way that IT clouds supported enterprises for years. -Our documentation can walk you through setting up your own Organization, deploying Sensors, writing detection and response rules, or outputting your data to any destination of your choosing. To dive in immediately, see our [Quickstart](quickstart.md) guide. +This documentation explains how to set up your own Organization, deploy Sensors, and write detection and response rules. It also explains how to send your data to a destination that you select. To start immediately, read the [Quickstart](quickstart.md) guide. -Dig in, and build the security program you need and have always wanted. +Use the platform to build the security program that you need. --- diff --git a/docs/2-sensors-deployment/adapters/as-a-service.md b/docs/2-sensors-deployment/adapters/as-a-service.md index 55c55cd4f..09d84d181 100644 --- a/docs/2-sensors-deployment/adapters/as-a-service.md +++ b/docs/2-sensors-deployment/adapters/as-a-service.md @@ -1,39 +1,39 @@ # Adapters as a Service -In some cases, users may need to install the LimaCharlie Adapter with persistence, to ensure that data collection survives a reboot and/or other disruptions. +Sometimes you must install the LimaCharlie Adapter with persistence. Persistence keeps data collection active after a reboot or another disruption. -To accommodate this need, the LimaCharlie adapter can be installed as a service. +You can install the LimaCharlie adapter as a service. ## Service Installation ### Windows -To install the Windows LimaCharlie adapter as a service, insert the `-install:` flag in the command line, following the adapter executable name. +To install the Windows LimaCharlie adapter as a service, use the `-install:` flag. Put the flag after the name of the adapter executable. -For example: +For example, replace this command: `./lc_adapter.exe azure_event_hub client_options.identity.installation_key=...` -would be replaced with +with this command: `./lc_adapter.exe -install:azure_collection azure_event_hub client_options.identity.installation_key=...` -This would create a service named `azure_collection` with the adapter config. +The second command creates a service named `azure_collection` with the adapter config. -Remember, adapter configurations can be provided via two methods: +You can give adapter configurations in two ways: -- In the command line, as part of a list of flags -- Via a YAML config file +- In the command line, as a list of flags +- In a YAML config file -**Note:** The service will point to `lc_adapter.exe` based on its path at the creation of the service. If you wish to move the adapter to a permanent location, please do so before creating the service. +**Note:** The service points to `lc_adapter.exe` at the path that the file has when you create the service. Move the adapter to its permanent location before you create the service. ### Linux / systemd -To install a LimaCharlie adapter as a service on a Linux system with systemd, you will need a service file, the adapter binary, and your adapter command. +On a Linux system with systemd, you need a service file, the adapter binary, and your adapter command. #### Adapter Binary -Download one of the [adapter binaries](deployment.md) and apply the necessary permissions: +Download one of the [adapter binaries](deployment.md). Then set the necessary permissions: ```bash wget -O /path/to/adapter-directory/lc-adapter $ADAPTER_BINARY_URL @@ -42,7 +42,7 @@ chmod +x /path/to/adapter-directory/lc-adapter #### Service File - /etc/systemd/system/limacharlie-adapter-name.service -You will replace `$ADAPTER_COMMAND` in the service file with your actual adapter command below. +In the service file, replace `$ADAPTER_COMMAND` with your own adapter command. ```bash [Unit] @@ -65,7 +65,7 @@ WantedBy=multi-user.target #### Adapter Command -Your adapter command may differ depending on your use case--this is an example of a [file](types/file.md) adapter to ingest logs from a JSON file. +Your adapter command changes with your use case. This example uses a [file](types/file.md) adapter to ingest logs from a JSON file. ```bash /path/to/adapter-directory/lc-adapter file file_path=/path/to/logs.json client_options.identity.installation_key= client_options.identity.oid= client_options.platform=json client_options.sensor_seed_key= client_options.mapping.event_type_path= client_options.hostname= @@ -87,7 +87,7 @@ To remove a Windows LimaCharlie Adapter service, use the `-remove: ### Linux -If your service is running with a systemd script, you can disable and remove it with the following: +If a systemd script runs your service, disable and remove it with these commands: ```bash sudo systemctl stop lc-adapter-name diff --git a/docs/2-sensors-deployment/adapters/deployment.md b/docs/2-sensors-deployment/adapters/deployment.md index 89789a688..0d8d93d00 100644 --- a/docs/2-sensors-deployment/adapters/deployment.md +++ b/docs/2-sensors-deployment/adapters/deployment.md @@ -1,21 +1,21 @@ # Adapter Deployment -Adapters can be deployed in one of two ways: +You can deploy adapters in two ways: -- **On-prem**, Adapters utilize the LC Adapter binary to ingest a data source and forward it to LimaCharlie. -- **Cloud-to-cloud**, connects the LimaCharlie cloud directly with your cloud source and automatically ingests data. +- **On-prem**, adapters use the LC Adapter binary to ingest a data source and send it to LimaCharlie. +- **Cloud-to-cloud**, connects the LimaCharlie cloud directly with your cloud source and ingests data automatically. -Which Adapter Do I Use for Cloud Data? +Adapter choice for cloud data. -You can use on-prem adapters to forward cloud data, or you could acquire the same data with a cloud-to-cloud connection. So, which one to use? +You can use an on-prem adapter to send cloud data to LimaCharlie. You can also get the same data with a cloud-to-cloud connection. -The answer lies in _how_ you want to send your data to LimaCharlie. Are you OK with configuring a connector from our platform, or would you rather use a bastion box in between? Either way works for us! +The choice depends on _how_ you want to send your data to LimaCharlie. A cloud-to-cloud connection is configured in the LimaCharlie cloud. An on-prem adapter puts a bastion box between the source and LimaCharlie. Both methods work. -The data ingested from adapters is parsed/mapped into JSON by LimaCharlie, according to the parameters you provided, unless using a pre-defined format. +LimaCharlie parses and maps the data from adapters into JSON. It uses the parameters that you supply, unless you use a pre-defined format. ## Adapter Binaries -Software-based, or "on-prem" adapters are available in the following formats: +Software-based, or "on-prem", adapters are available in these formats: ### POSIX-compliant @@ -41,21 +41,21 @@ Software-based, or "on-prem" adapters are available in the following formats: - -Another platform? +Other platforms. -If you need support for a specific platform, or require more information about supported platforms, please [let us know](https://www.limacharlie.io/contact). +If you need support for a specific platform, or more information about supported platforms, [contact LimaCharlie](https://www.limacharlie.io/contact). ## On-Prem + Cloud Management -LimaCharlie Adapters deployed manually (on-prem) also support cloud-based management. This makes the deployment of the adapter extremely easy while also making it easy to update the configs remotely after the fact. This is particularly critical for service providers that may be deploying adapters on customer networks where gaining access to the local adapter may be difficult. +LimaCharlie Adapters that you deploy manually (on-prem) also support cloud-based management. With cloud-based management, you can update the configs remotely after the deployment. This is important for service providers that deploy adapters on customer networks, where access to the local adapter is difficult. -To accomplish this, you need the `externaladapter.*` permissions. +To do this, you need the `externaladapter.*` permissions. ### Preparing -The first step of deploying this way is to create a new External Adapter record. These are found in the `external_adapter` Hive or under the Sensors section of the web app. +First, create a new External Adapter record. These records are in the `external_adapter` Hive, or under the Sensors section of the web app. -The content of an external adapter is exactly the same as a traditional [adapter configuration](usage.md) in YAML. It describes what you want your external adapter to do, like collect from file, operate as a syslog server etc. For example: +The content of an external adapter is the same as a traditional [adapter configuration](usage.md) in YAML. It describes what your external adapter does, such as collection from a file or operation as a syslog server. For example: ```yaml sensor_type: syslog @@ -72,22 +72,22 @@ syslog: port: 4242 ``` -Once your external adapter record is created, take note of the `GUID` (Globally Unique ID) found under the `sys_mtd` section of the JSON record, or on the right-hand side of the record view in the web app +After you create the external adapter record, find the `GUID` (Globally Unique ID). It is under the `sys_mtd` section of the JSON record, or on the right side of the record view in the web app . -This `GUID` is a shared secret value you will use in the deployed adapter to reference it to the record it should update and operate from. +The `GUID` is a shared secret. The deployed adapter uses the `GUID` to point to the record that it must update and operate from. ### Deploying -Now that the configuration of the adapter is ready, you can deploy the adapter on-prem according to the [normal process](usage.md). The only difference is that instead of running it with the full configuration locally, you can run it with the `cloud` collection method like this: +After the adapter configuration is ready, deploy the adapter on-prem with the [normal process](usage.md). Run the adapter with the `cloud` collection method instead of the full local configuration: ```bash ./lc_adapter cloud conf_guid=XXXXXXXXXXXXXXXXXXXXx oid=YYYYYYYYYYYYYYYYYYY ``` -This will start the adapter telling it to fetch the configuration it requires from the cloud based on the Organization ID (your tenant in LC) and the `GUID` of the record it should use. +The adapter starts and fetches the configuration that it needs from the cloud. It uses the Organization ID (your tenant in LC) and the `GUID` of the record. -From this point on, updating the record in LimaCharlie will automatically reconfigure the adapter on-prem, within about 1 minute of the change. +After this, an update to the record in LimaCharlie reconfigures the on-prem adapter automatically, in about 1 minute. -Adapters serve as flexible data ingestion mechanisms for both on-premise and cloud environments. +Adapters ingest data in on-premise and cloud environments. diff --git a/docs/2-sensors-deployment/adapters/examples/stdin-json.md b/docs/2-sensors-deployment/adapters/examples/stdin-json.md index 3b2925985..a229ed237 100644 --- a/docs/2-sensors-deployment/adapters/examples/stdin-json.md +++ b/docs/2-sensors-deployment/adapters/examples/stdin-json.md @@ -1,6 +1,6 @@ # Stdin JSON -This example is similar to the [Stdin](stdin.md) example, except it assumes the data being read is JSON, not text. If your data source is already JSON, it's simpler to let LimaCharlie handle the JSON parsing directly. +This example is similar to the [Stdin](stdin.md) example, but the data is JSON, not text. If your data source is already JSON, let LimaCharlie parse the JSON directly. ```bash ./lc_adapter stdin client_options.identity.installation_key=e9a3bcdf-efa2-47ae-b6df-579a02f3a54d \ @@ -11,14 +11,14 @@ This example is similar to the [Stdin](stdin.md) example, except it assumes the client_options.hostname=testclient3 ``` -Here's a breakdown of the above example: +The example uses these options: -- `stdin`: the method the Adapter should use to collect data locally. The `stdin` value will ingest from the Adapter's STDIN. +- `stdin`: the method that the Adapter uses to collect data locally. The `stdin` value ingests from the STDIN of the Adapter. - `client_options.identity.installation_key=....`: the Installation Key value from LimaCharlie. -- `client_options.identity.oid=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=json`: this indicates that the data read is already JSON, so just parse it as-is. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor ID generated for this Adapter later if you have to re-install the Adapter. -- `client_options.mapping.event_type_path=....`: specifies the field that should be interpreted as the "event_type" in LimaCharlie. +- `client_options.identity.oid=....`: the Organization ID in LimaCharlie that owns the installation key above. +- `client_options.platform=json`: shows that the data is already JSON, so LimaCharlie parses it as-is. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the Adapter. Keep this value. It lets you re-use the Sensor ID of this Adapter if you re-install the Adapter. +- `client_options.mapping.event_type_path=....`: specifies the field that LimaCharlie interprets as the "event_type". - `client_options.hostname=....`: specifies the sensor hostname for the adapter. -Note that we did not need to specify a `parsing_re` or `parsing_grok` because the data ingested is not text, but already JSON, so the parsing step is already done for us by setting `platform=json`. +The example does not specify `parsing_re` or `parsing_grok`. The ingested data is already JSON, and `platform=json` completes the parsing step. diff --git a/docs/2-sensors-deployment/adapters/examples/stdin.md b/docs/2-sensors-deployment/adapters/examples/stdin.md index 9fb2753a4..9917cbae0 100644 --- a/docs/2-sensors-deployment/adapters/examples/stdin.md +++ b/docs/2-sensors-deployment/adapters/examples/stdin.md @@ -1,6 +1,6 @@ # Stdin -This example uses the CLI Adapter to receive data from STDIN. This method is useful for ingesting arbitrary logs on disk or piping output from other applications. +This example uses the CLI Adapter to receive data from STDIN. Use this method to ingest logs on disk, or to pipe the output of another application. ```bash ./lc_adapter stdin client_options.identity.installation_key=e9a3bcdf-efa2-47ae-b6df-579a02f3a54d \ @@ -12,13 +12,13 @@ This example uses the CLI Adapter to receive data from STDIN. This method is use client_options.hostname=testclient3 ``` -Here's a breakdown of the above example: +The example uses these options: -- `stdin`: the method the Adapter should use to collect data locally. The `stdin` value will ingest from the Adapter's STDIN. +- `stdin`: the method that the Adapter uses to collect data locally. The `stdin` value ingests from the STDIN of the Adapter. - `client_options.identity.installation_key=....`: the Installation Key value from LimaCharlie. -- `client_options.identity.oid=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=text`: this indicates the type of data that will be received from this adapter. In this case it's `text` lines. -- `client_options.mapping.parsing_grok.message=....`: this is the grok expression describing how to interpret the text lines and how to convert them to JSON. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor ID generated for this Adapter later if you have to re-install the Adapter. -- `client_options.mapping.event_type_path=....`: specifies the field that should be interpreted as the "event_type" in LimaCharlie. +- `client_options.identity.oid=....`: the Organization ID in LimaCharlie that owns the installation key above. +- `client_options.platform=text`: the type of data that this adapter receives. In this example, the data is `text` lines. +- `client_options.mapping.parsing_grok.message=....`: the grok expression that describes how to interpret the text lines and how to convert them to JSON. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the Adapter. Keep this value. It lets you re-use the Sensor ID of this Adapter if you re-install the Adapter. +- `client_options.mapping.event_type_path=....`: specifies the field that LimaCharlie interprets as the "event_type". - `client_options.hostname=....`: specifies the sensor hostname for the adapter. diff --git a/docs/2-sensors-deployment/adapters/examples/windows-event-logs.md b/docs/2-sensors-deployment/adapters/examples/windows-event-logs.md index 757c39856..454334417 100644 --- a/docs/2-sensors-deployment/adapters/examples/windows-event-logs.md +++ b/docs/2-sensors-deployment/adapters/examples/windows-event-logs.md @@ -1,6 +1,6 @@ # Windows Event Logs -This example shows collecting Windows Event Logs (`wel`) from a Windows box natively (and therefore is only available using the Windows Adapter). This is useful for cases where you'd like to collect WEL without running the LimaCharlie Windows Agent. +This example collects Windows Event Logs (`wel`) natively from a Windows machine. Only the Windows Adapter can do this. Use this method to collect WEL without the LimaCharlie Windows Agent. Note: This example uses PowerShell backtick (`` ` ``) line continuation. On Linux/macOS shells, use backslash (`\`) instead. @@ -13,12 +13,12 @@ Note: This example uses PowerShell backtick (`` ` ``) line continuation. On Linu evt_sources=security:*,application:*,system:*,Microsoft-Windows-Windows Defender/Operational:* ``` -Here's a breakdown of the above example: +The example uses these options: -- `wel`: the method the Adapter should use to collect data locally. The `wel` value will use a native local Windows Event Logs subscription. +- `wel`: the method that the Adapter uses to collect data locally. The `wel` value uses a native local subscription to Windows Event Logs. - `client_options.identity.installation_key=....`: the Installation Key value from LimaCharlie. -- `client_options.identity.oid=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=wel`: this indicates the type of data that will be received from this adapter. In this case it's `wel` events. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor ID generated for this Adapter later if you have to re-install the Adapter. +- `client_options.identity.oid=....`: the Organization ID in LimaCharlie that owns the installation key above. +- `client_options.platform=wel`: the type of data that this adapter receives. In this example, the data is `wel` events. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the Adapter. Keep this value. It lets you re-use the Sensor ID of this Adapter if you re-install the Adapter. - `client_options.hostname=....`: specifies the sensor hostname for the adapter. -- `evt_sources=....`: a comma separated list of event channels to collect along with an XPath filter expression for each. The format is `CHANNEL_NAME:FILTER_EXPRESSION` where a filter of `*` means all events. Common channels: `security`, `system` and `application`. +- `evt_sources=....`: a comma separated list of event channels to collect, with an XPath filter expression for each channel. The format is `CHANNEL_NAME:FILTER_EXPRESSION`. A filter of `*` selects all events. Common channels: `security`, `system` and `application`. diff --git a/docs/2-sensors-deployment/adapters/index.md b/docs/2-sensors-deployment/adapters/index.md index 7ec307036..b758ced87 100644 --- a/docs/2-sensors-deployment/adapters/index.md +++ b/docs/2-sensors-deployment/adapters/index.md @@ -1,6 +1,6 @@ # Adapters -Adapters enable log ingestion from external sources into LimaCharlie. They transform various log formats into normalized LimaCharlie events. +Adapters ingest logs from external sources into LimaCharlie. They change many log formats into normalized LimaCharlie events. ## Deployment Options diff --git a/docs/2-sensors-deployment/adapters/tutorials/cloud-telemetry.md b/docs/2-sensors-deployment/adapters/tutorials/cloud-telemetry.md index 0da636c8c..98e870de2 100644 --- a/docs/2-sensors-deployment/adapters/tutorials/cloud-telemetry.md +++ b/docs/2-sensors-deployment/adapters/tutorials/cloud-telemetry.md @@ -1,22 +1,26 @@ # Tutorial: Ingesting Telemetry from Cloud-Based External Sources -LimaCharlie allows for ingestion of logs or telemetry from any external source in real-time. It includes built-in parsing for popular formats, with the option to define your own for custom sources. +LimaCharlie ingests logs or telemetry from any external source in real-time. It has built-in parsing for common formats. For a custom source, you can define your own parsing. There are two ways to ingest logs or telemetry from external sources: - Run the [LimaCharlie Adapter](../usage.md) on premises or on your cloud -- Provide credentials for the destination and allow LimaCharlie cloud to connect directly (available for cloud-based Adapters) +- Give the credentials for the destination and let the LimaCharlie cloud connect directly (available for cloud-based Adapters) -To connect with the cloud-based external source, first ensure you have the appropriate `cloudsensor.*` permissions. +To connect to a cloud-based external source, first make sure that you have the necessary `cloudsensor.*` permissions. -After the permissions have been enabled, navigate to the `Sensors` page of the web app and click `Add Sensor`. +After you enable the permissions, do these steps: -Choose an external source you would like to ingest logs or telemetry from, or filter the list to only include `Cloud & External Sources` to see available options. +1. In the web app, go to the `Sensors` page. +2. Click `Add Sensor`. +3. Choose the external source that you want to ingest logs or telemetry from. To see the available options, filter the list to `Cloud & External Sources`. -If there is an external source you wish to connect that is not listed, you can still ingest via the LimaCharlie Adapter with self-defined parsing. Alternatively, please contact us to discuss adding this source in LimaCharlie. + If an external source is not in the list, you can ingest it with the LimaCharlie Adapter and your own parsing. You can also contact LimaCharlie to discuss support for that source. -After selecting the Sensor type, choose or create an Installation Key. Then, enter the name for the sensor and provide method-specific credentials for connection. +4. Choose or create an Installation Key. +5. Enter the name for the sensor. +6. Enter the method-specific credentials for the connection. -If the sensor you selected is cloud-based, you will see the call to action `Complete Cloud Installation`. +If the sensor that you selected is cloud-based, the `Complete Cloud Installation` action is shown. -*Note: Sensors that support cloud to cloud communication, can also be installed by running an adapter on-prem or on cloud hosted by the customer. While it is a rare scenario, some customers might prefer that option when they do not want to share the sensor's API credentials with LimaCharlie.* +*Note: You can also install a sensor that supports cloud to cloud communication with an adapter on-prem, or on a cloud that the customer hosts. This scenario is rare. Some customers prefer this option because they do not want to share the API credentials of the sensor with LimaCharlie.* diff --git a/docs/2-sensors-deployment/adapters/tutorials/google-cloud-logs.md b/docs/2-sensors-deployment/adapters/tutorials/google-cloud-logs.md index e256e9f4b..abd517ad8 100644 --- a/docs/2-sensors-deployment/adapters/tutorials/google-cloud-logs.md +++ b/docs/2-sensors-deployment/adapters/tutorials/google-cloud-logs.md @@ -1,6 +1,6 @@ # Tutorial: Ingesting Google Cloud Logs -With LimaCharlie, you can easily ingest Google Cloud logs for further processing and automation. This article covers the following high-level steps of shipping logs from GCP into LimaCharlie: +With LimaCharlie, you can ingest Google Cloud logs for more processing and automation. This article gives the high-level steps to send logs from GCP into LimaCharlie: 1. Create a Log Sink to Pubsub in GCP 2. Create a Subscription for the Topic @@ -9,156 +9,146 @@ With LimaCharlie, you can easily ingest Google Cloud logs for further processing 5. Create an Installation Key in LimaCharlie 6. Run the LC Adapter to ingest the logs. -Note: This tutorial is a synthesized version of this [official GCP article](https://cloud.google.com/logging/docs/export/configure_export_v2). +Note: This tutorial is a synthesized version of the [official GCP article](https://cloud.google.com/logging/docs/export/configure_export_v2). ## Step 1: Create a Log Sink -In your GCP Project, or Organization, go to the Logging product and the Logs Router section. +1. In your GCP Project, or Organization, go to the Logging product and the Logs Router section. -![image.png](../../../assets/images/image(145).png) + ![image.png](../../../assets/images/image(145).png) -Click the Create Sink button, give it a Name and Description. +2. Click the Create Sink button. +3. Give the sink a Name and Description. +4. In the Sink Destination, choose Cloud Pub/Sub Topic as a sink service. +5. Below, select Create a Topic. -In the Sink Destination choose Cloud Pub/Sub Topic as a sink service. + ![image.png](../../../assets/images/image(146).png) -Below, select Create a Topic. +6. Give the Topic an ID. +7. Click Create Topic. The creation of the Topic takes a few seconds. +8. Click Next. +9. Choose the logs to include. Select only the logs that you want, because GCP logs can be verbose. -![image.png](../../../assets/images/image(146).png) + ![image.png](../../../assets/images/image(147).png) -Give the Topic an ID and click Create Topic. + To open the main logging interface, click the Preview Logs button in the top right. In that interface you can test different log selections. -The Topic should now be creating, which can take a few seconds. + This example uses this log filter: -Click Next. + ```text + logName:cloudaudit.googleapis.com + protoPayload.serviceName!="k8s.io" + protoPayload.serviceName!="compute.googleapis.com" + ``` -Now you need to choose which logs you want included. Be careful selecting exactly what you want as GCP logs can get very verbose. + This filter includes all cloudaudit logs, except some GKE and GCE logs. -![image.png](../../../assets/images/image(147).png) +10. Click Next. You can also define an exclusion filter. This example does not use one. +11. Click Create Sink. A confirmation shows that the sink was created. -Click the Preview Logs button in the top right to be taken to the main logging interface where you can experiment with selecting the right logs. - -For this example, let's use the following log filter: - -```text -logName:cloudaudit.googleapis.com -protoPayload.serviceName!="k8s.io" -protoPayload.serviceName!="compute.googleapis.com" -``` - -This filter will include all cloudaudit logs, except some GKE and GCE logs. - -Click Next. You can optionally define an exclusion filter. Let's skip this step. - -Click Create Sink. You should get a confirmation the sink was created. - -![image.png](../../../assets/images/image(148).png) + ![image.png](../../../assets/images/image(148).png) ## Step 2: Create a Subscription -Go to the Pubsub product. - -![image.png](../../../assets/images/image(149).png) - -Click on your new Topic. +1. Go to the Pubsub product. -Click on the Create Subscription button and select Create Subscription. + ![image.png](../../../assets/images/image(149).png) -![image.png](../../../assets/images/image(150).png) +2. Click your new Topic. +3. Click the Create Subscription button. +4. Select Create Subscription. -Give this Subscription a name, you will need this name later when configuring the Adapter. + ![image.png](../../../assets/images/image(150).png) -You can leave all other options to their default. Click Create. +5. Give this Subscription a name. You need this name later, when you configure the Adapter. +6. Keep the default value of all other options. +7. Click Create. ## Step 3: Create a Service Account -Head over to the IAM & Admin product. Then the Service Accounts section. +1. Go to the IAM & Admin product, then to the Service Accounts section. -![image.png](../../../assets/images/image(151).png) + ![image.png](../../../assets/images/image(151).png) -Click Create Service Account. +2. Click Create Service Account. +3. Give the new Service Account a Name and Description. +4. Click Create and Continue. +5. Select the Pub/Sub Subscriber role. -Give the new Service Account a Name and Description. Click Create and Continue. + ![image.png](../../../assets/images/image(152).png) -Select a Role. You want to select Pub/Sub Subscriber. +6. Click Continue. +7. Click Done. -![image.png](../../../assets/images/image(152).png) - -Click Continue. And finally click Done. - -This new Service Account has access to the Topic created. +The new Service Account has access to the Topic that you created. ## [OPTIONAL] Step 4: Create a GCE Instance -This step is optional. You may already have a machine you want to run the collector from, in which case you can skip this step. - -Head over to the Compute Engine product. - -![image.png](../../../assets/images/image(153).png) +This step is optional. If you already have a machine that can run the collector, go to the next step. -Click the Create Instance button. +1. Go to the Compute Engine product. -There is a lot you can customize here, but we'll skip over the more complex aspects you don't need to worry about here. + ![image.png](../../../assets/images/image(153).png) -- Give the instance a name. -- Select a zone nearby the LimaCharlie datacenter you're using. -- As a Machine Type, select e2-micro (the smallest and cheapest machine type). -- In the Identity and API access section, select the Service Account you created earlier. This will set this service account as the default identity of the machine, which in turn means you won't have to specify your credentials to the LimaCharlie Adapter we're about to run. +2. Click the Create Instance button. +3. Set these options. You can customize more options, but this tutorial does not use them. -Click Create. This may take a minute. + - Give the instance a name. + - Select a zone near the LimaCharlie datacenter that you use. + - As a Machine Type, select e2-micro (the smallest and cheapest machine type). + - In the Identity and API access section, select the Service Account that you created earlier. This sets the service account as the default identity of the machine. You then do not give your credentials to the LimaCharlie Adapter. -Once created, click the SSH button to log on the machine. +4. Click Create. This can take a minute. +5. After the instance is created, click the SSH button to log on to the machine. -![image.png](../../../assets/images/image(154).png) + ![image.png](../../../assets/images/image(154).png) -This will bring you to a console on the machine, ready to install the Adapter. +A console opens on the machine. You can now install the Adapter. ## Step 5: Create an Installation Key in LimaCharlie -In your Org in LimaCharlie, go to the Sensors > Installation Keys section. +1. In your Org in LimaCharlie, go to the Sensors > Installation Keys section. +2. Click the Create Installation Key button. +3. Enter a name for the key. This name does not change the name of the source of the logs. +4. Click the copy-to-clipboard button next to the Adapter Key column. **The value is a UUID. Keep it, because you need it in the next step.** -Click the Create Installation Key button. Enter a name for the key. This name will not impact the name given to the source of the logs. - -Click on the copy-to-clipboard button next to the Adapter Key column. **The value should be a UUID, keep note of it, you'll need it in the next step.** - -![Click the Create Installation Key button](../../../assets/images/image(309).png) + ![Click the Create Installation Key button](../../../assets/images/image(309).png) ## Step 6: Run the Adapter -First let's download the latest adapter for Linux. - -```bash -curl -L https://downloads.limacharlie.io/adapter/linux/64 -o lc_adapter -chmod +x lc_adapter -``` +1. Download the latest adapter for Linux. -We can confirm the adapter is running as expected: + ```bash + curl -L https://downloads.limacharlie.io/adapter/linux/64 -o lc_adapter + chmod +x lc_adapter + ``` -```bash -./lc_adapter -``` +2. Check that the adapter runs. -You should see all the options available to all the collection methods being printed to the console. + ```bash + ./lc_adapter + ``` -Now let's run the adapter with all the relevant configurations, replacing the various values necessary. + The console prints all the options that are available to all the collection methods. -```bash -./lc_adapter pubsub \ -client_options.identity.installation_key=YOUR_INSTALLATION_KEY \ -client_options.identity.oid=YOUR_LC_OID \ -client_options.platform=gcp \ -sub_name=YOUR_SUBSCRIPTION_NAME \ -project_name=YOUR_GCP_PROJECT_NAME \ -client_options.sensor_seed_key=SOME_ARBITRARY_ADAPTER_NAME -``` +3. Run the adapter with the necessary configuration. Replace each value with your own. -You should see some text letting you know the adapter is connecting to LimaCharlie, and if any errors occur fetching data from pubsub. + ```bash + ./lc_adapter pubsub \ + client_options.identity.installation_key=YOUR_INSTALLATION_KEY \ + client_options.identity.oid=YOUR_LC_OID \ + client_options.platform=gcp \ + sub_name=YOUR_SUBSCRIPTION_NAME \ + project_name=YOUR_GCP_PROJECT_NAME \ + client_options.sensor_seed_key=SOME_ARBITRARY_ADAPTER_NAME + ``` -Within a few seconds you should see the new Sensor in your Sensor List in LimaCharlie. +The adapter prints text about the connection to LimaCharlie. It also prints the errors that occur when it fetches data from pubsub. -Within a minute or two you should see the events flowing in the Timeline section of this new sensor. +The new Sensor is shown in your Sensor List in LimaCharlie after a few seconds. -That's it, you're good to go! +The events are shown in the Timeline section of the new sensor after one or two minutes. -The next step towards production would be to run the Adapter as a service, or within tmux/screen on the Linux host. Alternatively you could also replicate the above setup using the [Docker container](https://hub.docker.com/r/refractionpoint/lc-adapter) and a serverless platform like Cloud Run. +For production, run the Adapter as a service, or in tmux or screen on the Linux host. You can also repeat this setup with the [Docker container](https://hub.docker.com/r/refractionpoint/lc-adapter) and a serverless platform such as Cloud Run. For more documentation, see [Configuring Adapters](../usage.md). diff --git a/docs/2-sensors-deployment/adapters/tutorials/otel-webhook.md b/docs/2-sensors-deployment/adapters/tutorials/otel-webhook.md index 87624b05b..1a2327792 100644 --- a/docs/2-sensors-deployment/adapters/tutorials/otel-webhook.md +++ b/docs/2-sensors-deployment/adapters/tutorials/otel-webhook.md @@ -1,12 +1,12 @@ # Tutorial: Ingesting OpenTelemetry Data via Webhook -LimaCharlie webhook adapters support the [OpenTelemetry Protocol (OTLP)](https://opentelemetry.io/docs/specs/otlp/) over HTTP, allowing you to send OTel **logs**, **traces**, and **metrics** directly into LimaCharlie without running a separate collector. +LimaCharlie webhook adapters support the [OpenTelemetry Protocol (OTLP)](https://opentelemetry.io/docs/specs/otlp/) over HTTP. You can send OTel **logs**, **traces**, and **metrics** directly into LimaCharlie without a separate collector. -This builds on the standard [Webhook Adapter](webhook-adapter.md). If you haven't already, review that page first to understand webhook creation and configuration. +This tutorial builds on the standard [Webhook Adapter](webhook-adapter.md). Read that page first to learn how to create and configure a webhook. ## How It Works -OpenTelemetry SDKs and collectors export telemetry by sending HTTP POST requests to an OTLP endpoint. LimaCharlie's webhook gateway recognizes OTLP paths appended to the standard webhook URL and automatically parses the protobuf or JSON payloads into individual events. +OpenTelemetry SDKs and collectors export telemetry with HTTP POST requests to an OTLP endpoint. The LimaCharlie webhook gateway recognizes OTLP paths that you add to the standard webhook URL. It parses the protobuf or JSON payloads into single events. The URL pattern is: @@ -22,7 +22,7 @@ Where `` is one of: | `traces` | `/v1/traces` | Spans from OTel tracing SDKs | | `metrics` | `/v1/metrics` | Metric data points from OTel metrics SDKs | -This matches the standard OTLP HTTP path convention, so OTel SDKs work out of the box by setting the base endpoint URL to your webhook URL. +This is the standard OTLP HTTP path convention. Set the base endpoint URL of the OTel SDK to your webhook URL, and the SDK operates correctly. ## Supported Content Types @@ -35,9 +35,9 @@ This matches the standard OTLP HTTP path convention, so OTel SDKs work out of th ### 1. Create a Webhook Adapter -Follow the [Webhook Adapter tutorial](webhook-adapter.md) to create a webhook. The configuration is identical - no special settings are needed for OTel support. +Obey the [Webhook Adapter tutorial](webhook-adapter.md) to create a webhook. The configuration is the same - OTel support needs no special settings. -For example, using the CLI: +For example, with the CLI: ```bash echo '{ @@ -59,13 +59,13 @@ echo '{ ### 2. Get Your Webhook URL -Retrieve your hook domain: +Get your hook domain: ```bash limacharlie org urls ``` -This returns a domain like `9157798c50af372c.hook.limacharlie.io`. Your full OTLP base endpoint is: +The command returns a domain such as `9157798c50af372c.hook.limacharlie.io`. Your full OTLP base endpoint is: ```text https://9157798c50af372c.hook.limacharlie.io//otel-hook/my-otel-secret @@ -73,7 +73,7 @@ https://9157798c50af372c.hook.limacharlie.io//otel-hook/my-otel-secret ### 3. Configure Your OTel SDK or Collector -Set the OTLP HTTP exporter endpoint to your webhook URL. The OTel SDK will automatically append `/v1/logs`, `/v1/traces`, or `/v1/metrics` as needed. +Set the OTLP HTTP exporter endpoint to your webhook URL. The OTel SDK adds `/v1/logs`, `/v1/traces`, or `/v1/metrics` automatically, as necessary. #### Environment Variables (any OTel SDK) @@ -83,7 +83,7 @@ export OTEL_EXPORTER_OTLP_ENDPOINT="https://9157798c50af372c.hook.limacharlie.io export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" ``` -You can also configure per-signal endpoints: +You can also configure an endpoint for each signal: ```bash export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://9157798c50af372c.hook.limacharlie.io//otel-hook/my-otel-secret/v1/logs" @@ -93,7 +93,7 @@ export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="https://9157798c50af372c.hook.limach #### OTel Collector Configuration -If you're running an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), configure an `otlphttp` exporter: +If you run an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), configure an `otlphttp` exporter: ```yaml exporters: @@ -112,11 +112,11 @@ service: ## Event Format -Each OTel record is converted into a JSON event and ingested as a LimaCharlie event on the webhook sensor's timeline. All events include an `otel_type` field to identify their type. +LimaCharlie converts each OTel record into a JSON event. It ingests the event on the timeline of the webhook sensor. Each event has an `otel_type` field that identifies the type. ### Log Events -Each OTel `LogRecord` becomes an event with the following fields: +Each OTel `LogRecord` becomes an event with these fields: | Field | Description | |-----------------------------|----------------------------------------------------------------| @@ -182,7 +182,7 @@ Each OTel `Span` becomes an event: ### Metric Events -Each metric data point becomes a separate event. The `metric_type` field indicates the aggregation type: +Each metric data point becomes a separate event. The `metric_type` field shows the aggregation type: | `metric_type` | Description | |---------------------------|--------------------------------------| @@ -192,7 +192,7 @@ Each metric data point becomes a separate event. The `metric_type` field indicat | `summary` | Pre-computed quantiles | | `exponential_histogram` | Distribution with exponential buckets| -Common fields across all metric types: +Common fields for all metric types: | Field | Description | |------------------------|---------------------------------------------------------| @@ -206,11 +206,11 @@ Common fields across all metric types: | `description` | Metric description (if provided) | | `unit` | Metric unit (if provided) | -For `gauge` and `sum` types, the `value` field contains the numeric value. For `sum`, additional fields `is_monotonic` and `aggregation_temporality` are included. +For the `gauge` and `sum` types, the `value` field contains the numeric value. The `sum` type also has the `is_monotonic` and `aggregation_temporality` fields. ## Writing D&R Rules for OTel Events -OTel events flow through the same D&R rule evaluation as regular webhook events. You can write rules that target the `otel_type` field or any other field in the event. +The same D&R rule evaluation applies to OTel events and to other webhook events. You can write rules that target the `otel_type` field, or any other field in the event. Example D&R rule to detect error-level OTel logs: @@ -230,7 +230,7 @@ respond: ## Backward Compatibility -Standard (non-OTel) webhook requests to `///` continue to work exactly as before. OTel support is activated only when the URL contains the `/v1/logs`, `/v1/traces`, or `/v1/metrics` suffix. +Standard (non-OTel) webhook requests to `///` continue to operate as before. OTel support starts only when the URL contains the `/v1/logs`, `/v1/traces`, or `/v1/metrics` suffix. ## Related Articles diff --git a/docs/2-sensors-deployment/adapters/tutorials/webhook-adapter.md b/docs/2-sensors-deployment/adapters/tutorials/webhook-adapter.md index 81f23bf1f..941a49ca6 100644 --- a/docs/2-sensors-deployment/adapters/tutorials/webhook-adapter.md +++ b/docs/2-sensors-deployment/adapters/tutorials/webhook-adapter.md @@ -1,12 +1,12 @@ # Tutorial: Creating a Webhook Adapter -LimaCharlie supports webhooks as a telemetry ingestion method. Webhooks are technically cloud [Adapters](../deployment.md), as they cannot be deployed on-prem or through the downloadable Adapter binary. +LimaCharlie supports webhooks as a method to ingest telemetry. Webhooks are cloud [Adapters](../deployment.md), because you cannot deploy them on-prem or with the downloadable Adapter binary. -Webhook adapters are created by enabling a webhook through the `cloud_sensor` Hive feature. Webhook creation will enable a specific URL that can receive webhooks from any platform. Received data will be ingested in LimaCharlie as a Sensor, similar to an Office365 or Syslog Adapter. +To create a webhook adapter, enable a webhook with the `cloud_sensor` Hive feature. The webhook enables a specific URL that can receive webhooks from any platform. LimaCharlie ingests the received data as a Sensor, like an Office365 or Syslog Adapter. ## Creating a Webhook Adapter -Webhook adapters can be created either through the webapp, API, or CLI. Before creation, let's look at the basic webhook configuration and values necessary to build the adapter. +You can create a webhook adapter with the web app, the API, or the CLI. First, examine the basic webhook configuration and the values that the adapter needs. ```json { @@ -31,21 +31,21 @@ Webhook adapters can be created either through the webapp, API, or CLI. Before c Field descriptions: -- `secret`: this secret value will be part of the URL to accept your webhooks. It enables you to prevent or revoke unauthorized access to a hook. -- `signature_secret`, `signature_header`, `signature_scheme`: placeholders for generic webhook signature validation. If you require a specific format, please get in touch with us. -- `client_options.hostname`: provide your own name for the webhook adapter. -- `client_options.identity.oid`: the OID of the organization you wish to send to. -- `client_options.identity.installation_key`: the installation key to be used for the adapter. -- `client_options.platform`: the data format (typically `json` for webhooks). -- `client_options.sensor_seed_key`: an arbitrary value used to generate a stable Sensor ID. +- `secret`: the secret value that is part of the URL that accepts your webhooks. Use it to stop or revoke unauthorized access to a hook. +- `signature_secret`, `signature_header`, `signature_scheme`: placeholders for generic validation of webhook signatures. If you need a specific format, contact LimaCharlie. +- `client_options.hostname`: your own name for the webhook adapter. +- `client_options.identity.oid`: the OID of the organization that receives the data. +- `client_options.identity.installation_key`: the installation key for the adapter. +- `client_options.platform`: the data format (usually `json` for webhooks). +- `client_options.sensor_seed_key`: an arbitrary value that generates a stable Sensor ID. -When the above configuration is provided to LimaCharlie, a webhook adapter will appear and be available for webhook event ingestion. Here's an example of creating the above record through the LimaCharlie CLI: +When you give this configuration to LimaCharlie, the webhook adapter appears and can ingest webhook events. This example creates the record with the LimaCharlie CLI: ```bash echo '{"sensor_type": "webhook", "webhook": {"secret": "some-secret-value-hard-to-predict", "signature_secret": "", "signature_header": "", "signature_scheme": "", "client_options": {"hostname": "", "identity": {"oid": "", "installation_key": ""}, "platform": "json", "sensor_seed_key": "test-webhook"}}}' | limacharlie hive set cloud_sensor --key my-webhook --data - ``` -After creating the webhook, you will be provided with a geo-dependent URL, respective to your LimaCharlie Organization location. You can also retrieve your webhook URLs with either of the following commands: +After you create the webhook, LimaCharlie gives you a geo-dependent URL for the location of your LimaCharlie Organization. You can also get your webhook URLs with one of these commands: - REST API: [getOrgURLs](https://api.limacharlie.io/static/swagger/#/Org/get_orgs__oid___urls) - Python SDK: @@ -56,19 +56,19 @@ python3 -c "from limacharlie.client import Client; from limacharlie.sdk.organiza ## Using the webhook adapter -After capturing the webhook URL in the previous step, only a few more pieces of data are necessary to construct the webhook ingestion. +After you get the webhook URL in the previous step, you need only a few more values to construct the webhook ingestion. -Let's assume the returned domain looks like `9157798c50af372c.hook.limacharlie.io`, the format of the URL would be: +If the returned domain is `9157798c50af372c.hook.limacharlie.io`, the URL format is: `https://9157798c50af372c.hook.limacharlie.io/OID/HOOKNAME/SECRET`, where: -- OID is the Organization OID provided in the configuration above. -- HOOKNAME is the name of the hook provided in the configuration above. -- SECRET is the secret value provided in the configuration. You can provide the secret value in the URL or as an HTTP header named `lc-secret`. +- OID is the Organization OID from the configuration above. +- HOOKNAME is the name of the hook from the configuration above. +- SECRET is the secret value from the configuration. Put the secret value in the URL, or in an HTTP header named `lc-secret`. ## Supported Webhook Format -When sending data via POST requests to the URL, the body of your request is expected to be one or many JSON events. Supported formats include: +When you send data with POST requests to the URL, the body of the request must be one or more JSON events. These formats are supported: - Simple JSON object: @@ -84,6 +84,6 @@ When sending data via POST requests to the URL, the body of your request is expe {"some":"data"} ``` -Or, one of the above, but compressed using gzip. +You can also compress one of these formats with gzip. -With the completed webhook URL, you can begin sending events and will see them in the Timeline for your webhook Adapter. +With the complete webhook URL, you can send events. The events are shown in the Timeline of your webhook Adapter. diff --git a/docs/2-sensors-deployment/adapters/types/1password.md b/docs/2-sensors-deployment/adapters/types/1password.md index 2aa0c637c..8bad36194 100644 --- a/docs/2-sensors-deployment/adapters/types/1password.md +++ b/docs/2-sensors-deployment/adapters/types/1password.md @@ -1,23 +1,23 @@ # 1Password -[1Password](https://1password.com/) provides an events API to fetch audit logs. Events can be ingested directly via a cloud-to-cloud or CLI Adapter. +[1Password](https://1password.com/) has an events API that supplies audit logs. A cloud-to-cloud adapter or a CLI adapter can ingest these events. See [1Password's official Events API documentation](https://developer.1password.com/docs/events-api/reference/). -1Password telemetry can be addressed via the `1password` platform. +You address 1Password telemetry with the `1password` platform. ## Adapter Deployment -1Password events can be collected directly from the 1Password API, via a cloud-to-cloud Adapter, or via the CLI Adapter. 1Password adapters require the following options: +A cloud-to-cloud adapter or a CLI adapter collects 1Password events directly from the 1Password API. 1Password adapters need these options: -- `token`: the API token provisioned through 1password. -- `endpoint`: the API endpoint to use, depending on your 1password plan, see their documentation below. +- `token`: the API token that you create in 1Password. +- `endpoint`: the API endpoint to use. The endpoint depends on your 1Password plan. See the 1Password documentation. -You can generate an access token from 1Password at [this link](https://support.1password.com/events-reporting/). +Create an access token in the [1Password events reporting documentation](https://support.1password.com/events-reporting/). ## Cloud-to-Cloud Adapter -LimaCharlie offers a 1Password guided configuration in the web UI. From your 1Password instance, you will need: +LimaCharlie has a guided configuration for 1Password in the web app. From your 1Password instance, you need: - 1Password API Access Token - Endpoint; one of the following: @@ -27,11 +27,11 @@ LimaCharlie offers a 1Password guided configuration in the web UI. From your 1Pa - 1Password.ca - 1Password.eu -After providing an [Installation Key](../../installation-keys.md), provide the required values and LimaCharlie will establish a Cloud Adapter for 1Password events +Give an [Installation Key](../../installation-keys.md) and the required values. LimaCharlie then creates a cloud adapter for 1Password events. ### Infrastructure as Code Deployment -LimaCharlie IaC Adapter can also be used to ingest 1Password events. +The LimaCharlie IaC adapter can also ingest 1Password events. ```python sensor_type: "1password" diff --git a/docs/2-sensors-deployment/adapters/types/atlassian.md b/docs/2-sensors-deployment/adapters/types/atlassian.md index f9a4605b4..1cf8a4ab7 100644 --- a/docs/2-sensors-deployment/adapters/types/atlassian.md +++ b/docs/2-sensors-deployment/adapters/types/atlassian.md @@ -1,6 +1,6 @@ # Atlassian -[Atlassian](https://www.atlassian.com/) makes a suite of products that help foster enterprise work management, IT service management, and Agile development. Atlassian's products include: +[Atlassian](https://www.atlassian.com/) makes products for enterprise work management, IT service management, and Agile development. The Atlassian products include: - Bitbucket - Confluence @@ -8,23 +8,23 @@ - Opsgenie - Trello -Atlassian has [extensive documentation](https://confluence.atlassian.com/alldoc/atlassian-documentation-32243719.html) for both their Cloud and Data Center/Server editions. +Atlassian has [full documentation](https://confluence.atlassian.com/alldoc/atlassian-documentation-32243719.html) for the Cloud and the Data Center/Server editions. -Currently, LimaCharlie supports ingestion of Jira events. Jira events can be ingested in LimaCharlie via a `json` webhook Adapter. +LimaCharlie supports the ingestion of Jira events. A `json` webhook adapter ingests Jira events into LimaCharlie. ## Adapter Deployment -Jira events are ingested via a cloud-to-cloud webhook Adapter, configured to receive JSON events. In the creation of the Adapter, we map fields directly to the expected Atlassian events. The steps of creating this Adapter and enabling the input include: +A cloud-to-cloud webhook adapter ingests Jira events. You configure the adapter to receive JSON events, and you map the fields to the Atlassian events. To create the adapter and enable the input, do these steps: -1. Creating the webhook Adapter via the LimaCharlie CLI. -2. Discovering the URL created for the webhook Adapter. -3. Providing the completed URL to Jira for webhook events. +1. Create the webhook adapter with the LimaCharlie CLI. +2. Find the URL that LimaCharlie creates for the webhook adapter. +3. Give the complete URL to Jira for webhook events. ### 1. Creating the LimaCharlie Webhook Adapter -These steps are adapted from the [generic webhook adapter creation guide](../tutorials/webhook-adapter.md). +These steps come from the [generic webhook adapter creation guide](../tutorials/webhook-adapter.md). -Creating a Webhook Adapter requires a set of parameters, including organization ID, Installation Key, platform, and mapping details. The following configuration has been provided to configure a webhook Adapter for ingesting Jira events: +A webhook adapter needs a set of parameters: the organization ID, an Installation Key, a platform, and mapping details. This configuration sets up a webhook adapter that ingests Jira events: ```json { @@ -48,37 +48,37 @@ Creating a Webhook Adapter requires a set of parameters, including organization } ``` -The mapping above is based on the expected webhook event from Jira. Note that in the mapping above, we make the following change: +The mapping above matches the webhook event from Jira. The mapping makes these two changes: -- `event_type_path` is mapped to the `webhookEvent` field -- `event_time_path` is mapped to the `timestamp` field +- `event_type_path` maps to the `webhookEvent` field +- `event_time_path` maps to the `timestamp` field ### 2. Building the Webhook URL -After creating the webhook, you'll need to retrieve the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. You'll need the following information to complete the Webhook URL: +After you create the webhook, get the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. To complete the webhook URL, you need this information: - Organization ID - Webhook name (from the config) - Secret (from the config) -Let's assume the returned domain looks like `9157798c50af372c.hook.limacharlie.io`, the format of the URL would be: +If the returned domain is `9157798c50af372c.hook.limacharlie.io`, the URL has this format: `https://9157798c50af372c.hook.limacharlie.io/OID/HOOKNAME/SECRET` -Note that the `secret` value can be provided in the webhook URL or as an HTTP header named `lc-secret`. +You can give the `secret` value in the webhook URL or in an HTTP header named `lc-secret`. ### 3. Providing the URL to Jira for Webhook Events -Within the Atlassian Admin window, navigate to **Jira Administration** > **Jira settings** > **Advanced** > **WebHooks**. Select **+ Create a WebHook**. +In the Atlassian Admin window, go to **Jira Administration** > **Jira settings** > **Advanced** > **WebHooks**. Select **+ Create a WebHook**. ![image.png](../../../assets/images/image(178).png) -- Choose an appropriate name to differentiate that this is a LimaCharlie webhook -- Provide the webhook URL (see step 2 above) -- (optional) Provide a description -- (optional) Provide a JQL query to select certain issues that will trigger Webhooks. The default selection is *All issues*. +- Choose a name that identifies the webhook as a LimaCharlie webhook +- Give the webhook URL (see step 2 above) +- (optional) Give a description +- (optional) Give a JQL query that selects the issues that trigger webhooks. The default selection is *All issues*. -Within the WebHook creation dialog, you can also select the granularity of events to send via the WebHook. High-level event categories include: +In the WebHook creation dialog, you can also select which events the webhook sends. The main event categories are: - Issues - Issue events @@ -93,9 +93,9 @@ Within the WebHook creation dialog, you can also select the granularity of event - Project-related - Jira Software-related -By default, issues will be sent as JSON, which is natively accepted by LimaCharlie. Save your WebHook configuration, and perform an action that you know will trigger the event. +By default, Jira sends issues as JSON. LimaCharlie accepts JSON directly. Save your WebHook configuration, then do an action that triggers the event. -If configured properly, you should see your Jira events in LimaCharlie. Here's an example event: +If the configuration is correct, your Jira events appear in LimaCharlie. This is an example event: ```json { @@ -298,4 +298,4 @@ If configured properly, you should see your Jira events in LimaCharlie. Here's a } ``` -Note that the Jira "webhookEvent" becomes the event type, also represented in the LimaCharlie Adapter timeline. +The Jira "webhookEvent" becomes the event type. The LimaCharlie adapter timeline also shows this event type. diff --git a/docs/2-sensors-deployment/adapters/types/aws-cloudtrail.md b/docs/2-sensors-deployment/adapters/types/aws-cloudtrail.md index 5c4f339aa..0d13fb36a 100644 --- a/docs/2-sensors-deployment/adapters/types/aws-cloudtrail.md +++ b/docs/2-sensors-deployment/adapters/types/aws-cloudtrail.md @@ -1,41 +1,41 @@ # AWS CloudTrail -[AWS CloudTrail](https://docs.aws.amazon.com/cloudtrail/) logs allow you to monitor AWS deployments. CloudTrail logs can provide granular visibility into AWS instances and can be used within D&R rules to identify AWS abuse. +[AWS CloudTrail](https://docs.aws.amazon.com/cloudtrail/) logs let you monitor AWS deployments. CloudTrail logs give detailed visibility into AWS instances. You can use them in D&R rules to find abuse of AWS. -This Adapter allows you to ingest AWS CloudTrail events via either an [S3 bucket](https://aws.amazon.com/s3/) or [SQS message queue](https://aws.amazon.com/sqs/). +This adapter ingests AWS CloudTrail events from an [S3 bucket](https://aws.amazon.com/s3/) or from an [SQS message queue](https://aws.amazon.com/sqs/). -CloudTrail events can be addressed in LimaCharlie as the `aws` platform. +You address CloudTrail events in LimaCharlie with the `aws` platform. ## Adapter Deployment -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter uses. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options -CloudTrail logs can be collected via a cloud-to-cloud Adapter, or via the CLI Adapter. Furthermore, within each option, there is a choice of collecting logs from an S3 bucket or an SQS message queue. +A cloud-to-cloud adapter or a CLI adapter collects CloudTrail logs. With each option, you can collect the logs from an S3 bucket or from an SQS message queue. ## Cloud-to-Cloud Adapter -Within the LimaCharlie web application, you can create an AWS CloudTrail Cloud Connector using the `+ Add Sensor` option. +In the LimaCharlie web app, create an AWS CloudTrail cloud connector with the `+ Add Sensor` option. ![image.png](../../../assets/images/image(160).png) -After providing an Installation Key, you will be guided through connecting either an S3 bucket or SQS queue to ingest AWS CloudTrail events. +After you give an Installation Key, the web app guides you to connect an S3 bucket or an SQS queue that ingests AWS CloudTrail events. ### Collecting AWS CloudTrail Logs via an S3 Bucket -If collecting CloudTrail logs via an S3 bucket, you will need the following parameters: +To collect CloudTrail logs from an S3 bucket, you need these parameters: - `bucket_name` - The name of the S3 bucket holding the data) - `secret_key` - The API key for AWS that has access to the respective bucket. - `access_key` - The AWS access key for the API key -The following sample configuration can be used to create an S3 CLI Adapter for AWS CloudTrail events: +This sample configuration creates an S3 CLI adapter for AWS CloudTrail events: ```yaml s3: @@ -53,14 +53,14 @@ s3: #### Collecting AWS CloudTrail Logs via an SQS Queue -If collecting CloudTrail logs via an SQS queue, you will need the following parameters: +To collect CloudTrail logs from an SQS queue, you need these parameters: - `secret_key` - The API key for AWS that has access to the respective bucket. - `access_key` - The AWS access key for the API key -- `region` - The AWS region where the SQS instance lives +- `region` - The AWS region that contains the SQS instance - `queue_url` - The URL to the SQS instance -The following sample configuration can be used to create an SQS CLI Adapter for AWS CloudTrail events: +This sample configuration creates an SQS CLI adapter for AWS CloudTrail events: ```yaml sqs: diff --git a/docs/2-sensors-deployment/adapters/types/aws-guardduty.md b/docs/2-sensors-deployment/adapters/types/aws-guardduty.md index 7dd9aaf83..8459cd66a 100644 --- a/docs/2-sensors-deployment/adapters/types/aws-guardduty.md +++ b/docs/2-sensors-deployment/adapters/types/aws-guardduty.md @@ -2,7 +2,7 @@ ## Overview -This Adapter allows you to ingest AWS GuardDuty events via either an [S3 bucket](https://aws.amazon.com/s3/) or [SQS message queue](https://aws.amazon.com/sqs/). +This adapter ingests AWS GuardDuty events from an [S3 bucket](https://aws.amazon.com/s3/) or from an [SQS message queue](https://aws.amazon.com/sqs/). [AWS GuardDuty](https://aws.amazon.com/guardduty/) helps you protect your AWS accounts with intelligent threat detection. @@ -10,24 +10,24 @@ Telemetry Platform: `guard_duty` ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter uses. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options #### Collecting AWS GuardDuty Logs via an S3 Bucket -If collecting GuardDuty logs via an S3 bucket, you will need the following parameters: +To collect GuardDuty logs from an S3 bucket, you need these parameters: - `bucket_name` - The name of the S3 bucket holding the data) - `secret_key` - The API key for AWS that has access to the respective bucket. - `access_key` - The AWS access key for the API key -The following command will create an Adapter using the (1) Adapter binary and (2) logs stored in an S3 bucket: +This command creates an adapter that uses the adapter binary and reads logs from an S3 bucket: ```bash ./lc_adapter s3 client_options.identity.installation_key= \ @@ -41,14 +41,14 @@ client_options.hostname=guardduty-logs #### Collecting AWS GuardDuty Logs via an SQS Queue -If collecting GuardDuty logs via an SQS queue, you will need the following parameters: +To collect GuardDuty logs from an SQS queue, you need these parameters: - `secret_key` - The API key for AWS that has access to the respective bucket. - `access_key` - The AWS access key for the API key -- `region` - The AWS region where the SQS instance lives +- `region` - The AWS region that contains the SQS instance - `queue_url` - The URL to the SQS instance -The following command will create an Adapter using the (1) Adapter binary and (2) logs stored in an SQS queue: +This command creates an adapter that uses the adapter binary and reads logs from an SQS queue: ```bash ./lc_adapter sqs client_options.identity.installation_key= \ @@ -64,6 +64,6 @@ region= ## Guided Deployment -Within the LimaCharlie web application, you can create an AWS GuardDuty Cloud Connector using the `+ Add Sensor` option. +In the LimaCharlie web app, create an AWS GuardDuty cloud connector with the `+ Add Sensor` option. ![Add Sensor option for AWS GuardDuty Cloud Connector in the LimaCharlie web application](../../../assets/images/image(304).png) diff --git a/docs/2-sensors-deployment/adapters/types/azure-event-hub.md b/docs/2-sensors-deployment/adapters/types/azure-event-hub.md index e2e88321e..7ffc30d9c 100644 --- a/docs/2-sensors-deployment/adapters/types/azure-event-hub.md +++ b/docs/2-sensors-deployment/adapters/types/azure-event-hub.md @@ -2,9 +2,9 @@ ## Overview -This Adapter allows you to connect to an Azure Event Hub to fetch structured data stored there. +This adapter connects to an Azure Event Hub and fetches the structured data in the hub. -[Azure Event Hubs](https://azure.microsoft.com/en-us/products/event-hubs) are fully managed, real-time data ingestion services that allow for event streaming from various Microsoft Azure services. LimaCharlie can ingest either structured known data (such as JSON or XML) *or* known Microsoft data types, including: +[Azure Event Hubs](https://azure.microsoft.com/en-us/products/event-hubs) are fully managed, real-time data ingestion services. They stream events from Microsoft Azure services. LimaCharlie can ingest known structured data, such as JSON or XML, *or* known Microsoft data types. The Microsoft data types include: - Azure Monitor (Platform: `azure_monitor`) - Entra ID [formerly Azure AD] (Platform: `azure_ad`) @@ -14,13 +14,13 @@ This Adapter allows you to connect to an Azure Event Hub to fetch structured dat - Azure Network Security Group (Platform: `azure_network_security_group`) - Azure SQL Audit (Platform: `azure_sql_audit`) -> **Choosing the platform:** the Event Hub is only a transport — `client_options.platform` selects the LimaCharlie parser and must match the data being streamed **into** the hub (see the list above). Use `json` only for custom or unknown data, in which case you must supply your own `mapping`. Note that `azure_event_hub_namespace` is **not** a generic value for "data arriving via Event Hub": it is used solely for ingesting an Event Hub namespace's own diagnostic logs. +> **Choosing the platform:** the Event Hub is only a transport. `client_options.platform` selects the LimaCharlie parser, and it must match the data that streams **into** the hub (see the list above). Use `json` only for custom or unknown data. With `json`, you must supply your own `mapping`. `azure_event_hub_namespace` is **not** a generic value for "data that arrives through an Event Hub". It ingests only the diagnostic logs of an Event Hub namespace. Microsoft has [documentation for creating an Event Hub](https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-create). ## Configuring Data Streams -When using Azure Event Hub, you must configure the source service to stream data to your Event Hub. The data you receive depends entirely on what you configure in Azure. +When you use an Azure Event Hub, you must configure the source service to stream data to your Event Hub. The data that you receive depends on your configuration in Azure. ### For Entra ID (`azure_ad`) @@ -46,7 +46,7 @@ See: [Defender XDR streaming event types](https://learn.microsoft.com/en-us/defe Configure **Diagnostic Settings** on individual Azure resources: -1. Navigate to the Azure resource you want to monitor +1. Go to the Azure resource that you want to monitor 2. Go to **Diagnostic settings** and add a setting 3. Select your Event Hub and choose logs/metrics to stream @@ -54,29 +54,29 @@ See: [Stream Azure platform logs to Event Hub](https://learn.microsoft.com/en-us ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter uses. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options -- If using a binary Adapter, `azure_event_hub` will be the ingestion type. -- `connection_string` - The connection string provided in Azure for connecting to the Azure Event Hub, including the `EntityPath=...` at the end which identifies the Hub Name (this component is sometimes now shown in the connection string provided by Azure). +- With a binary adapter, the ingestion type is `azure_event_hub`. +- `connection_string` - The connection string that Azure supplies for the Azure Event Hub. It includes the `EntityPath=...` part at the end, which identifies the hub name (this component is sometimes now shown in the connection string provided by Azure). ## Guided Deployment -Azure Event Hub data can be pulled via either a cloud or binary Adapter. +A cloud adapter or a binary adapter can pull Azure Event Hub data. ### Cloud-to-Cloud -LimaCharlie offers several helpers within the webapp that allow you to ingest Microsoft data, such as Entra ID or Microsoft Defender, from Azure Event Hubs. +The LimaCharlie web app has helpers that ingest Microsoft data, such as Entra ID or Microsoft Defender, from Azure Event Hubs. ### CLI Deployment -The following example configures a binary Adapter to collect Microsoft Defender data from an Azure Event Hub: +This example configures a binary adapter that collects Microsoft Defender data from an Azure Event Hub: ```bash ./lc_adapter azure_event_hub client_options.identity.installation_key= \ diff --git a/docs/2-sensors-deployment/adapters/types/azure/key-vault.md b/docs/2-sensors-deployment/adapters/types/azure/key-vault.md index 81e430f27..4f5ef806c 100644 --- a/docs/2-sensors-deployment/adapters/types/azure/key-vault.md +++ b/docs/2-sensors-deployment/adapters/types/azure/key-vault.md @@ -1,19 +1,19 @@ # Azure Key Vault -Azure [Key Vault](https://azure.microsoft.com/en-us/products/key-vault) is a product that helps safeguard cryptographic keys and other secrets used by cloud apps and services. LimaCharlie can ingest and natively parse Key Vault logs. +Azure [Key Vault](https://azure.microsoft.com/en-us/products/key-vault) protects cryptographic keys and other secrets that cloud apps and services use. LimaCharlie can ingest and parse Key Vault logs directly. ## Log Ingestion -Azure Key Vault logs can be ingested via: +You can ingest Azure Key Vault logs through: - [Azure Event Hub](../azure-event-hub.md) - LimaCharlie [Webhooks](../../tutorials/webhook-adapter.md) -When configuring the adapter, set `client_options.platform: azure_key_vault` to select the dedicated parser. Upon ingestion, the log `category` field is used to define the Event Type and the `time` field provides the event timestamp. +When you configure the adapter, set `client_options.platform: azure_key_vault` to select the dedicated parser. At ingestion, the log `category` field sets the event type, and the `time` field supplies the event timestamp. ## Sample Event -The following sample event is taken from Microsoft Azure documentation: +This sample event comes from the Microsoft Azure documentation: ```json { diff --git a/docs/2-sensors-deployment/adapters/types/azure/kubernetes-service.md b/docs/2-sensors-deployment/adapters/types/azure/kubernetes-service.md index d7ed8b168..c0a1d5bf2 100644 --- a/docs/2-sensors-deployment/adapters/types/azure/kubernetes-service.md +++ b/docs/2-sensors-deployment/adapters/types/azure/kubernetes-service.md @@ -1,14 +1,14 @@ # Azure Kubernetes Service (AKS) -[Azure Kubernetes Service](https://azure.microsoft.com/en-us/products/kubernetes-service) (AKS) is a quick way to start developing and deploying cloud-native apps in Azure. LimaCharlie can ingest Azure Kubernetes Service logs. +[Azure Kubernetes Service](https://azure.microsoft.com/en-us/products/kubernetes-service) (AKS) is a quick way to start the development and deployment of cloud-native apps in Azure. LimaCharlie can ingest Azure Kubernetes Service logs. Microsoft has [more information about Azure Kubernetes logs and metrics](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-livedata-overview). ## Log Ingestion -AKS logs can be ingested via: +You can ingest AKS logs through: - [Azure Event Hub](../azure-event-hub.md) - LimaCharlie [Webhooks](../../tutorials/webhook-adapter.md) -When configuring the adapter, set `client_options.platform: azure_kubernetes_service` to select the dedicated parser. Upon ingestion, the log `category` field is used to define the Event Type and the `time` field provides the event timestamp. +When you configure the adapter, set `client_options.platform: azure_kubernetes_service` to select the dedicated parser. At ingestion, the log `category` field sets the event type, and the `time` field supplies the event timestamp. diff --git a/docs/2-sensors-deployment/adapters/types/azure/monitor.md b/docs/2-sensors-deployment/adapters/types/azure/monitor.md index da221da4e..c9efdfa3f 100644 --- a/docs/2-sensors-deployment/adapters/types/azure/monitor.md +++ b/docs/2-sensors-deployment/adapters/types/azure/monitor.md @@ -1,14 +1,14 @@ # Azure Monitor -Azure Monitor Logs are a feature of Azure Monitor that collect and organize log and performance data from monitored resources. See Microsoft's [Azure Monitor Logs reference](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-platform-logs) for more detail. +Azure Monitor Logs are a feature of Azure Monitor. They collect and organize log data and performance data from monitored resources. For more detail, see the Microsoft [Azure Monitor Logs reference](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-platform-logs). -LimaCharlie can ingest and natively parse Azure Monitor Logs. +LimaCharlie can ingest and parse Azure Monitor Logs directly. ## Log Ingestion -Azure Monitor logs can be ingested via: +You can ingest Azure Monitor logs through: - [Azure Event Hub](../azure-event-hub.md) - LimaCharlie [Webhooks](../../tutorials/webhook-adapter.md) -When configuring the adapter, set `client_options.platform: azure_monitor` to select the dedicated parser. Upon ingestion, the log `category` field is used to define the Event Type and the `time` field provides the event timestamp. +When you configure the adapter, set `client_options.platform: azure_monitor` to select the dedicated parser. At ingestion, the log `category` field sets the event type, and the `time` field supplies the event timestamp. diff --git a/docs/2-sensors-deployment/adapters/types/azure/network-security-group.md b/docs/2-sensors-deployment/adapters/types/azure/network-security-group.md index c25d1b9f3..f6b8a1088 100644 --- a/docs/2-sensors-deployment/adapters/types/azure/network-security-group.md +++ b/docs/2-sensors-deployment/adapters/types/azure/network-security-group.md @@ -1,14 +1,14 @@ # Azure Network Security Group -Azure Network security groups help filter network traffic between Azure resources in an Azure virtual network. See Microsoft's [Network security groups overview](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview) for more detail. +Azure network security groups filter network traffic between Azure resources in an Azure virtual network. For more detail, see the Microsoft [Network security groups overview](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview). -LimaCharlie can ingest and natively parse Azure Network Security Group logs. +LimaCharlie can ingest and parse Azure Network Security Group logs directly. ## Log Ingestion -Azure Network Security Group logs can be ingested via: +You can ingest Azure Network Security Group logs through: - [Azure Event Hub](../azure-event-hub.md) - LimaCharlie [Webhooks](../../tutorials/webhook-adapter.md) -When configuring the adapter, set `client_options.platform: azure_network_security_group` to select the dedicated parser. Upon ingestion, the log `category` field is used to define the Event Type and the `time` field provides the event timestamp. +When you configure the adapter, set `client_options.platform: azure_network_security_group` to select the dedicated parser. At ingestion, the log `category` field sets the event type, and the `time` field supplies the event timestamp. diff --git a/docs/2-sensors-deployment/adapters/types/azure/sql-audit-logs.md b/docs/2-sensors-deployment/adapters/types/azure/sql-audit-logs.md index c25daeebe..f7e140288 100644 --- a/docs/2-sensors-deployment/adapters/types/azure/sql-audit-logs.md +++ b/docs/2-sensors-deployment/adapters/types/azure/sql-audit-logs.md @@ -1,14 +1,14 @@ # Azure SQL Audit Logs -Microsoft Azure SQL is a scalable, cloud-hosted database that integrates with the Azure ecosystem. See Microsoft's [Azure SQL Database product page](https://azure.microsoft.com/en-us/products/azure-sql/database) for more detail. +Microsoft Azure SQL is a scalable, cloud-hosted database that integrates with the Azure ecosystem. For more detail, see the Microsoft [Azure SQL Database product page](https://azure.microsoft.com/en-us/products/azure-sql/database). -LimaCharlie can ingest and natively parse Azure SQL Server audit logs. +LimaCharlie can ingest and parse Azure SQL Server audit logs directly. ## Log Ingestion -Azure SQL Server audit logs can be ingested via: +You can ingest Azure SQL Server audit logs through: - [Azure Event Hub](../azure-event-hub.md) - LimaCharlie [Webhooks](../../tutorials/webhook-adapter.md) -When configuring the adapter, set `client_options.platform: azure_sql_audit` to select the dedicated parser. Upon ingestion, the log `category` field is used to define the Event Type and the `time` field provides the event timestamp. +When you configure the adapter, set `client_options.platform: azure_sql_audit` to select the dedicated parser. At ingestion, the log `category` field sets the event type, and the `time` field supplies the event timestamp. diff --git a/docs/2-sensors-deployment/adapters/types/canarytokens.md b/docs/2-sensors-deployment/adapters/types/canarytokens.md index 52c2194b2..00ba0d5ea 100644 --- a/docs/2-sensors-deployment/adapters/types/canarytokens.md +++ b/docs/2-sensors-deployment/adapters/types/canarytokens.md @@ -1,8 +1,8 @@ # Canarytokens -Canarytokens are a free, quick, painless way to help defenders discover they've been breached (by having attackers announce themselves). Canarytokens are digital traps, or tripwires, that can be placed in an organization's network as a "lure" for adversaries. When actioned against, canaries will fire an alert, that can be forwarded to LimaCharlie. +Canarytokens are a free and quick way to help defenders find that an attacker breached them, because the attacker announces itself. Canarytokens are digital traps, or tripwires, that you put in the network of an organization as a "lure" for adversaries. When an adversary uses a canary, the canary sends an alert. The alert can go to LimaCharlie. -Canarytokens can be ingested in LimaCharlie via a Webhook Adapter, and are recognized as the `canary_token` platform. +A webhook adapter ingests Canarytokens into LimaCharlie. LimaCharlie recognizes them as the `canary_token` platform. ## A Little More @@ -10,26 +10,26 @@ LimaCharlie published a [blog post about the Canarytoken integration](https://li ## Adapter Deployment -Canarytoken alerts are ingested via a cloud-to-cloud webhook Adapter configured to receive JSON events. The LimaCharlie platform has pre-built mapping for Canarytoken alerts. A Canarytokens Adapter can be initially deployed in two ways: +A cloud-to-cloud webhook adapter ingests Canarytoken alerts. You configure the adapter to receive JSON events. LimaCharlie has a pre-built mapping for Canarytoken alerts. You can do the first deployment of a Canarytokens adapter in two ways: -- Via the LimaCharlie web UI -- Via the LimaCharlie CLI +- With the LimaCharlie web app +- With the LimaCharlie CLI -Regardless of which method utilized, Steps 2 and 3 will still be the same. +Steps 2 and 3 are the same for both methods. ### 1a. Initial deployment via the LimaCharlie web UI -Within the LimaCharlie UI, navigate to **Sensors** > **Sensors List** > **+ Add** Sensor. Select the **Canary Token** option. +In the LimaCharlie web app, go to **Sensors** > **Sensors List** > **+ Add** Sensor. Select the **Canary Token** option. -After selecting or creating an Installation Key, the web UI will ask you to name the Adapter and select a Secret value. +After you select or create an Installation Key, the web app asks you to name the adapter and select a Secret value. -Click **Complete Cloud Installation** to create the cloud-to-cloud Adapter. Proceed to step 2 to continue. +Click **Complete Cloud Installation** to create the cloud-to-cloud adapter. Then go to step 2. ### 1b. Initial deployment via the LimaCharlie CLI -A Canarytokens Adapter can be deployed via the LimaCharlie CLI. The step is adapted from the [generic Webhook Adapter creation guide](../tutorials/webhook-adapter.md). +The LimaCharlie CLI can also deploy a Canarytokens adapter. This step comes from the [generic Webhook Adapter creation guide](../tutorials/webhook-adapter.md). -The following configuration can be modified to easily configure a Webhook Adapter for receiving Canarytokens events. +Change this configuration to set up a webhook adapter that receives Canarytokens events. ```json { @@ -52,30 +52,34 @@ The following configuration can be modified to easily configure a Webhook Adapte } ``` -Note that in the mapping above, the `event_type_path` field is set to a static string of `Canarytoken Hit`. You can change this to any desired value. +In the mapping above, the `event_type_path` field is set to the static string `Canarytoken Hit`. You can change it to any value. -To create this webhook adapter, run the following command, replacing `` with the name of the config file from above: +To create this webhook adapter, run this command. Replace `` with the name of the config file above: `limacharlie hive set cloud_sensor --key canarytoken --data ` ### 2. Building the Webhook URL -After creating the webhook, you'll need to retrieve the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. You'll need the following information to complete the Webhook URL: +After you create the webhook, get the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. To complete the webhook URL, you need this information: - Organization ID - Webhook name (from the config) - Secret (from the config) -Let's assume the returned domain looks like `9157798c50af372c.hook.limacharlie.io`, the format of the URL would be: +If the returned domain is `9157798c50af372c.hook.limacharlie.io`, the URL has this format: `https://9157798c50af372c.hook.limacharlie.io/OID/HOOKNAME/SECRET` -Note that the `secret` value can be provided in the webhook URL or as an HTTP header named `lc-secret`. +You can give the `secret` value in the webhook URL or in an HTTP header named `lc-secret`. ### 3. Configuring the Canaryalert Webhook Output -Navigate to the [Canarytokens generate page](https://canarytokens.org/generate) to create your token of choice. +Go to the [Canarytokens generate page](https://canarytokens.org/generate) and create the token that you want. ![image.png](../../../assets/images/image(173).png) -Utilize the URL from Step 2 as the webhook URL. Provide a reminder note, which will also appear in the Canarytoken alert when tripped. Click **Create my Canarytoken**, which will provide you the content related to the selected token. When the Canarytoken is tripped, a webhook alert will be forwarded to the LimaCharlie Adapter. +1. Use the URL from step 2 as the webhook URL. +2. Give a reminder note. The note also appears in the Canarytoken alert when an adversary trips the token. +3. Click **Create my Canarytoken**. The page then supplies the content for the selected token. + +When an adversary trips the Canarytoken, a webhook alert goes to the LimaCharlie adapter. diff --git a/docs/2-sensors-deployment/adapters/types/carbon-black.md b/docs/2-sensors-deployment/adapters/types/carbon-black.md index 110a7ad24..33fa37879 100644 --- a/docs/2-sensors-deployment/adapters/types/carbon-black.md +++ b/docs/2-sensors-deployment/adapters/types/carbon-black.md @@ -2,22 +2,22 @@ ## Overview -LimaCharlie can ingest Carbon Black events from a number of storage locations. Typically, an organization would export Carbon Black data via the API to a storage mechanism, such as an S3 bucket, which would then be ingested by LimaCharlie. +LimaCharlie can ingest Carbon Black events from many storage locations. An organization usually exports Carbon Black data through the API to a storage location, such as an S3 bucket. LimaCharlie then ingests the data from that location. -Carbon Black events are observable in Detection & Response rules via the `carbon_black` platform. +You see Carbon Black events in Detection & Response rules through the `carbon_black` platform. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter uses. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ## Config File -VMWare Carbon Black data can be exported via the API to an S3 bucket, and then ingested with LimaCharlie. The following command utilizes a CLI Adapter to ingest these events +You can export VMWare Carbon Black data through the API to an S3 bucket, then ingest it with LimaCharlie. This command uses a CLI adapter to ingest these events ```bash ./lc_adapter s3 client_options.identity.installation_key= \ @@ -30,14 +30,14 @@ secret_key=XXXXXXXX \ "prefix=events/org_key=NKZAAAEM/" ``` -Here's a breakdown of the above example: +This is an explanation of the example above: -- `lc_adapter`: simply the CLI Adapter. -- `s3`: the data will be collected from an AWS S3 bucket. +- `lc_adapter`: the CLI adapter. +- `s3`: the adapter collects the data from an AWS S3 bucket. - `client_options.identity.installation_key=....`: the Installation Key value from LimaCharlie. -- `client_options.identity.oid=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=carbon_black`: this indicates the data received will be Carbon Black events from their API. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor IDs generated for the Carbon Black sensors from this Adapter later if you have to re-install the Adapter. +- `client_options.identity.oid=....`: the LimaCharlie Organization ID that owns the installation key above. +- `client_options.platform=carbon_black`: this value shows that the received data is Carbon Black events from the Carbon Black API. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the adapter. Record it. If you re-install the adapter, this value lets you re-use the Sensor IDs that LimaCharlie generated for the Carbon Black sensors. - `bucket_name:....`: the name of the S3 bucket holding the data. - `access_key:....`: the AWS Access Key for the API key below. - `secret_key:....`: the API key for AWS that has access to this bucket. diff --git a/docs/2-sensors-deployment/adapters/types/cato.md b/docs/2-sensors-deployment/adapters/types/cato.md index 4e294ccce..9ce8cdd2b 100644 --- a/docs/2-sensors-deployment/adapters/types/cato.md +++ b/docs/2-sensors-deployment/adapters/types/cato.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to the Cato API to fetch logs from the [events feed](https://support.catonetworks.com/hc/en-us/articles/360019839477-Cato-API-EventsFeed-Large-Scale-Event-Monitoring). +This adapter connects to the Cato API and fetches logs from the [events feed](https://support.catonetworks.com/hc/en-us/articles/360019839477-Cato-API-EventsFeed-Large-Scale-Event-Monitoring). ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter uses. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options @@ -38,4 +38,4 @@ accountid=$ACCOUNT_ID ## API Doc -See the official [documentation](https://support.catonetworks.com/hc/en-us/articles/360019839477-Cato-API-EventsFeed-Large-Scale-Event-Monitoring). +See the official [Cato API Events Feed documentation](https://support.catonetworks.com/hc/en-us/articles/360019839477-Cato-API-EventsFeed-Large-Scale-Event-Monitoring). diff --git a/docs/2-sensors-deployment/adapters/types/checkpoint-harmony.md b/docs/2-sensors-deployment/adapters/types/checkpoint-harmony.md index 0a5b3eb85..00abc8f10 100644 --- a/docs/2-sensors-deployment/adapters/types/checkpoint-harmony.md +++ b/docs/2-sensors-deployment/adapters/types/checkpoint-harmony.md @@ -2,23 +2,23 @@ ## Overview -This Adapter ingests events from [Check Point Harmony](https://www.checkpoint.com/harmony/) into LimaCharlie via the Infinity Portal APIs. Two independent sources are supported: +This Adapter ingests events from [Check Point Harmony](https://www.checkpoint.com/harmony/) into LimaCharlie through the Infinity Portal APIs. The adapter supports two independent sources: -- **Infinity Events** — the unified Logs-as-a-Service stream covering Harmony Endpoint, Harmony Email & Collaboration, Harmony Mobile, Harmony Connect, and Harmony Browse. -- **Entities** — polls the Harmony Email & Collaboration (HEC) `search/query` entity API. A single source that runs a list of *named queries*: each query is one server-side-filtered feed. Restore requests on quarantined mail, recipient/subject/DLP watches, and the unfiltered email firehose are all expressed as different queries on the same engine — no Go code changes needed to add a new scenario. +- **Infinity Events** — the unified Logs-as-a-Service stream that covers Harmony Endpoint, Harmony Email & Collaboration, Harmony Mobile, Harmony Connect, and Harmony Browse. +- **Entities** — polls the Harmony Email & Collaboration (HEC) `search/query` entity API. This one source runs a list of *named queries*. Each query is one feed that the server filters. Restore requests on quarantined mail, watches on recipient, subject, or DLP, and the unfiltered email firehose are all different queries on the same engine. A new scenario needs no change to the Go code. -Both sources share a single set of Infinity Portal API credentials. At least one source must be enabled or the adapter will refuse to start. +Both sources share one set of Infinity Portal API credentials. You must turn on at least one source. If both sources are off, the adapter does not start. -A previous `emails` firehose source has been folded into `entities` as a preset. See [Migrating from `emails`](#migrating-from-emails) below. +The previous `emails` firehose source is now a preset in `entities`. See [Migrating from `emails`](#migrating-from-emails) below. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options @@ -26,37 +26,37 @@ Adapter Type: `harmony` **Top-level credentials (always required):** -- `client_id`: Infinity Portal Client ID. Create under *Global Settings → API Keys*. For Infinity Events the key must include the *Logs as a Service* service; for the Entities source it must include the *Harmony Email & Collaboration* service. A single key with both services attached is supported. +- `client_id`: Infinity Portal Client ID. Create it under *Global Settings → API Keys*. For Infinity Events, the key must include the *Logs as a Service* service. For the Entities source, the key must include the *Harmony Email & Collaboration* service. One key with both services attached is supported. - `access_key`: Infinity Portal Access Key paired with the Client ID above. -- `url` *(optional)*: Infinity Portal gateway base URL. Defaults to `https://cloudinfra-gw.portal.checkpoint.com`. Use the regional variant (for example `https://cloudinfra-gw-us.portal.checkpoint.com`) if your tenant lives in a regional data center. Both `/app/laas-logs-api` and `/app/hec-api` share the same hostname per region. +- `url` *(optional)*: Infinity Portal gateway base URL. Defaults to `https://cloudinfra-gw.portal.checkpoint.com`. If your tenant is in a regional data center, use the regional variant, for example `https://cloudinfra-gw-us.portal.checkpoint.com`. In each region, `/app/laas-logs-api` and `/app/hec-api` share the same hostname. -All duration fields below are parsed with [`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration) — for example `"60s"`, `"5m"`, `"1h30m"`, `"360h"`. +[`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration) parses all the duration fields below — for example `"60s"`, `"5m"`, `"1h30m"`, `"360h"`. **`events` block — Infinity Events source:** -- `events.enabled`: set to `true` to turn the source on. -- `events.cloud_services` *(optional)*: list of cloud services to pull events for. Names must match the gateway exactly — the Email service is `Harmony Email & Collaboration` (ampersand, not the word "and"), and the gateway rejects the "and" spelling. Defaults to the full Harmony suite: `Harmony Endpoint`, `Harmony Email & Collaboration`, `Harmony Mobile`, `Harmony Connect`, `Harmony Browse`. -- `events.filter` *(optional)*: Infinity Events query filter applied to every cloud service. -- `events.poll_interval` *(optional)*: polling cadence. Defaults to `60s`. +- `events.enabled`: set to `true` to turn on the source. +- `events.cloud_services` *(optional)*: list of the cloud services to pull events for. The names must match the gateway exactly. The Email service is `Harmony Email & Collaboration` with an ampersand, and the gateway rejects the spelling with the word "and". Defaults to the full Harmony suite: `Harmony Endpoint`, `Harmony Email & Collaboration`, `Harmony Mobile`, `Harmony Connect`, `Harmony Browse`. +- `events.filter` *(optional)*: Infinity Events query filter that applies to every cloud service. +- `events.poll_interval` *(optional)*: time between polls. Defaults to `60s`. - `events.page_limit` *(optional)*: page size for the records-retrieval API. Defaults to `100`. The gateway rejects values below `10` with HTTP 400. -- `events.limit` *(optional)*: cap on records returned per cloud service per poll. Defaults to `5000`. +- `events.limit` *(optional)*: maximum number of records returned for each cloud service in each poll. Defaults to `5000`. -If a configured `cloud_service` is not provisioned for the tenant the gateway returns the query in state `Canceled`; the adapter logs one warning per poll and keeps going (it does not surface as an error). Remove the service from `cloud_services` to silence the warning. +If a configured `cloud_service` is not provisioned for the tenant, the gateway returns the query in state `Canceled`. The adapter writes one warning for each poll and continues. This condition is not an error. To stop the warning, remove the service from `cloud_services`. **`entities` block — HEC entity-query source:** -- `entities.enabled`: set to `true` to turn the source on. -- `entities.queries`: list of named queries. Each entry is one independent feed with its own dedup state and its own `_lc_harmony_query` annotation downstream. +- `entities.enabled`: set to `true` to turn on the source. +- `entities.queries`: list of named queries. Each entry is one independent feed. Each feed has its own dedup state and its own `_lc_harmony_query` annotation downstream. Each `entities.queries` entry supports the following fields: | Field | Default | Notes | | --- | --- | --- | | `name` | — (required) | Identifier for the feed. Must be unique within `entities.queries`. Appears in errors and as `_lc_harmony_query`. | -| `saas` | `[office365_emails, google_mail]` | SaaS platforms to query, each independently. Only `office365_emails` and `google_mail` are supported. | -| `filter` | `[]` | List of `{attr, op, value}` predicates passed through as `entityExtendedFilter`. ANDed by the gateway. Empty is allowed (then the query is bounded only by the entity window and, in cursor mode, the injected cursor predicate). | +| `saas` | `[office365_emails, google_mail]` | The SaaS platforms to query. The adapter queries each one independently. Only `office365_emails` and `google_mail` are supported. | +| `filter` | `[]` | List of `{attr, op, value}` predicates that pass through as `entityExtendedFilter`. The gateway combines them with AND. An empty list is allowed. The entity window then bounds the query, plus the injected cursor predicate in cursor mode. | | `cursor_field` | `""` | Empty → window mode. Set to `entityPayload.` or `entityInfo.` (must reference a timestamp-typed field) → cursor mode. See [Two cursor modes](#two-cursor-modes) below. | -| `include_splits` | `false` | If `true`, ship `entityPayload.emailSplit == "split"` master records alongside their child copies (firehose semantics). Default skips them so a single email isn't double-emitted per query. | +| `include_splits` | `false` | If `true`, send `entityPayload.emailSplit == "split"` master records with their child copies (firehose semantics). The default skips them, so one query does not emit the same email twice. | | `lookback` | `1h` (window) / `360h` (cursor) | Floor on `entityFilter.startDate` (received time). Duration string. | | `initial_lookback` | `1h` | Cursor mode only: how far back the cursor starts on the first poll. Duration string. | | `poll_interval` | `5m` | Time between polls. Duration string. | @@ -68,22 +68,22 @@ filter: - {attr: , op: , value: ""} ``` -`attr` is a Check Point [saasAttrName](https://sc1.checkpoint.com/documents/Harmony_Email_and_Collaboration_API_Reference/Topics-HEC-Avanan-API-Reference-Guide/Managing-Secured-Entities/Search-query.htm) (e.g. `entityPayload.subject`, `entityPayload.recipients`, `entityPayload.isRestoreRequested`). `op` is one of `is`, `isNot`, `contains`, `notContains`, `startsWith`, `isEmpty`, `isNotEmpty`, `greaterThan`, `lessThan`. `value` is a string; booleans are spelled as the string `"true"` / `"false"`. Unknown ops are rejected at startup so a typo fails loudly instead of silently matching nothing. +`attr` is a Check Point [saasAttrName](https://sc1.checkpoint.com/documents/Harmony_Email_and_Collaboration_API_Reference/Topics-HEC-Avanan-API-Reference-Guide/Managing-Secured-Entities/Search-query.htm), for example `entityPayload.subject`, `entityPayload.recipients`, or `entityPayload.isRestoreRequested`. `op` is one of `is`, `isNot`, `contains`, `notContains`, `startsWith`, `isEmpty`, `isNotEmpty`, `greaterThan`, `lessThan`. `value` is a string. Write a boolean as the string `"true"` or `"false"`. The adapter rejects an unknown op at startup, so a typo fails immediately instead of matching nothing. #### Two cursor modes | Mode | When to use | `entityFilter` sent | Cursor | | --- | --- | --- | --- | | **Window mode** (`cursor_field` empty) | The matching email is itself recent — content/recipient/detection filters, or the unfiltered firehose. | `saas` + `startDate` + `endDate` + `saasEntity` (received-time window). | Rolling window + dedup. | -| **Cursor mode** (`cursor_field` set) | The event of interest is decoupled in time from the email's receipt — e.g. a restore request on an old quarantined email. | `saas` + wide `startDate` only — no `endDate`, no `saasEntity`. | Adapter auto-injects `{cursor_field} greaterThan {cursor}` and advances `cursor` to the newest value seen. | +| **Cursor mode** (`cursor_field` set) | The event of interest is separated in time from the receipt of the email — for example a restore request on an old quarantined email. | `saas` + wide `startDate` only — no `endDate`, no `saasEntity`. | The adapter injects `{cursor_field} greaterThan {cursor}` and moves `cursor` to the newest value that it sees. | -A *filtered* query (non-empty `filter`) is bounded server-side by the predicates, so it scales independently of total mail volume. The **unfiltered firehose preset** (window mode, no `filter`, `include_splits: true`) is the exception: it is bounded only by the received-time window, so on a very high-volume tenant a long `lookback` can hit the gateway's per-query record ceiling (~10,000 records, oldest-first). Keep `lookback` short for that preset (the 1h default is intentional), or use a filtered query. +The predicates of a *filtered* query (non-empty `filter`) bound it on the server, so its cost does not change with total mail volume. The **unfiltered firehose preset** (window mode, no `filter`, `include_splits: true`) is the exception. Only the received-time window bounds it. On a tenant with very high mail volume, a long `lookback` can reach the record ceiling of the gateway for each query (about 10,000 records, oldest first). Keep `lookback` short for that preset (the 1h default is intentional), or use a filtered query. -> **Restore requests require cursor mode.** A window-mode query (or the firehose preset) cannot surface a restore request. The window filters on the email's *received* time, but the underlying quarantined email may have been received hours, days, or months before the restore was requested — so it isn't in any recent received-time window. Use the `restore_requests` preset below. +> **Restore requests require cursor mode.** A window-mode query (or the firehose preset) cannot show a restore request. The window filters on the *received* time of the email. The quarantined email can arrive hours, days, or months before the restore request, so it is not in a recent received-time window. Use the `restore_requests` preset below. #### Annotations -Every record carries adapter-added annotations to make routing easy downstream: +The adapter adds annotations to every record. Use them to route the record downstream: - `_lc_harmony_source` — `infinity_events` or `entities`. - `_lc_harmony_service` — the Infinity Events cloud service (events source only). @@ -92,7 +92,7 @@ Every record carries adapter-added annotations to make routing easy downstream: #### Example presets -Quarantined-email restore requests — canonical cursor-mode preset, mirrors Check Point's own XSOAR `restore_requests`: +Restore requests for quarantined email — the canonical cursor-mode preset. It is the same as the Check Point XSOAR `restore_requests` preset: ```yaml harmony: @@ -139,11 +139,11 @@ harmony: poll_interval: 5m ``` -Multiple queries can be listed under one source — each runs independently, with its own dedup state and its own `_lc_harmony_query` annotation. +You can list many queries under one source. Each query runs independently, with its own dedup state and its own `_lc_harmony_query` annotation. ### CLI Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. The adapter accepts dot-notation flags for the nested `events.*` and `entities.*` fields; `entities.queries` is passed as a single JSON string. +Get the [Adapter downloads](../deployment.md) from the deployment page. The adapter accepts dot-notation flags for the nested `events.*` and `entities.*` fields. Pass `entities.queries` as one JSON string. ```bash chmod +x /path/to/lc_adapter @@ -213,19 +213,19 @@ harmony: ### Preparing Infinity Portal credentials 1. Sign in to the [Infinity Portal](https://portal.checkpoint.com/) with an account that can manage API keys. -2. Navigate to *Global Settings → API Keys → New*. -3. Attach the services your adapter needs: +2. Go to *Global Settings → API Keys → New*. +3. Attach the services that your adapter needs: - *Logs as a Service* for the Infinity Events source. - *Harmony Email & Collaboration* for the Entities source. - - A single key with both services attached is fine. -4. Copy the resulting **Client ID** and **Access Key**. The Access Key is shown only once — save it somewhere safe. -5. Note the **Authentication URL** shown next to the key. If it points at a regional gateway (`cloudinfra-gw-us.portal.checkpoint.com`, `cloudinfra-gw-eu.portal.checkpoint.com`, etc.) you will need to supply that hostname as the adapter's `url` value. + - One key with both services attached is supported. +4. Copy the **Client ID** and the **Access Key**. The portal shows the Access Key one time only. Keep it in a safe location. +5. Record the **Authentication URL** that the portal shows next to the key. If it points at a regional gateway (`cloudinfra-gw-us.portal.checkpoint.com`, `cloudinfra-gw-eu.portal.checkpoint.com`, etc.), give that hostname as the `url` value of the adapter. ### Setting up the Adapter -Within the LimaCharlie web application, select `+ Add Sensor`, and then choose **Check Point Harmony**. +In the LimaCharlie web app, select `+ Add Sensor`. Then choose **Check Point Harmony**. -Pick or create an Installation Key for this adapter, then fill in the form: +Select or create an Installation Key for this adapter. Then complete the form: | Field | Value | | --- | --- | @@ -236,15 +236,15 @@ Pick or create an Installation Key for this adapter, then fill in the form: | Events Cloud Services | *(optional)* Comma-separated cloud services. Leave blank for the full Harmony suite. | | Events Filter | *(optional)* Infinity Events query filter | | Entities Enabled | Toggle on to poll the HEC entity-query source | -| Entities Queries | *(optional)* JSON array of named entity queries — see [Adapter-specific Options](#adapter-specific-options) above for the schema and presets. | +| Entities Queries | *(optional)* JSON array of named entity queries. For the schema and the presets, see [Adapter-specific Options](#adapter-specific-options) above. | -At least one of *Events Enabled* or *Entities Enabled* must be on or the adapter will refuse to start. +Turn on *Events Enabled*, *Entities Enabled*, or both. If both are off, the adapter does not start. -Click `Complete Cloud Installation`. LimaCharlie will authenticate against the Infinity Portal and begin polling. +Click `Complete Cloud Installation`. LimaCharlie authenticates against the Infinity Portal and starts to poll. ## Sample Rule -When ingested, Harmony events can be referenced directly in D&R rules. The adapter annotates every record with `_lc_harmony_source` so you can pivot on the originating API, and entities records additionally carry `_lc_harmony_query` so you can route per query: +After ingestion, D&R rules can reference Harmony events directly. The adapter annotates every record with `_lc_harmony_source`, so you can pivot on the source API. Entities records also carry `_lc_harmony_query`, so you can route each query separately: ```yaml # Detection — flag restore requests from the entities source @@ -263,11 +263,11 @@ rules: name: Harmony Restore Request ``` -For the unfiltered firehose query, narrow the detection on the verdict/lifecycle fields carried inline on each entity (under `event/entityInfo` and the entity payload) to match only the cases you care about — for example a quarantined message or a declined restore request. +For the unfiltered firehose query, narrow the detection with the verdict and lifecycle fields on each entity (under `event/entityInfo` and the entity payload). Match only the cases that you need — for example a quarantined message or a declined restore request. ## Migrating from `emails` -The previous `emails` source has been removed. Adapter configs carrying `harmony.emails: {enabled: true}` will fail Validate at startup with a clear message pointing to this guide. +The previous `emails` source is removed. An adapter config with `harmony.emails: {enabled: true}` fails Validate at startup. The message points to this guide. **Before:** @@ -294,7 +294,7 @@ harmony: poll_interval: 5m ``` -Downstream rules / dashboards that filter on `_lc_harmony_source: emails` need to be updated to filter on `_lc_harmony_source: entities` (plus optionally `_lc_harmony_query: emails` if you want to scope to this specific feed). +Update the downstream rules and dashboards that filter on `_lc_harmony_source: emails`. They must filter on `_lc_harmony_source: entities`. You can also add `_lc_harmony_query: emails` to limit the filter to this feed. ## API Docs diff --git a/docs/2-sensors-deployment/adapters/types/crowdstrike.md b/docs/2-sensors-deployment/adapters/types/crowdstrike.md index 3584c473b..157567dd7 100644 --- a/docs/2-sensors-deployment/adapters/types/crowdstrike.md +++ b/docs/2-sensors-deployment/adapters/types/crowdstrike.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to CrowdStrike Falcon Cloud to stream events as they happen in the CrowdStrike Falcon Console. +This Adapter connects to CrowdStrike Falcon Cloud. It streams events as they occur in the CrowdStrike Falcon Console. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. ### Adapter-specific Options @@ -22,7 +22,7 @@ Adapter Type: `falconcloud` ### Manual Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. +Get the [Adapter downloads](../deployment.md) from the deployment page. ```bash chmod +x /path/to/lc_adapter @@ -60,4 +60,4 @@ sensor_type: "falconcloud" ## API Doc -See the official [documentation](https://developer.crowdstrike.com/docs/openapi/) and [additional docs on the library used to access the Falcon APIs](https://github.com/CrowdStrike/gofalcon). +See the official [CrowdStrike OpenAPI documentation](https://developer.crowdstrike.com/docs/openapi/) and the [documentation for the library that accesses the Falcon APIs](https://github.com/CrowdStrike/gofalcon). diff --git a/docs/2-sensors-deployment/adapters/types/duo.md b/docs/2-sensors-deployment/adapters/types/duo.md index 413ad64a3..e26c3c69e 100644 --- a/docs/2-sensors-deployment/adapters/types/duo.md +++ b/docs/2-sensors-deployment/adapters/types/duo.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to the Duo Admin API and fetch logs from it. +This Adapter connects to the Duo Admin API and fetches logs from it. ## Configurations Adapter Type: `duo` - `client_options`: see [common adapter configuration](../usage.md). -- `integration_key`: an integration key created from within Duo that associated with your "app". +- `integration_key`: an integration key that you create in Duo and associate with your "app". - `secret_key`: the secret key for your "app". -- `api_hostname`: the DNS for your "app", a value given to you by Duo. +- `api_hostname`: the DNS name for your "app". Duo gives you this value. ### Infrastructure as Code Deployment diff --git a/docs/2-sensors-deployment/adapters/types/evtx.md b/docs/2-sensors-deployment/adapters/types/evtx.md index 8208aba96..6c5c49c98 100644 --- a/docs/2-sensors-deployment/adapters/types/evtx.md +++ b/docs/2-sensors-deployment/adapters/types/evtx.md @@ -2,17 +2,17 @@ ## Overview -This Adapter allows you to ingest and convert a `.evtx` file into LimaCharlie. The `.evtx` files are the binary format used by Microsoft for Windows Event Logs. This is useful to ingest historical Windows Event Logs, for example during an Incident Response (IR) engagement. +This Adapter converts a `.evtx` file and ingests it into LimaCharlie. A `.evtx` file uses the binary format that Microsoft applies to Windows Event Logs. Use this adapter to ingest historical Windows Event Logs, for example during an Incident Response (IR) engagement. -For real-time collection of Windows Event Logs, see the [Windows Event Logs](../../tutorials/windows-event-logs.md) documentation. +To collect Windows Event Logs in real time, see the [Windows Event Logs](../../tutorials/windows-event-logs.md) documentation. ## Configurations Adapter Type: `evtx` - `client_options`: see [common adapter configuration](../usage.md). -- `file_path`: path to the `.evtx` file to ingest. -- `write_timeout_sec`: number of seconds before a write to LimaCharlie times out (default: 600). +- `file_path`: the path to the `.evtx` file to ingest. +- `write_timeout_sec`: the number of seconds before a write to LimaCharlie times out (default: 600). ### Configuration File Example @@ -30,7 +30,7 @@ evtx: ### CLI Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. +Get the [Adapter downloads](../deployment.md) from the deployment page. ```bash /path/to/lc_adapter evtx \ diff --git a/docs/2-sensors-deployment/adapters/types/file.md b/docs/2-sensors-deployment/adapters/types/file.md index 490a6ec10..accc6172c 100644 --- a/docs/2-sensors-deployment/adapters/types/file.md +++ b/docs/2-sensors-deployment/adapters/types/file.md @@ -2,47 +2,47 @@ ## Overview -This Adapter allows you to ingest logs from a file, either as a one time operation or by following its output (like `tail -f`). A more detailed guide to file collection can be found in the [Log Collection Guide](../../log-collection-guide.md). +This Adapter ingests logs from a file. It can do one pass over the file, or it can read new content as the file grows (like `tail -f`). For more detail about file collection, see the [Log Collection Guide](../../log-collection-guide.md). ### Configuration -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. See below. Adapter type `file`: -- `file_path`: simple file pattern like `./files_*.txt` -- `no_follow`: if `true`, the file content will be sent, but additions to the file will not be reported -- `inactivity_threshold`: the number of seconds after which an unmodified file becomes ignored (default: 86400, i.e. 24 hours) -- `reactivation_threshold`: the number of seconds within which a previously inactive file must be modified to resume tailing (default: 60) -- `backfill`: if `true`, a single pass at all the matching files will be made to ingest them, useful for historical ingestion -- `serialize_files`: if `true`, files will be ingested one at a time, useful for very large number of files that could blow up memory +- `file_path`: a file pattern, for example `./files_*.txt` +- `no_follow`: if `true`, the adapter sends the file content but does not report additions to the file +- `inactivity_threshold`: the number of seconds without a change after which the adapter ignores a file (default: 86400, that is 24 hours) +- `reactivation_threshold`: the number of seconds in which an inactive file must change for the adapter to tail it again (default: 60) +- `backfill`: if `true`, the adapter makes one pass over all the matching files and ingests them. Use this option for historical ingestion +- `serialize_files`: if `true`, the adapter ingests the files one at a time. Use this option for a very large number of files that can exhaust memory - `poll`: if `true`, use polling instead of filesystem event notifications to detect file changes. See [Polling Mode](#polling-mode) below -- `multi_line_json`: if `true`, the adapter will buffer lines and assemble complete JSON objects spanning multiple lines before sending them -- `write_timeout_sec`: number of seconds before a write to LimaCharlie times out (default: 600) +- `multi_line_json`: if `true`, the adapter buffers lines and assembles complete JSON objects that span multiple lines before it sends them +- `write_timeout_sec`: the number of seconds before a write to LimaCharlie times out (default: 600) ### Polling Mode -By default, the file adapter relies on OS-level filesystem notifications (such as `inotify` on Linux or `kqueue` on BSD/macOS) to detect when new data is written to a file. While efficient, this mechanism can fail to detect changes in certain situations: +By default, the file adapter uses filesystem notifications from the operating system (such as `inotify` on Linux or `kqueue` on BSD/macOS) to detect new data in a file. This mechanism is efficient, but it can fail to detect changes in these situations: -- **Log rotation**: When a log management tool (e.g. `newsyslog`, `logrotate`) rotates a file, the original file descriptor may become stale. The filesystem notification watcher may remain attached to the old (now renamed or deleted) file and miss writes to the new file at the same path. -- **Network and virtual filesystems**: NFS, CIFS/SMB, and some FUSE-based filesystems may not reliably deliver filesystem notifications. -- **Platform-specific quirks**: Some operating systems or filesystem drivers have incomplete or inconsistent notification support. +- **Log rotation**: When a log management tool (for example `newsyslog` or `logrotate`) rotates a file, the original file descriptor can become stale. The notification watcher can stay attached to the old file, which is now renamed or deleted, and miss the writes to the new file at the same path. +- **Network and virtual filesystems**: NFS, CIFS/SMB, and some filesystems that use FUSE do not always deliver filesystem notifications. +- **Platform-specific quirks**: Some operating systems or filesystem drivers have incomplete or inconsistent support for notifications. -Setting `poll: true` switches the adapter to a polling-based approach that periodically checks the file for new content. This is slightly less efficient than event-driven notifications but is more reliable across different platforms and when log rotation is in use. +Set `poll: true` to switch the adapter to polling. The adapter then checks the file for new content at regular intervals. Polling is a little less efficient than event notifications, but it is more reliable on different platforms and with log rotation. -The adapter also performs its own inode-based rotation detection — if a file's inode changes between poll cycles, the adapter automatically closes the old file handle and opens the new file. This works in conjunction with polling mode to provide reliable collection across rotations. +The adapter also detects rotation with the inode of the file. If the inode of a file changes between poll cycles, the adapter closes the old file handle and opens the new file. This detection works with polling mode to give reliable collection across rotations. **When to use `poll: true`:** -- You are running on FreeBSD, OpenBSD, NetBSD, or Solaris -- Your log files are rotated by tools like `newsyslog` or `logrotate` -- The adapter stops collecting after a log rotation event -- Your files reside on a network or virtual filesystem +- You use FreeBSD, OpenBSD, NetBSD, or Solaris +- Tools such as `newsyslog` or `logrotate` rotate your log files +- The adapter stops collection after a log rotation event +- Your files are on a network filesystem or a virtual filesystem **Example:** @@ -60,7 +60,7 @@ file: ### CLI Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. +Get the [Adapter downloads](../deployment.md) from the deployment page. ```bash chmod +x /path/to/lc_adapter diff --git a/docs/2-sensors-deployment/adapters/types/gmail.md b/docs/2-sensors-deployment/adapters/types/gmail.md index cee37b900..66150f2ff 100644 --- a/docs/2-sensors-deployment/adapters/types/gmail.md +++ b/docs/2-sensors-deployment/adapters/types/gmail.md @@ -2,30 +2,30 @@ ## Overview -This Adapter collects telemetry from one or many Gmail mailboxes using the [Gmail REST API](https://developers.google.com/workspace/gmail/api/reference/rest). Beyond incoming-email telemetry, it can collect the mailbox configuration and change signals most relevant to **Business Email Compromise (BEC)** — the mail rules, forwarding, aliases, delegates, protocol access, and deletions an intruder uses to persist, exfiltrate mail, and cover their tracks. +This adapter collects telemetry from one or more Gmail mailboxes with the [Gmail REST API](https://developers.google.com/workspace/gmail/api/reference/rest). It also collects the mailbox configuration and the change signals for **Business Email Compromise (BEC)**. These signals are the mail rules, forwarding, aliases, delegates, protocol access, and deletions that an intruder uses to keep access, exfiltrate mail, and hide activity. -Each signal is an independent, opt-in **capability** that ships its own event type. They are all readable with the default `gmail.readonly` scope. +Each signal is an independent **capability** that you enable, and each capability sends its own event type. The default `gmail.readonly` scope can read all of them. -With the service-account flow the adapter can watch **many mailboxes at once** — an explicit list, or every mailbox in a Google Workspace domain via auto-discovery — and ships each mailbox to its own LimaCharlie sensor. +With the service-account flow, the adapter can collect **many mailboxes at once**: an explicit list, or every mailbox in a Google Workspace domain through auto-discovery. The adapter sends each mailbox to its own LimaCharlie sensor. ## Capabilities -Enable any combination with the `collect_*` flags. If you set none, the adapter defaults to message telemetry only (`collect_messages`). +Enable any combination of the `collect_*` flags. If you set none, the adapter collects only message telemetry (`collect_messages`). | Flag | Event type(s) | What it gives you | | --- | --- | --- | -| `collect_messages` | `gmail_message` | Incoming email as telemetry — the raw signal for phishing/lure detection. | -| `collect_filters` | `gmail_filter` | Mail rules. Attackers create rules that auto-delete, auto-forward, or hide replies about invoices/wires. | -| `collect_forwarding` | `gmail_forwarding_address`, `gmail_auto_forwarding` | Forwarding destinations and the account-wide auto-forward toggle — a classic mail-exfiltration vector. | -| `collect_send_as` | `gmail_send_as` | Send-as / "from" identities. An added identity is an impersonation/persistence signal. | -| `collect_delegates` | `gmail_delegate` | Mailbox delegates — granting a delegate is persistence. **Workspace only** (see note below). | -| `collect_imap_pop` | `gmail_imap`, `gmail_pop` | IMAP/POP access settings. Enabling these allows bulk mailbox download via a desktop client. | -| `collect_vacation` | `gmail_vacation` | The vacation responder, occasionally abused for harvesting/social engineering. | +| `collect_messages` | `gmail_message` | Incoming email as telemetry. This is the raw signal to detect phishing and lures. | +| `collect_filters` | `gmail_filter` | Mail rules. Attackers create rules that auto-delete, auto-forward, or hide replies about invoices and wires. | +| `collect_forwarding` | `gmail_forwarding_address`, `gmail_auto_forwarding` | Forwarding destinations and the account-wide auto-forward setting. Attackers use these to exfiltrate mail. | +| `collect_send_as` | `gmail_send_as` | Send-as / "from" identities. A new identity is a signal of impersonation or persistence. | +| `collect_delegates` | `gmail_delegate` | Mailbox delegates. A new delegate gives persistence. **Workspace only** (see the note below). | +| `collect_imap_pop` | `gmail_imap`, `gmail_pop` | IMAP/POP access settings. If these are enabled, a desktop client can download the full mailbox. | +| `collect_vacation` | `gmail_vacation` | The vacation responder. Attackers sometimes abuse it for harvesting and social engineering. | | `collect_history` | `gmail_history` | Mailbox changes: message **deletions** and **label changes** (marking a security alert read, trashing the fraud thread). | -> **Delegates are Workspace-only.** Google exposes the delegates listing only to service-account clients with domain-wide delegation. On a consumer account (or without delegation) the call returns an error, which the adapter logs and skips — it does not stop the adapter or affect the other capabilities. +> **Delegates are Workspace-only.** Google gives the delegates listing only to service-account clients that have domain-wide delegation. On a consumer account, or without delegation, the call returns an error. The adapter logs the error and skips the capability. The adapter continues to run, and the other capabilities are not affected. -The configuration-state capabilities (filters, forwarding, send-as, delegates, IMAP/POP, vacation) are **change-only**: an item is shipped when it first appears or its content changes, and suppressed otherwise. On adapter restart the in-memory dedupe state is empty, so the current state is re-emitted once as a fresh baseline — write detections against the *state* in these events rather than treating every event as a brand-new change. +The configuration-state capabilities (filters, forwarding, send-as, delegates, IMAP/POP, vacation) are **change-only**. The adapter sends an item only when the item first appears or when its content changes. After an adapter restart, the in-memory dedupe state is empty, so the adapter sends the current state one time as a new baseline. Write detections against the *state* in these events, and do not treat every event as a new change. ## Authentication @@ -33,7 +33,11 @@ Choose one of two modes. ### OAuth 2.0 refresh token (a single mailbox) -For collecting one user's mailbox. Create an OAuth client (Desktop or Web) in the Google Cloud console, enable the Gmail API, and complete the authorization-code flow once to obtain a refresh token for the `gmail.readonly` scope. +Use this mode to collect the mailbox of one user. + +1. Create an OAuth client (Desktop or Web) in the Google Cloud console. +2. Enable the Gmail API. +3. Complete the authorization-code flow one time. The flow gives a refresh token for the `gmail.readonly` scope. | Field | Description | | --- | --- | @@ -43,7 +47,11 @@ For collecting one user's mailbox. Create an OAuth client (Desktop or Web) in th ### Service account with domain-wide delegation (Google Workspace) -For monitoring Workspace mailboxes without per-user consent. Create a service account, enable domain-wide delegation, and in the Workspace Admin console authorize its client id for the `https://www.googleapis.com/auth/gmail.readonly` scope. +Use this mode to monitor Workspace mailboxes without consent from each user. + +1. Create a service account. +2. Enable domain-wide delegation for the service account. +3. In the Workspace Admin console, authorize the client id of the service account for the `https://www.googleapis.com/auth/gmail.readonly` scope. | Field | Description | | --- | --- | @@ -51,32 +59,32 @@ For monitoring Workspace mailboxes without per-user consent. Create a service ac | `service_account_file` | Path to the service account JSON key file (alternative to the inline form) | | `subject` | A single mailbox owner to impersonate, e.g. `user@yourdomain.com` | -Provide the mailbox(es) with `subject` (one), `subjects` (a list), and/or `discover_mailboxes` (the whole domain). At least one of these is required. +Select the mailboxes with `subject` (one mailbox), `subjects` (a list), or `discover_mailboxes` (the full domain). You can combine them. You must set at least one. ## Multiple mailboxes -With the service-account flow, each mailbox is impersonated independently and **shipped to its own sensor**: when more than one mailbox is collected, the sensor seed key is derived as `/` and the sensor hostname is set to the mailbox address. +With the service-account flow, the adapter impersonates each mailbox independently and sends each one **to its own sensor**. When the adapter collects more than one mailbox, the sensor seed key becomes `/`, and the sensor hostname becomes the mailbox address. -There are two ways to enumerate mailboxes, and they can be combined (the union is collected): +Two methods enumerate mailboxes. You can combine them, and the adapter collects the union: -- **Static list** (`subjects`): list the mailboxes explicitly — good for a fixed set of high-value mailboxes (executives, finance, AP). -- **Auto-discovery** (`discover_mailboxes`): enumerate the Workspace domain's mailboxes via the Admin SDK Directory API, re-run on `discovery_interval` (default 1h) so newly-provisioned mailboxes are picked up and deprovisioned ones dropped automatically. Suspended accounts are skipped unless `include_suspended` is set. +- **Static list** (`subjects`): name each mailbox. Use this method for a fixed set of high-value mailboxes, such as executives, finance, and AP. +- **Auto-discovery** (`discover_mailboxes`): enumerate the mailboxes of the Workspace domain with the Admin SDK Directory API. The adapter repeats discovery on `discovery_interval` (default 1h), so it adds new mailboxes and drops deprovisioned ones automatically. The adapter skips suspended accounts unless you set `include_suspended`. -Auto-discovery has two extra requirements beyond the Gmail collection itself: +Auto-discovery needs two items more than the Gmail collection: -1. `admin_subject` — a Workspace admin user the service account impersonates for the Directory call. +1. `admin_subject` — a Workspace admin user that the service account impersonates for the Directory call. 2. An extra delegated scope — authorize the service account's client id for `https://www.googleapis.com/auth/admin.directory.user.readonly` in the Workspace Admin console. -If a discovery pass fails or comes back empty while mailboxes are already being collected, the current set keeps collecting (with a warning logged) — discovery never tears down working mailboxes on a transient blip. +If a discovery pass fails or returns nothing while the adapter already collects mailboxes, the current set continues to collect and the adapter logs a warning. A temporary failure of discovery does not stop the mailboxes that work. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter: +All adapters support the same `client_options`. Always set them when you use the binary adapter: -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) for this adapter. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. - `client_options.platform`: `gmail`. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from. +- `client_options.sensor_seed_key`: a name for this adapter. LimaCharlie generates Sensor IDs (SID) from this name. ### Adapter-specific Options @@ -88,36 +96,36 @@ Adapter Type: `gmail` | `service_account_credentials` / `service_account_file` | — | Service-account flow credentials (Workspace). | | `subject` | — | Single mailbox to impersonate (service-account flow). | | `subjects` | — | Static list of mailboxes to impersonate. | -| `discover_mailboxes` | `false` | Enumerate the domain's mailboxes via the Directory API. | -| `admin_subject` | — | Admin user impersonated for the Directory API (required with `discover_mailboxes`). | +| `discover_mailboxes` | `false` | Enumerate the mailboxes of the domain with the Directory API. | +| `admin_subject` | — | Admin user to impersonate for the Directory API (necessary with `discover_mailboxes`). | | `customer` | `my_customer` | Directory API customer id (mutually exclusive with `domain`). | | `domain` | — | Restrict discovery to one domain of a multi-domain Workspace. | | `discovery_query` | — | Optional Directory API user search filter, e.g. `orgUnitPath='/Finance'`. | -| `discovery_interval` | `1h` | How often discovery re-enumerates. | +| `discovery_interval` | `1h` | How often discovery enumerates again. | | `include_suspended` | `false` | Also collect suspended mailboxes. | -| `max_concurrent_polls` | `10` | Cap on how many mailboxes poll the Gmail API at once. | +| `max_concurrent_polls` | `10` | Maximum number of mailboxes that poll the Gmail API at the same time. | | `collect_messages` … `collect_history` | see [Capabilities](#capabilities) | Capability toggles. | | `settings_poll_interval` | `15m` | Cadence for the configuration-state capabilities. | -| `user_id` | `me` | Mailbox path segment for the refresh-token flow. Ignored by the service-account flow. | -| `query` | `in:inbox` | Gmail [search query](https://support.google.com/mail/answer/7190) selecting messages. A time bound is appended automatically — do not add one. | +| `user_id` | `me` | Mailbox path segment for the refresh-token flow. The service-account flow ignores it. | +| `query` | `in:inbox` | Gmail [search query](https://support.google.com/mail/answer/7190) that selects messages. The adapter appends a time bound automatically. Do not add one. | | `scopes` | `gmail.readonly` | OAuth scopes to request. | | `format` | `full` | Message detail: `minimal`, `full`, `raw`, or `metadata`. | | `metadata_headers` | — | Headers to keep when `format` is `metadata`. | -| `label_ids` | — | Only list messages carrying all of these label ids. | +| `label_ids` | — | Only list messages that carry all of these label ids. | | `include_spam_trash` | `false` | Include SPAM and TRASH messages. | | `max_results` | `100` | Page size for the message listing (max 500). | -| `poll_interval` | `5m` | Wait between message/history polls. | -| `overlap` | `2m` | Window backdating to avoid gaps from late-indexed mail; re-listed messages are deduped. | -| `initial_lookback` | `0` | On startup, reach back this far to backfill recent mail. | -| `dedupe_ttl` | `168h` (7d) | How long a message id is remembered to suppress re-shipping. | -| `retry_base_delay` / `max_retry_delay` / `max_retry_attempts` | `5s` / `30s` / `3` | Transient-failure retry tuning. | +| `poll_interval` | `5m` | Wait between message and history polls. | +| `overlap` | `2m` | Backdates the window to prevent gaps from mail that Gmail indexes late. The adapter dedupes messages that it lists again. | +| `initial_lookback` | `0` | At startup, go back this far to backfill recent mail. | +| `dedupe_ttl` | `168h` (7d) | How long the adapter remembers a message id and does not send it again. | +| `retry_base_delay` / `max_retry_delay` / `max_retry_attempts` | `5s` / `30s` / `3` | Retry tuning for temporary failures. | ## How collection works -- **Messages**: each poll lists message ids matching `query` over a rolling time window, fetches each message at the configured `format`, and forwards the full message resource verbatim. A deduper keyed on the immutable Gmail message id guarantees each message ships exactly once despite overlapping windows. The event timestamp is the message's `internalDate`. -- **Configuration state**: polled on `settings_poll_interval`; only appearances and changes are shipped. -- **History**: the first run records a baseline `historyId` and ships nothing; later polls list forward from the cursor, filtered to deletions and label changes. Gmail retains history for roughly a week — if the cursor ages out, the adapter re-baselines and resumes rather than stopping. -- **Errors**: `401` triggers one transparent token refresh; `429`/`5xx`/`403` rate-limit errors are retried with backoff; persistently rejected credentials stop that mailbox's collector (other mailboxes are unaffected); a failing BEC capability is logged and skipped without affecting the others. +- **Messages**: each poll lists the message ids that match `query` in a rolling time window. The adapter gets each message in the configured `format` and sends the full message resource unchanged. A deduper uses the immutable Gmail message id, so each message ships one time even when the windows overlap. The event timestamp is the `internalDate` of the message. +- **Configuration state**: the adapter polls on `settings_poll_interval` and sends only new items and changes. +- **History**: the first run records a baseline `historyId` and sends nothing. Later polls list forward from the cursor and keep only deletions and label changes. Gmail keeps history for about one week. If the cursor expires, the adapter makes a new baseline and continues instead of stopping. +- **Errors**: a `401` causes one token refresh. The adapter retries `429`, `5xx`, and `403` rate-limit errors with backoff. Credentials that stay rejected stop the collector of that mailbox, but the other mailboxes continue. The adapter logs and skips a BEC capability that fails, and the other capabilities continue. ## CLI Deployment @@ -140,7 +148,7 @@ chmod +x /path/to/lc_adapter ## Infrastructure as Code Deployment -Full BEC monitoring of a Workspace mailbox — message telemetry plus the persistence, exfiltration, and tamper signals: +This example gives full BEC monitoring of a Workspace mailbox: message telemetry with the persistence, exfiltration, and tamper signals. ```yaml # For cloud sensor deployment, store credentials as hive secrets: @@ -169,7 +177,7 @@ gmail: sensor_seed_key: "gmail-sensor" ``` -Domain-wide auto-discovery — every mailbox in the Workspace, each on its own sensor: +This example uses domain-wide auto-discovery. It collects every mailbox in the Workspace, each mailbox on its own sensor. ```yaml sensor_type: "gmail" @@ -192,7 +200,7 @@ gmail: ## Sample Rule -The BEC capabilities ship each signal under its own event type, so D&R rules can route directly on the signal. For example, flag every change to the account-wide auto-forwarding setting: +The BEC capabilities send each signal with its own event type, so a D&R rule can match the signal directly. This example flags each change to the account-wide auto-forwarding setting: ```yaml # Detection @@ -206,7 +214,7 @@ value: true name: Gmail auto-forwarding enabled ``` -> **Note:** the `gmail.metadata` scope does not allow the `q` search parameter. If you restrict the adapter to that scope, leave `query` empty and rely on `label_ids` / `include_spam_trash` instead. The default `gmail.readonly` scope covers every capability; the narrower `gmail.metadata` scope cannot read the settings sub-resources, so a capability using them will be logged and skipped. +> **Note:** the `gmail.metadata` scope does not allow the `q` search parameter. If you limit the adapter to that scope, leave `query` empty and use `label_ids` and `include_spam_trash`. The default `gmail.readonly` scope covers every capability. The narrower `gmail.metadata` scope cannot read the settings sub-resources, so the adapter logs and skips a capability that uses them. ## API Docs diff --git a/docs/2-sensors-deployment/adapters/types/google-cloud-pubsub.md b/docs/2-sensors-deployment/adapters/types/google-cloud-pubsub.md index ea64d7896..0cafa73d6 100644 --- a/docs/2-sensors-deployment/adapters/types/google-cloud-pubsub.md +++ b/docs/2-sensors-deployment/adapters/types/google-cloud-pubsub.md @@ -2,7 +2,7 @@ ## Overview -This Adapter allows you to ingest events from a Google Cloud Pubsub subscription. +This Adapter ingests events from a Google Cloud Pubsub subscription. ## Configurations @@ -10,12 +10,12 @@ Adapter Type: `pubsub` - `client_options`: see [common adapter configuration](../usage.md). - `sub_name`: the name of the subscription to subscribe to. -- `service_account_creds`: the string version of the JSON credentials for a (Google) Service Account to use accessing the subscription. +- `service_account_creds`: the string version of the JSON credentials for a (Google) Service Account that accesses the subscription. - `project_name`: project name where the `sub_name` exists. ### CLI Deployment -This example assumes that the Adapter is running from a host that has [default credentials](https://cloud.google.com/docs/authentication/production) (via the `GOOGLE_APPLICATION_CREDENTIALS` environment variable) setup. If it's not the case you will need to use `service_account_creds` to provide the contents of the JSON credentials of the GCP Service Account to use. +This example assumes that the Adapter runs on a host that has [default credentials](https://cloud.google.com/docs/authentication/production), set with the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. If the host does not have them, use `service_account_creds` to give the contents of the JSON credentials of the GCP Service Account. ```bash ./lc_adapter pubsub client_options.identity.installation_key=f5eaaaad-575a-498e-bfc2-5f83e249a646 \ @@ -26,14 +26,14 @@ This example assumes that the Adapter is running from a host that has [default c client_options.sensor_seed_key=gcplogs ``` -Here's the breakdown of the above example: +This list explains the example above: -- `lc_adapter`: simply the CLI Adapter. -- `pubsub`: the method the Adapter should use to collect data locally. +- `lc_adapter`: the CLI Adapter. +- `pubsub`: the method that the Adapter uses to collect data locally. - `client_options.identity.installation_key=....`: the Installation Key value from LimaCharlie. -- `client_options.identity.oid=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=gcp`: this indicates that the data read is logs from Google Cloud Platform. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor ID generated for this Adapter later if you have to re-install the Adapter. +- `client_options.identity.oid=....`: the LimaCharlie Organization ID that the installation key above belongs to. +- `client_options.platform=gcp`: shows that the data is logs from Google Cloud Platform. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the Adapter. Record it. If you install the Adapter again, you can re-use the Sensor ID that LimaCharlie generated for it. - `sub_name=usp`: the Subscription name to consume the logs from. - `project_name=monitored-proj`: the GCP Project name this Subscription belongs to. diff --git a/docs/2-sensors-deployment/adapters/types/google-cloud-storage.md b/docs/2-sensors-deployment/adapters/types/google-cloud-storage.md index 2907c3959..1f65ee2c2 100644 --- a/docs/2-sensors-deployment/adapters/types/google-cloud-storage.md +++ b/docs/2-sensors-deployment/adapters/types/google-cloud-storage.md @@ -2,9 +2,9 @@ ## Overview -This Adapter allows you to ingest files/blobs stored in Google Cloud Storage (GCS). +This Adapter ingests files and blobs that are stored in Google Cloud Storage (GCS). -Note that this adapter operates as a sink by default, meaning it will "consume" files from the GCS bucket by deleting them once ingested. +By default, this adapter operates as a sink: it "consumes" the files in the GCS bucket. It deletes each file after it ingests the file. ## Configurations @@ -12,9 +12,9 @@ Adapter Type: `gcs` - `client_options`: see [common adapter configuration](../usage.md). - `bucket_name`: the name of the bucket to ingest from. -- `service_account_creds`: the string version of the JSON credentials for a (Google) Service Account to use accessing the bucket. -- `prefix`: only ingest files with a given path prefix. -- `single_load`: if `true`, the adapter will not operate as a sink, it will ingest all files in the bucket once and will then exit. +- `service_account_creds`: the string version of the JSON credentials for a (Google) Service Account that accesses the bucket. +- `prefix`: only ingest files that have this path prefix. +- `single_load`: if `true`, the adapter does not operate as a sink. It ingests all files in the bucket one time and then exits. ### Infrastructure as Code Deployment diff --git a/docs/2-sensors-deployment/adapters/types/google-workspace.md b/docs/2-sensors-deployment/adapters/types/google-workspace.md index 7ffd3c5a3..3d997a9e8 100644 --- a/docs/2-sensors-deployment/adapters/types/google-workspace.md +++ b/docs/2-sensors-deployment/adapters/types/google-workspace.md @@ -1,33 +1,33 @@ # Google Workspace -[Google Workspace](https://workspace.google.com/) provides various communication, collaboration, and productivity applications for businesses of all sizes. [Google Workspace audit logs](https://cloud.google.com/logging/docs/audit/gsuite-audit-logging) provide data to help track "Who did what, where, an when?". +[Google Workspace](https://workspace.google.com/) gives communication, collaboration, and productivity applications to businesses of all sizes. [Google Workspace audit logs](https://cloud.google.com/logging/docs/audit/gsuite-audit-logging) supply data that helps you track "Who did what, where, and when?". -Google Workspace Audit logs can be ingested via a Google Cloud Platform, deploye as a cloud-to-cloud LimaCharlie Adapter. Events will be ingested and observed via the `gcp` platform. +LimaCharlie ingests Google Workspace Audit logs through Google Cloud Platform, with a cloud-to-cloud LimaCharlie Adapter. The `gcp` platform ingests and shows the events. ## Adapter Deployment -Prior to ingesting Google Workspace Audit logs in LimaCharlie, you must first configure logs to be written to GCP. Afterwards, a cloud-to-cloud GCP Adapter can be deployed to ingest these events into LimaCharlie. +Before LimaCharlie can ingest Google Workspace Audit logs, you must configure the logs to write to GCP. Then deploy a cloud-to-cloud GCP Adapter to ingest these events into LimaCharlie. -The following steps help prepare this: +These steps prepare the deployment: ### Step 1: Enable Platform Sharing in Google Workspace -In the Google Workspace admin console navigate to [Account -> Account Settings -> Legal and Compliance](https://admin.google.com/u/1/ac/companyprofile/legal) +In the Google Workspace admin console, go to [Account -> Account Settings -> Legal and Compliance](https://admin.google.com/u/1/ac/companyprofile/legal). -Verify that under "Sharing options", `Google Cloud Platform Sharing Options` is set to Enabled. +Under "Sharing options", check that `Google Cloud Platform Sharing Options` is set to Enabled. -For further details, refer to [Google's documentation on Audit logs for Google Workspace](https://cloud.google.com/logging/docs/audit/gsuite-audit-logging) +For more details, see [Google's documentation on Audit logs for Google Workspace](https://cloud.google.com/logging/docs/audit/gsuite-audit-logging). ### Step 2: Verify logs appear in Google Cloud Platform -In the GCP Console go to the [Logs Explorer](https://console.cloud.google.com/logs/query). Ensure you're at the organization level (and not in a particular folder). +In the GCP Console, go to the [Logs Explorer](https://console.cloud.google.com/logs/query). Make sure that you are at the organization level, and not in a folder. -From the Resources drop-down, choose `Audited Resource`, then press Apply. +From the Resources drop-down, choose `Audited Resource`. Then press Apply. -You should see logging details related to Google Workspace, under the following log name(s): +Log details for Google Workspace appear under this log name: `logName:admin.googleapis.com` ### Step 3: Create a cloud-to-cloud GCP Adapter -Once Google Workspace Audit logs are pushed to GCP, events can be ingested via either [Google Cloud Storage](google-cloud-storage.md) or [Google Cloud Pubsub](google-cloud-pubsub.md). Utilize the appropriate documentation to set up the desired Adapter. +After GCP receives the Google Workspace Audit logs, you can ingest the events with [Google Cloud Storage](google-cloud-storage.md) or [Google Cloud Pubsub](google-cloud-pubsub.md). Use the page for the Adapter that you choose. diff --git a/docs/2-sensors-deployment/adapters/types/hubspot.md b/docs/2-sensors-deployment/adapters/types/hubspot.md index 3d28cb6e3..bbd1a7da0 100644 --- a/docs/2-sensors-deployment/adapters/types/hubspot.md +++ b/docs/2-sensors-deployment/adapters/types/hubspot.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to HubSpot to fetch [account activity logs](https://developers.hubspot.com/docs/guides/api/settings/account-activity-api). +This Adapter connects to HubSpot and gets [account activity logs](https://developers.hubspot.com/docs/guides/api/settings/account-activity-api). ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always set them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to set these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) for this adapter. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name for this adapter. LimaCharlie generates Sensor IDs (SID) from this name. See below. ### Adapter-specific Options diff --git a/docs/2-sensors-deployment/adapters/types/iis.md b/docs/2-sensors-deployment/adapters/types/iis.md index bcdf8ae8b..576186f4b 100644 --- a/docs/2-sensors-deployment/adapters/types/iis.md +++ b/docs/2-sensors-deployment/adapters/types/iis.md @@ -1,29 +1,29 @@ # IIS Logs -Microsoft's Internet Information Services (IIS) web server is a web server commonly found on Microsoft Windows servers. This Adapter assists with sending IIS web logs to LimaCharlie via the Adapter binary. +Microsoft Internet Information Services (IIS) is a web server that is common on Microsoft Windows servers. This Adapter sends IIS web logs to LimaCharlie with the Adapter binary. Telemetry Platform (if applicable): `iis` ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always set them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to set these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) for this adapter. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name for this adapter. LimaCharlie generates Sensor IDs (SID) from this name. See below. ### Adapter-specific Options -IIS web logs often have a standardized schema, unless manually changed by administrators. The `iis` platform in LimaCharlie expects the following structure: +IIS web logs usually have a standard schema, unless an administrator changes it. The `iis` platform in LimaCharlie expects this structure: `#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken` #### Log Structure -If your IIS logs are a different structure from above, please let us know and we can assist in customizing the parser! +If your IIS logs have a different structure, contact the LimaCharlie team. The team can customize the parser. -The structure of these fields is as follows: +These are the fields: | Field Name | Explanation | | --- | --- | @@ -33,21 +33,21 @@ The structure of these fields is as follows: | cs-method | The method of request from the client | | cs-uri-stem | The URI requested by the client | | cs-uri-query | The query added to the URI in the client request | -| s-port | The server port) | -| cs-username | The client username (if provided) | +| s-port | The server port | +| cs-username | The client username (if the client supplies one) | | c-ip | The IP address of the client | | cs-user-agent | The user-agent of the client | | cs-referer | The referer that directed the client to the site | | sc-status | The service status code | | sc-substatus | The service substatus code (if applicable) | | sc-win32-status | The Windows status code | -| time-taken | The time taken to render the request resource(s) | +| time-taken | The time to render the requested resources | ## Configuration File -IIS logs are typically stored "on disk" of the web server, in files that roll daily. Thus, collecting IIS web logs would be done with a binary Adapter that can monitor specific IIS log folder(s) for new files. The Adapter type would be `file`, while the platform is `iis`. +IIS keeps the logs on the disk of the web server, in files that roll daily. To collect IIS web logs, use a binary Adapter that monitors the IIS log folders for new files. The Adapter type is `file`, and the platform is `iis`. -The following configuration file can be used as a starter to monitor IIS web log directories. Replace any values with `< >` characters with values unique to your Organization and/or deployment. *Do not include the* `<` *or* `>` *characters in your config file!* +Use the configuration file below as a start to monitor the directories of IIS web logs. Replace each value in `< >` characters with a value that is unique to your Organization or deployment. *Do not include the* `<` *or* `>` *characters in your config file!* ### Please customize according to your environment/LimaCharlie organization @@ -66,18 +66,18 @@ file: no_follow: false ``` -A few notes about the IIS platform parser: +These notes apply to the IIS platform parser: -- The server IP address (identified in the logs as `s-ip` will be used as the hostname within LimaCharlie. -- The `date` and `time` fields are combined to a single field represented as `ts`. The above configuration uses this field as the event time, unless removed. -- The `sensor_seed_key` can be any value of your choosing, please make sure it's unique per web server. -- You can specify multiple configurations in one file if you wish to collect logs from multiple folders. -- The `no_follow: false` specification ensures that the Adapter monitors for new files and/or writes to existing files. You can exclude this option if you are going to ingest "dead" log files. -- All IIS events will be represented as `IIS_WEBLOG` in the Adapter telemetry. +- LimaCharlie uses the server IP address (`s-ip` in the logs) as the hostname. +- The parser combines the `date` and `time` fields into one field, `ts`. The configuration above uses this field as the event time, unless you remove the mapping. +- The `sensor_seed_key` can be any value. Make sure that it is unique for each web server. +- To collect logs from more than one folder, set more than one configuration in one file. +- The `no_follow: false` option makes sure that the Adapter monitors for new files and for writes to existing files. Remove this option if you ingest "dead" log files. +- The Adapter telemetry shows all IIS events as `IIS_WEBLOG`. -If you have any questions about collecting IIS web logs, please reach out to the LimaCharlie team. +If you have questions about the collection of IIS web logs, contact the LimaCharlie team. -Once the config file is set, you can run the Adapter on Windows with the following command (assuming the file is named `config.yaml`): +After you set the config file, run the Adapter on Windows with this command. The example assumes that the file is named `config.yaml`: `.exe file config.yaml` diff --git a/docs/2-sensors-deployment/adapters/types/imap.md b/docs/2-sensors-deployment/adapters/types/imap.md index cb13db2be..6c0367927 100644 --- a/docs/2-sensors-deployment/adapters/types/imap.md +++ b/docs/2-sensors-deployment/adapters/types/imap.md @@ -2,7 +2,7 @@ ## Overview -This Adapter allows you to ingest emails as events from an IMAP server. +This Adapter ingests emails from an IMAP server as events. ## Configurations @@ -10,15 +10,15 @@ Adapter Type: `imap` - `client_options`: see [common adapter configuration](../usage.md). - `server`: the domain and port of the IMAP server, like `imap.gmail.com:993`. -- `username`: the user name to log in to IMAP as. -- `password`: the password for the above user name. +- `username`: the user name for the IMAP login. +- `password`: the password for the user name above. - `inbox_name`: the name of the inbox to monitor. -- `is_insecure`: do NOT connect using SSL. +- `is_insecure`: do NOT connect with SSL. - `from_zero`: collect all existing emails in the inbox. -- `include_attachments`: send attachment data to LimaCharlie, used to generate attachment hashes in the cloud. +- `include_attachments`: send attachment data to LimaCharlie. The cloud uses this data to generate attachment hashes. - `max_body_size`: only send attachments below this many bytes to LimaCharlie. -- `attachment_ingest_key`: if specified, an [Ingestion Key](../../../7-administration/access/api-keys.md) used to ingest attachment as Artifacts into LimaCharlie. -- `attachment_retention_days`: the number of days to retain Artifact attachment for. +- `attachment_ingest_key`: if set, an [Ingestion Key](../../../7-administration/access/api-keys.md) that ingests attachments into LimaCharlie as Artifacts. +- `attachment_retention_days`: the number of days to keep the Artifact attachment. ### Configuration File Example @@ -51,9 +51,9 @@ imap: ## Use Cases -Although this Adapter can be used on any IMAP server for any inbox, it is often used to perform enterprise wide analysis and alerting using Email Journaling. +You can use this Adapter with any IMAP server and any inbox. A frequent use is analysis and alerting across an enterprise with Email Journaling. -Email Journaling is supported by all major email platforms to perform analysis at scale. It generally involves enabling a data flow of all emails on the platform towards a specific email account where all emails accumulate. +All major email platforms support Email Journaling for analysis at scale. Email Journaling sends all emails on the platform to one email account, where the emails accumulate. Documentation for common platforms: @@ -62,7 +62,7 @@ Documentation for common platforms: ## Example Format -Emails ingested through the IMAP Adapter are in raw format so that detailed header information can be included and analyzed. Below is an example of an email received into LimaCharlie from a Google Workspace mailbox: +The IMAP Adapter ingests emails in raw format, so each event keeps the full header information for analysis. This example shows an email that LimaCharlie received from a Google Workspace mailbox: ```json { diff --git a/docs/2-sensors-deployment/adapters/types/it-glue.md b/docs/2-sensors-deployment/adapters/types/it-glue.md index bcdfab77c..d37d588f1 100644 --- a/docs/2-sensors-deployment/adapters/types/it-glue.md +++ b/docs/2-sensors-deployment/adapters/types/it-glue.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to IT Glue to fetch activity logs. +This Adapter connects to IT Glue and gets activity logs. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always set them when you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to set these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) for this adapter. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name for this adapter. LimaCharlie generates Sensor IDs (SID) from this name. See below. ### Adapter-specific Options diff --git a/docs/2-sensors-deployment/adapters/types/json.md b/docs/2-sensors-deployment/adapters/types/json.md index 97302e30b..198bb8082 100644 --- a/docs/2-sensors-deployment/adapters/types/json.md +++ b/docs/2-sensors-deployment/adapters/types/json.md @@ -2,22 +2,22 @@ ## Overview -This Adapter allows you to ingest JSON-formatted logs from a file. It uses the [File](file.md) adapter with `client_options.platform` set to `json`. +This Adapter lets you ingest JSON-formatted logs from a file. It uses the [File](file.md) adapter with `client_options.platform` set to `json`. -When ingesting JSON data, each line of the file is expected to contain a complete JSON object (one object per line). For JSON objects that span multiple lines, use the `multi_line_json: true` option. +Each line of the file must contain one complete JSON object. If a JSON object spans multiple lines, use the `multi_line_json: true` option. Adapter type: `file` ## Configuration -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. - `client_options.platform`: set to `json` for JSON-formatted logs. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name. -Since this adapter uses the file adapter under the hood, all [File adapter options](file.md) are available, including `no_follow`, `backfill`, `poll`, `multi_line_json`, and others. +This adapter uses the file adapter, so all [File adapter options](file.md) are available. These options include `no_follow`, `backfill`, `poll`, `multi_line_json`, and more. ### Configuration File Example diff --git a/docs/2-sensors-deployment/adapters/types/kubernetes-pods.md b/docs/2-sensors-deployment/adapters/types/kubernetes-pods.md index 22fee7906..af9d460f4 100644 --- a/docs/2-sensors-deployment/adapters/types/kubernetes-pods.md +++ b/docs/2-sensors-deployment/adapters/types/kubernetes-pods.md @@ -2,9 +2,9 @@ ## Overview -This Adapter allows you to ingest the logs from the pods running in a Kubernetes cluster. +This Adapter lets you ingest the logs from the pods that run in a Kubernetes cluster. -The adapter relies on local filesystem access to the standard Kubernetes pod logging structure. This means the adapter is best run as a Daemon Set in Kubernetes with the pod logs location mounted (usually `/var/log/pods`). +The adapter needs local filesystem access to the standard structure of Kubernetes pod logs. For this reason, it is best to run the adapter as a Daemon Set in Kubernetes, with the location of the pod logs mounted (usually `/var/log/pods`). A [public Docker container](https://hub.docker.com/r/refractionpoint/lc-adapter-k8s-pods) is available as `refractionpoint/lc-adapter-k8s-pods`. @@ -15,7 +15,7 @@ Adapter Type: `k8s_pods` The following fields are required for configuration: - `client_options`: see [common adapter configuration](../usage.md). -- `root`: The root of the Kubernetes directory storing logs, usually `/var/log/pods`. +- `root`: The root of the Kubernetes directory that stores logs, usually `/var/log/pods`. ### Infrastructure as Code Deployment diff --git a/docs/2-sensors-deployment/adapters/types/mac-unified-logging.md b/docs/2-sensors-deployment/adapters/types/mac-unified-logging.md index c9b35c5e2..79484c253 100644 --- a/docs/2-sensors-deployment/adapters/types/mac-unified-logging.md +++ b/docs/2-sensors-deployment/adapters/types/mac-unified-logging.md @@ -2,20 +2,20 @@ ## Overview -This Adapter allows you to collect events from MacOS Unified Logging. +This Adapter lets you collect events from MacOS Unified Logging. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name, see below. **Optional Arguments:** -- `predicate`: an [NSPredicate](https://developer.apple.com/documentation/foundation/nspredicate) filter string to limit which log entries are collected. Example: `predicate='subsystem=="com.apple.TimeMachine"'` +- `predicate`: an [NSPredicate](https://developer.apple.com/documentation/foundation/nspredicate) filter string that limits which log entries the adapter collects. Example: `predicate='subsystem=="com.apple.TimeMachine"'` - `write_timeout_sec`: number of seconds before a write to LimaCharlie times out (default: 600). ## CLI Deployment @@ -50,7 +50,7 @@ mac_unified_logging: ## Service Creation -If you want this adapter to run as a service, you can run the following script to add a plist file to the endpoint **with your variables replaced**. Please note that this example also has an example predicate, so if you do not wish to use a predicate, remove that line. +To run this adapter as a service, run the script below. It adds a plist file to the endpoint **with your variables replaced**. This example also contains an example predicate. If you do not want to use a predicate, remove that line. ```bash sudo -i diff --git a/docs/2-sensors-deployment/adapters/types/microsoft-365.md b/docs/2-sensors-deployment/adapters/types/microsoft-365.md index 10a6b18d6..a101430c5 100644 --- a/docs/2-sensors-deployment/adapters/types/microsoft-365.md +++ b/docs/2-sensors-deployment/adapters/types/microsoft-365.md @@ -1,16 +1,16 @@ # Microsoft 365 -Microsoft 365, formerly Office 365, is a product family of productivity software, collaboration and cloud-based services owned by Microsoft. This Adapter allows you to ingest audit events from the [Office 365 Management Activity API](https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-reference). +Microsoft 365, formerly Office 365, is a family of products from Microsoft. It contains productivity software, collaboration tools, and cloud-based services. This Adapter lets you ingest audit events from the [Office 365 Management Activity API](https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-reference). -Microsoft 365 events can be ingested in LimaCharlie and observed as the `office365` platform. +LimaCharlie ingests Microsoft 365 events and shows them as the `office365` platform. -> Always set `client_options.platform: office365` for this adapter. The `office365` parser extracts the event type (`Operation`) and timestamp (`CreationTime`) from unified audit log records automatically — no manual `mapping` is needed. Do not substitute `json`. +> Always set `client_options.platform: office365` for this adapter. The `office365` parser extracts the event type (`Operation`) and the timestamp (`CreationTime`) from unified audit log records automatically. You do not need a manual `mapping`. Do not use `json` instead. > -> **Note on naming:** The platform identifier `office365` reflects the legacy product name. Microsoft renamed Office 365 to Microsoft 365 in 2020. +> **Note on naming:** The platform identifier `office365` comes from the legacy product name. Microsoft renamed Office 365 to Microsoft 365 in 2020. ## Adapter Deployment -Microsoft 365 events are ingested via a cloud-to-cloud Adapter configured specifically to review M365 events. When creating an Adapter, the following data points are required: +A cloud-to-cloud Adapter ingests Microsoft 365 events. You configure this Adapter specifically to review M365 events. When you create an Adapter, these values are required: - `domain`: Office 365 domain - `tenant_id`: Office 365 tenant ID @@ -34,9 +34,9 @@ Microsoft 365 events are ingested via a cloud-to-cloud Adapter configured specif For the complete list of audit activities by workload, see [Microsoft's audit log activities documentation](https://learn.microsoft.com/en-us/purview/audit-log-activities). -If creating a Microsoft 365 Adapter via the Web UI, the helper form will navigate you through providing these values. +If you create a Microsoft 365 Adapter in the Web UI, the helper form guides you through these values. -Establishing a cloud-to-cloud connector between LimaCharlie and Office 365 requires a few steps to provide the correct permissions for the [Office 365 Management Activity API](https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-reference). +To connect LimaCharlie to Office 365, you must first do some steps. These steps give the correct permissions for the [Office 365 Management Activity API](https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-reference). ### Infrastructure as Code Deployment @@ -75,29 +75,29 @@ office365: ### Preparing Office 365 details -To establish an Office 365 adapter, we will need to complete a few steps within the Azure portal. Ensure that you have the correct permissions to set up a new App registration. +To establish an Office 365 adapter, you must do some steps in the Azure portal. Make sure that you have the correct permissions to create a new App registration. - Within the Microsoft Azure portal, create a new App registration. See Microsoft's [App registration Quickstart](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). -- The LimaCharlie connector requires a secret for Office 365 data. You can create one under `Certificates & secrets`. Be sure to copy this value and save it somewhere - you can only view it once. +- The LimaCharlie adapter needs a secret for Office 365 data. Create one under `Certificates & secrets`. Copy this value and save it - you can see it one time only. ![image.png](../../../assets/images/image(73).png) -- Additionally, you'll need to ensure that the app has the correct permissions to view Office 365 data via the Management API. Within `API Permissions`, configure the following permissions: +- The app must also have the correct permissions to view Office 365 data through the Management API. Within `API Permissions`, configure these permissions: - `ActivityFeed.Read` (Delegated & Application) - `ActivityFeed.ReadDlp` (Delegated & Application) *[if you want DLP permissions]* ![image.png](../../../assets/images/image(74).png) -Additionally, you may need to grant admin consent to the above permissions. +It is possible that you must also grant admin consent for these permissions. -At this point, you should have all the details you need to configure the Adapter. +You now have all the details that you need to configure the Adapter. ### Setting Up the Adapter -Within the LimaCharlie web application, select `+ Add` Sensor, and then select `Office 365`: +Within the LimaCharlie web app, select `+ Add` Sensor. Then select `Office 365`: -You can select a pre-existing Installation Key or create a new one, unique for this adapter. Once an Installation Key is selected, you will be prompted with a form to finish setting up the adapter. Choose your desired adapter name, and provide the following values: +Select an existing Installation Key, or create a new key for this adapter. After you select an Installation Key, the web app shows a form. Choose a name for the adapter and give these values: | Item | Azure Portal Location | | --- | --- | @@ -108,7 +108,7 @@ You can select a pre-existing Installation Key or create a new one, unique for t | Client Secret | Created during creation in Certificates & secrets | | API Endpoint | `enterprise`, `gcc-gov`, `gcc-high-gov`, or `dod-gov` | -Finally, you will also need to select a "Content Type" to import. This is the type of events you want to bring in to LimaCharlie. The options are as follows: +You must also select a "Content Type" to import. This is the type of events that you want to ingest into LimaCharlie. The options are: - `Audit.AzureActiveDirectory` - `Audit.Exchange` @@ -118,18 +118,18 @@ Finally, you will also need to select a "Content Type" to import. This is the ty Without a value, the default is *all of the above*. -Click `Complete Cloud Installation`, and LimaCharlie will attempt to connect to the Microsoft Office 365 Management API and pull events. +Click `Complete Cloud Installation`. LimaCharlie then tries to connect to the Microsoft Office 365 Management API and pull events. ## Sample Rule -When ingested into LimaCharlie, Office 365 data can be referenced directly in your D&R rules. You could do this via a platform operator: +After LimaCharlie ingests Office 365 data, you can reference the data directly in your D&R rules. One method is the platform operator: ```yaml op: is platform name: office365 ``` -We can also reference Office 365 events directly. The following sample rule looks at `FileAccessed` events from anonymous user names, and reports accordingly. +You can also reference Office 365 events directly. The sample rule below looks at `FileAccessed` events from anonymous user names and reports them. ```yaml # Detection @@ -143,4 +143,4 @@ value: anon name: OneDrive File Accessed by Anonymous User ``` -Note that in the detection above, we pivot on the `FileAccessed` event, which is associated with SharePoint activity. Available event types will depend on source activity and events ingested. See Microsoft's [audit log activities reference](https://learn.microsoft.com/en-us/purview/audit-log-activities). +The detection above uses the `FileAccessed` event, which is associated with SharePoint activity. The available event types depend on the source activity and the events that you ingest. See Microsoft's [audit log activities reference](https://learn.microsoft.com/en-us/purview/audit-log-activities). diff --git a/docs/2-sensors-deployment/adapters/types/microsoft-defender.md b/docs/2-sensors-deployment/adapters/types/microsoft-defender.md index 6b2dee507..5394cef0e 100644 --- a/docs/2-sensors-deployment/adapters/types/microsoft-defender.md +++ b/docs/2-sensors-deployment/adapters/types/microsoft-defender.md @@ -2,13 +2,13 @@ ## Overview -LimaCharlie can ingest [Microsoft 365 Defender logs](https://learn.microsoft.com/en-us/microsoft-365/security/defender/microsoft-365-defender?view=o365-worldwide) via three methods [Azure Event Hub](azure-event-hub.md) Adapter, the [Microsoft Defender API](https://learn.microsoft.com/en-us/defender-endpoint/api/exposed-apis-create-app-nativeapp), or a Custom Webhook +LimaCharlie can ingest [Microsoft 365 Defender logs](https://learn.microsoft.com/en-us/microsoft-365/security/defender/microsoft-365-defender?view=o365-worldwide) with three methods: the [Azure Event Hub](azure-event-hub.md) Adapter, the [Microsoft Defender API](https://learn.microsoft.com/en-us/defender-endpoint/api/exposed-apis-create-app-nativeapp), or a Custom Webhook Microsoft has [documentation for creating an Event Hub](https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-create). Telemetry Platform: `msdefender` -> Use `client_options.platform: msdefender` for **both** ingestion methods. The `msdefender` parser understands the Streaming API `records` envelope (Event Hub) as well as bare Graph `alerts_v2` alert objects (API adapter), extracting event types and timestamps automatically and mapping raw device telemetry to native LimaCharlie event types (`NEW_PROCESS`, `NETWORK_CONNECTIONS`, etc.) with one sensor per Defender device. Do not substitute `json` — it bypasses this parser and requires manual field mappings. +> Use `client_options.platform: msdefender` for **both** ingestion methods. The `msdefender` parser reads the Streaming API `records` envelope (Event Hub) and also bare Graph `alerts_v2` alert objects (API adapter). It extracts event types and timestamps automatically. It maps raw device telemetry to native LimaCharlie event types (`NEW_PROCESS`, `NETWORK_CONNECTIONS`, and others), with one sensor for each Defender device. Do not use `json` instead. The `json` platform does not use this parser and needs manual field mappings. ## Data Collected @@ -21,20 +21,20 @@ Telemetry Platform: `msdefender` ### Microsoft Defender API -The API adapter polls Microsoft Graph's `/security/alerts_v2` endpoint every 30 seconds. This provides **security alerts** from Microsoft Defender products including: +The API adapter polls Microsoft Graph's `/security/alerts_v2` endpoint every 30 seconds. It gives **security alerts** from Microsoft Defender products, which include: - Defender for Endpoint - Defender for Office 365 - Defender for Identity - Defender for Cloud Apps -These are curated, high-fidelity alerts that Microsoft has already correlated and enriched. +These are curated, high-fidelity alerts that Microsoft correlated and enriched. For alert schema details, see [Microsoft's alerts_v2 API documentation](https://learn.microsoft.com/en-us/graph/api/resources/security-alert). ### Azure Event Hub (Streaming API) -When using Event Hub with Defender, you receive **raw telemetry** via the Defender Streaming API. This includes detailed event tables such as: +When you use Event Hub with Defender, you receive **raw telemetry** through the Defender Streaming API. The telemetry includes event tables such as: - **DeviceProcessEvents** - Process creation and execution - **DeviceNetworkEvents** - Network connections @@ -43,13 +43,13 @@ When using Event Hub with Defender, you receive **raw telemetry** via the Defend - **DeviceRegistryEvents** - Registry modifications - **DeviceEvents** - Miscellaneous security events -This provides full endpoint telemetry for custom detection rules and threat hunting. +This method gives full endpoint telemetry for custom detection rules and threat hunting. For the complete list of supported streaming event types, see [Microsoft's Defender XDR streaming event types documentation](https://learn.microsoft.com/en-us/defender-xdr/supported-event-types). ### Defender API Configuration -To collect data via the Microsoft Defender API, configure an App Registration in Azure with the following permission: +To collect data through the Microsoft Defender API, configure an App Registration in Azure with this permission: - `SecurityAlert.Read.All` @@ -61,24 +61,24 @@ Then create a Defender adapter in LimaCharlie with: ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name, see below. ### Adapter-specific Options -- `connection_string` - The connection string provided in Azure for connecting to the Azure Event Hub, including the `EntityPath=...` at the end which identifies the Hub Name (this component is sometimes now shown in the connection string provided by Azure). +- `connection_string` - The connection string that Azure gives you to connect to the Azure Event Hub. It includes the `EntityPath=...` at the end, which identifies the Hub Name (this component is sometimes now shown in the connection string provided by Azure). ## Guided Deployment -In the LimaCharlie web app, you can find a Microsoft Defender helper for connecting to an existing Azure Event Hub and ingesting Microsoft Defender logs. +The LimaCharlie web app has a Microsoft Defender helper. Use it to connect to an existing Azure Event Hub and to ingest Microsoft Defender logs. ### CLI Deployment -The following example configuration ingests Microsoft Defender logs from an Azure Event Hub to LimaCharlie. +The example configuration below ingests Microsoft Defender logs from an Azure Event Hub into LimaCharlie. ```bash ./lc_adapter azure_event_hub client_options.identity.installation_key= \ diff --git a/docs/2-sensors-deployment/adapters/types/microsoft-entra-id.md b/docs/2-sensors-deployment/adapters/types/microsoft-entra-id.md index 5b9ca6df2..2ebac9bab 100644 --- a/docs/2-sensors-deployment/adapters/types/microsoft-entra-id.md +++ b/docs/2-sensors-deployment/adapters/types/microsoft-entra-id.md @@ -2,16 +2,16 @@ [Microsoft Entra ID](https://www.microsoft.com/en-us/security/business/identity-access/microsoft-entra-id), formerly Azure Active Directory, is an identity and access management solution from Microsoft that helps organizations secure and manage identities for hybrid and multicloud environments. -The Entra ID API Adapter polls Microsoft Graph directly and can collect three streams: Identity Protection **risk detections**, **sign-in logs** and **directory audit logs**. Because it only needs an Entra app registration — no Azure subscription or Event Hub — it is the lowest-friction way to standardize Entra telemetry collection across tenants. Data received via an Azure Event Hub or Webhook will be unique to your custom output parameters. +The Entra ID API Adapter polls Microsoft Graph directly. It can collect three streams: Identity Protection **risk detections**, **sign-in logs** and **directory audit logs**. It needs only an Entra app registration, and no Azure subscription or Event Hub. Therefore, it is the least complex method to standardize the collection of Entra telemetry across tenants. Data that you receive through an Azure Event Hub or Webhook is unique to your custom output parameters. -Entra ID data uses one of two platform values depending on the ingestion method — they are **not** interchangeable: +Entra ID data uses one of two platform values, which depend on the ingestion method. The two values are **not** interchangeable: - **Azure Event Hub / Webhook** (diagnostic settings log stream — SignInLogs, AuditLogs, etc.): `client_options.platform: azure_ad` - **Entra ID API** (risk detections, sign-in logs and directory audit logs polled from Microsoft Graph): `client_options.platform: entraid` -> **Note on naming:** The platform identifier `azure_ad` reflects the legacy product name (Azure Active Directory). Microsoft renamed this product to Microsoft Entra ID in 2023. Despite naming the same product, `azure_ad` and `entraid` select different parsers: `azure_ad` parses the Azure diagnostic-stream `records` envelope (event type from `category`, timestamp from `time`), while `entraid` parses the Graph objects directly (event type from `activity`/`category`, or `SignIn` for sign-in records; timestamp from `detectedDateTime`/`activityDateTime`/`createdDateTime` depending on the stream). Crossing them silently breaks event-type and timestamp extraction. +> **Note on naming:** The platform identifier `azure_ad` comes from the legacy product name (Azure Active Directory). Microsoft renamed this product to Microsoft Entra ID in 2023. The two identifiers name the same product, but they select different parsers. `azure_ad` parses the Azure diagnostic-stream `records` envelope (event type from `category`, timestamp from `time`). `entraid` parses the Graph objects directly (event type from `activity`/`category`, or `SignIn` for sign-in records; timestamp from `detectedDateTime`/`activityDateTime`/`createdDateTime`, which depends on the stream). If you cross the two, the extraction of the event type and the timestamp breaks without an error. > -> **Choosing by data need:** Directory audit events — app consent (`Consent to application`), OAuth2 permission grants (`Add OAuth2PermissionGrant`), app role assignments, user/group/role changes — are available from the API adapter's `audit_logs` stream, from the diagnostic-stream **AuditLogs** category (Event Hub, platform `azure_ad`), or from the Microsoft 365 unified audit log ([`office365` adapter](microsoft-365.md), `Audit.AzureActiveDirectory` content type, where operation names carry a trailing period). Also prefer `azure_ad` over `azure_monitor` for Entra streams: both parse the same envelope, but the platform value tags the sensor and drives `is platform` / LCQL targeting and shared detection rules. +> **Choosing by data need:** Directory audit events include app consent (`Consent to application`), OAuth2 permission grants (`Add OAuth2PermissionGrant`), app role assignments, and changes to users, groups and roles. Three sources give these events: the API adapter's `audit_logs` stream, the diagnostic-stream **AuditLogs** category (Event Hub, platform `azure_ad`), and the Microsoft 365 unified audit log ([`office365` adapter](microsoft-365.md), `Audit.AzureActiveDirectory` content type, where operation names have a trailing period). For Entra streams, use `azure_ad` and not `azure_monitor`. Both parse the same envelope, but the platform value tags the sensor. The tag then controls `is platform` and LCQL targeting, and shared detection rules. ## Data Collected @@ -33,32 +33,32 @@ The API adapter polls Microsoft Graph every 30 seconds. The `streams` option sel | `sign_ins` | `/auditLogs/signIns` | Interactive sign-in events (user, app, IP, location, device, conditional access result) | `SignIn` | | `audit_logs` | `/auditLogs/directoryAudits` | Directory changes: user/group/role management, app registrations, app consent and OAuth2 permission grants | the audit's `category` (e.g. `UserManagement`, `ApplicationManagement`) | -For example, `streams: risk_detections,sign_ins,audit_logs` collects everything; leaving the option empty collects risk detections only, matching the historical behavior of existing deployments. +For example, `streams: risk_detections,sign_ins,audit_logs` collects all three streams. If you leave the option empty, the adapter collects risk detections only. This is the historical behavior of existing deployments. For the full list of risk detection types, see [Microsoft's documentation](https://learn.microsoft.com/en-us/entra/id-protection/concept-identity-protection-risks). **Requirements per stream:** -- `risk_detections` requires the `IdentityRiskEvent.Read.All` application permission. Note the tenant only produces risk detections with Entra ID Identity Protection (P2 for the full detection set). -- `sign_ins` requires the `AuditLog.Read.All` and `Directory.Read.All` application permissions, and the tenant must hold an Entra ID P1 (or P2) license — a Microsoft Graph requirement, the same one that applies to streaming SignInLogs to an Event Hub. -- `audit_logs` requires the `AuditLog.Read.All` application permission. +- `risk_detections` needs the `IdentityRiskEvent.Read.All` application permission. The tenant produces risk detections only with Entra ID Identity Protection (P2 for the full detection set). +- `sign_ins` needs the `AuditLog.Read.All` and `Directory.Read.All` application permissions. The tenant must also hold an Entra ID P1 (or P2) license. This is a Microsoft Graph requirement, the same one that applies when you stream SignInLogs to an Event Hub. +- `audit_logs` needs the `AuditLog.Read.All` application permission. ### Azure Event Hub -When using Event Hub, you receive whatever data you configure Azure to stream. You must configure **Azure Diagnostic Settings** in Entra ID to send logs to your Event Hub. Common log types include: +When you use Event Hub, you receive the data that you configure Azure to stream. You must configure **Azure Diagnostic Settings** in Entra ID to send logs to your Event Hub. Common log types include: - **Sign-in logs** - Interactive and non-interactive authentication events - **Audit logs** - Directory changes (user/group management, app registrations, app consent and OAuth2 permission grants) - **Provisioning logs** - User provisioning to SaaS apps - **Risky users/sign-ins** - Identity Protection detections (alternative to API) -In the `azure_ad` stream the LimaCharlie event type is the log *category* (e.g. `AuditLogs`, `SignInLogs`), so detection rules targeting a specific operation match on the `event/operationName` field. +In the `azure_ad` stream, the LimaCharlie event type is the log *category* (e.g. `AuditLogs`, `SignInLogs`). Therefore, a detection rule that targets a specific operation matches on the `event/operationName` field. See [Microsoft's documentation on streaming Entra ID logs](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/howto-stream-logs-to-event-hub). ## Adapter Deployment -Microsoft Entra ID logs are ingested into LimaCharlie via: +LimaCharlie ingests Microsoft Entra ID logs with these methods: 1. Azure Event Hub 2. Entra ID API @@ -66,9 +66,9 @@ Microsoft Entra ID logs are ingested into LimaCharlie via: ### Azure Event Hub -Within the LimaCharlie web app, there is a helper that can be used to easily configure receiving Entra ID events via an Azure Event Hub. +The LimaCharlie web app has a helper. Use it to configure how LimaCharlie receives Entra ID events through an Azure Event Hub. -If utilizing the helper, only two fields are required: +If you use the helper, only two fields are required: - Name for the adapter - Connection string to the Azure Event Hub @@ -79,43 +79,43 @@ Microsoft has [documentation for creating an Event Hub](https://learn.microsoft. ### Entra ID API -To collect data via the Entra ID API, you'll need to configure an App Registration in Azure and ensure it has the correct permissions. +To collect data through the Entra ID API, configure an App Registration in Azure. Make sure that it has the correct permissions. -1. In Azure, navigate to the Entra ID Overview page. Select **App Registrations** and click `+ New Registration`. +1. In Azure, go to the Entra ID Overview page. Select **App Registrations** and click `+ New Registration`. 2. Name the application, and select the **Supported account types**. -3. After registering an App, you'll be provided metadata for that application. Take note of the `Application (client) ID` and `Directory (tenant) ID` fields, as you will need them for configuration. -4. Select **Add a certificate or secret,** and create a new client secret. Provide a description and select an applicable Expiration time. *Note: You will need to refresh the Secret in LimaCharlie once it expires!* -5. After creating the secret, copy the `Secret Value`. You will need this to configure the LimaCharlie Adapter. -6. Navigate to the **Manage** > **API permissions** menu for your newly-created application. Grant the **Application** permissions required by the streams you plan to collect (see [Requirements per stream](#entra-id-api)): +3. After you register an App, Azure shows metadata for that application. Record the `Application (client) ID` and `Directory (tenant) ID` fields. You need them for the configuration. +4. Select **Add a certificate or secret,** and create a new client secret. Give a description and select an applicable Expiration time. *Note: You must refresh the Secret in LimaCharlie after it expires!* +5. After you create the secret, copy the `Secret Value`. You need it to configure the LimaCharlie Adapter. +6. Go to the **Manage** > **API permissions** menu for your new application. Grant the **Application** permissions that the streams you plan to collect need (see [Requirements per stream](#entra-id-api)): 1. IdentityRiskEvent.Read.All (`risk_detections`) 2. AuditLog.Read.All (`sign_ins`, `audit_logs`) 3. Directory.Read.All (`sign_ins`) 4. User.Read (default) -7. Click **Grant admin consent** for the tenant — application permissions have no effect until an admin consents. +7. Click **Grant admin consent** for the tenant. Application permissions have no effect until an admin consents. Create a new Adapter within LimaCharlie, and select Microsoft Entra ID. Select `Microsoft Entra ID API` as the ingestion method. -1. Name the Adapter and provide the following details: +1. Name the Adapter and give these details: 1. Tenant ID 2. Client ID 3. Client Secret 4. Streams (optional): comma separated values among `risk_detections`, `sign_ins` and `audit_logs`; empty means `risk_detections` only - 5. *Note: You can use the Secrets Manager for these values if you wish!* + 5. *Note: You can use the Secrets Manager for these values.* -Click **Complete Cloud Installation**, and the Adapter should be created successfully. Monitor the **Platform Logs** for any errors. +Click **Complete Cloud Installation**. LimaCharlie then creates the Adapter. Monitor the **Platform Logs** for errors. -**Note:** Collection starts from the moment the Adapter is created (there is no historical backfill), so a stream only produces events as new ones occur. For `risk_detections` in particular, silence after creation usually just means no risky events have happened yet! +**Note:** Collection starts when you create the Adapter (there is no historical backfill). A stream gives events only when new events occur. For `risk_detections`, no data after creation usually means that no risky events occurred yet. ### Webhooks -Within the LimaCharlie web app, there is a helper that can be used to easily configure receiving Entra ID events. +The LimaCharlie web app has a helper. Use it to configure how LimaCharlie receives Entra ID events. -If utilizing the helper, only two fields are required: +If you use the helper, only two fields are required: - Name for the adapter - Secret component of the URL for the webhook -More information about creating a webhook and obtaining the completed URL, utilizing the secret component, [can be found here](../tutorials/webhook-adapter.md). +For more information about how to create a webhook and get the completed URL with the secret component, see the [webhook adapter tutorial](../tutorials/webhook-adapter.md). diff --git a/docs/2-sensors-deployment/adapters/types/mimecast.md b/docs/2-sensors-deployment/adapters/types/mimecast.md index 082e948fb..d86f4f22e 100644 --- a/docs/2-sensors-deployment/adapters/types/mimecast.md +++ b/docs/2-sensors-deployment/adapters/types/mimecast.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to the Mimecast API to stream audit events as they happen. +This Adapter lets you connect to the Mimecast API and stream audit events when they occur. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name, see below. ### Adapter-specific Options @@ -64,4 +64,4 @@ mimecast: ## API Doc -See the official [documentation](https://developer.services.mimecast.com/docs/auditevents/1/routes/api/audit/get-audit-events/post). +See the official [Mimecast audit events API documentation](https://developer.services.mimecast.com/docs/auditevents/1/routes/api/audit/get-audit-events/post). diff --git a/docs/2-sensors-deployment/adapters/types/okta.md b/docs/2-sensors-deployment/adapters/types/okta.md index 2092a7a25..d37289d7f 100644 --- a/docs/2-sensors-deployment/adapters/types/okta.md +++ b/docs/2-sensors-deployment/adapters/types/okta.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to Okta to fetch system logs. +This Adapter lets you connect to Okta and fetch system logs. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name, see below. ### Adapter-specific Options @@ -62,4 +62,4 @@ okta: ## API Doc -See the official [documentation](https://developer.okta.com/docs/reference/api/system-log/). +See the official [Okta System Log API documentation](https://developer.okta.com/docs/reference/api/system-log/). diff --git a/docs/2-sensors-deployment/adapters/types/pandadoc.md b/docs/2-sensors-deployment/adapters/types/pandadoc.md index 9e338d818..15350aab0 100644 --- a/docs/2-sensors-deployment/adapters/types/pandadoc.md +++ b/docs/2-sensors-deployment/adapters/types/pandadoc.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to PandaDoc to fetch [API logs](https://developers.pandadoc.com/reference/list-api-logs). +This Adapter lets you connect to PandaDoc and fetch [API logs](https://developers.pandadoc.com/reference/list-api-logs). ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, for example `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. Sensor IDs (SID) are generated from this name, see below. ### Adapter-specific Options @@ -61,4 +61,4 @@ pandadoc: ## API Doc -See the official [documentation](https://developers.pandadoc.com/reference/list-api-logs). +See the official [PandaDoc API logs documentation](https://developers.pandadoc.com/reference/list-api-logs). diff --git a/docs/2-sensors-deployment/adapters/types/s3.md b/docs/2-sensors-deployment/adapters/types/s3.md index af9cecd82..6fdb9ba04 100644 --- a/docs/2-sensors-deployment/adapters/types/s3.md +++ b/docs/2-sensors-deployment/adapters/types/s3.md @@ -2,9 +2,9 @@ ## Overview -This Adapter allows you to ingest files/blobs stored in AWS S3. +This Adapter ingests files and blobs that are stored in AWS S3. -Note that this adapter operates as a sink by default, meaning it will "consume" files from the S3 bucket by deleting them once ingested. +By default, this adapter operates as a sink. It consumes the files in the S3 bucket: it deletes each file after it ingests the file. ### AWS S3 Requirements @@ -36,10 +36,10 @@ Adapter Type: `s3` - `client_options`: see [common adapter configuration](../usage.md). - `bucket_name`: the name of the bucket to ingest from. -- `access_key`: an Access Key from S3 used to access the bucket. -- `secret_key`: the secret key associated with the `access_key` used to access the bucket. -- `prefix`: only ingest files with a given path prefix. **Do not include a leading** `/` **in the prefix.** -- `single_load`: if `true`, the adapter will not operate as a sink, it will ingest all files in the bucket once and will then exit. +- `access_key`: an Access Key from S3 that gives access to the bucket. +- `secret_key`: the secret key for the `access_key` that gives access to the bucket. +- `prefix`: ingest only the files with this path prefix. **Do not include a leading** `/` **in the prefix.** +- `single_load`: if `true`, the adapter does not operate as a sink. It ingests all the files in the bucket one time, then it stops. ### Infrastructure as Code Deployment diff --git a/docs/2-sensors-deployment/adapters/types/sentinelone.md b/docs/2-sensors-deployment/adapters/types/sentinelone.md index 300514c7e..f14f7115e 100644 --- a/docs/2-sensors-deployment/adapters/types/sentinelone.md +++ b/docs/2-sensors-deployment/adapters/types/sentinelone.md @@ -1,15 +1,15 @@ # SentinelOne -This Adapter allows you to stream SentinelOne activities, threats, and alerts to LimaCharlie via SentinelOne API. It can optionally be scoped to specific SentinelOne sites/accounts (a single tenant of an MSP console) and pull the agent inventory so every endpoint in scope appears as an individual LimaCharlie sensor. +This Adapter streams SentinelOne activities, threats, and alerts to LimaCharlie through the SentinelOne API. You can scope it to specific SentinelOne sites or accounts, which is a single tenant of an MSP console. It can also pull the agent inventory, so that each endpoint in scope becomes an individual LimaCharlie sensor. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or if you create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify with LimaCharlie. - `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name, see below. ### Adapter-specific Options @@ -18,11 +18,11 @@ Adapter Type: `sentinel_one` - `domain` - your SentinelOne MGMT endpoint, `https://.sentinelone.net` - `api_key` - SentinelOne API token - `start_time` - optional start time to fetch past events. -- `site_ids` - optional comma-separated SentinelOne Site IDs. Every request is scoped to these sites (the standard `siteIds` filter), so an MSP/partner console token pulls in a **single tenant** instead of every site the token can see. Find a Site ID in the SentinelOne console under *Sentinels → Site Info*. +- `site_ids` - optional comma-separated SentinelOne Site IDs. The adapter scopes each request to these sites with the standard `siteIds` filter. A token for an MSP or partner console then pulls in a **single tenant**, not every site that the token can see. Find a Site ID in the SentinelOne console under *Sentinels → Site Info*. - `account_ids` - optional comma-separated SentinelOne Account IDs; like `site_ids` but at the account level. -- `collect_agents` - optional boolean. When `true`, the adapter also polls the agent (endpoint) inventory (`/web/api/v2.1/agents`) and ships one `agents` record per agent, re-shipping a record whenever the agent's details change. The first poll walks the full inventory, so the endpoints in scope appear in LimaCharlie as individual sensors right away — even before they produce any threat/alert/activity telemetry. Decommissioned agents are excluded. Off by default. The API token must be allowed to view Endpoints; like any permission problem on a polled endpoint, a `403` stops the adapter with a visible error rather than silently skipping the feed. -- `agents_poll_interval` - optional, how often the agent inventory is re-polled when `collect_agents` is on, as a Go duration in nanoseconds. Default 15 minutes. -- `urls` - Advanced, CLI only: a comma-separated list of REST API paths to scrub. The `site_ids`/`account_ids` scoping applies to custom paths too, so every path listed here must accept the standard `siteIds`/`accountIds` filters when scoping is configured. If omitted, by default the adapter brings activities, alerts, and threats: +- `collect_agents` - optional boolean. When `true`, the adapter also polls the agent (endpoint) inventory (`/web/api/v2.1/agents`). It ships one `agents` record for each agent, and ships the record again each time the details of the agent change. The first poll reads the full inventory. The endpoints in scope then appear in LimaCharlie as individual sensors immediately, before they produce any threat, alert, or activity telemetry. The adapter excludes decommissioned agents. This option is off by default. The API token must have permission to view Endpoints. As with any permission problem on a polled endpoint, a `403` stops the adapter and shows an error. The adapter does not skip the feed silently. +- `agents_poll_interval` - optional. How often the adapter polls the agent inventory again when `collect_agents` is on, as a Go duration in nanoseconds. Default 15 minutes. +- `urls` - Advanced, CLI only: a comma-separated list of REST API paths to scrub. The scope from `site_ids` and `account_ids` also applies to custom paths. Each path in this list must accept the standard `siteIds` and `accountIds` filters when you configure a scope. If you omit this option, the adapter brings activities, alerts, and threats: ```text /web/api/v2.1/activities, @@ -32,7 +32,7 @@ Adapter Type: `sentinel_one` ### Endpoints as individual sensors -SentinelOne telemetry is multiplexed into one LimaCharlie sensor per SentinelOne agent: threats, alerts, activities and (with `collect_agents`) inventory records that carry the same agent id all collapse onto the same per-endpoint sensor, named after the endpoint's hostname. Combined with `site_ids`, this maps one tenant of a multi-tenant SentinelOne console into a LimaCharlie organization with one sensor per endpoint — the same MSP workflow as the [ThreatLocker adapter](threatlocker.md)'s Managed Organization ID scoping. +LimaCharlie multiplexes SentinelOne telemetry into one sensor for each SentinelOne agent. Threats, alerts, activities, and inventory records (with `collect_agents`) that carry the same agent id go to the same sensor for that endpoint. The sensor takes the name of the endpoint's hostname. With `site_ids`, this maps one tenant of a multi-tenant SentinelOne console into a LimaCharlie organization with one sensor for each endpoint. This is the same MSP workflow as the scope by Managed Organization ID in the [ThreatLocker adapter](threatlocker.md). Agent inventory records arrive with the event type `s1_agent`; threats, alerts and activities arrive as `s1_threat`, `s1_alert` and `s1_activity`. @@ -40,13 +40,16 @@ Agent inventory records arrive with the event type `s1_agent`; threats, alerts a ### Web App -On the Sensors page, Add Sensor, and choose SentinelOne sensor type. Fill out the parameters, and complete the cloud installation. +1. On the Sensors page, select Add Sensor. +2. Choose the SentinelOne sensor type. +3. Fill in the parameters. +4. Complete the cloud installation. ![image.png](../../../assets/images/image(301).png) ### On-prem deployment -Follow docs [Adapter Deployment](../deployment.md), download the binaries for your platform, and run the adapter: +Obey the instructions in [Adapter Deployment](../deployment.md). Download the binaries for your platform, then run the adapter: ```bash ./lc_adapter sentinel_one client_options.identity.installation_key=714e1fa5-aaaa-aaaa-aaaa-aaaaaaaaaaaa client_options.identity.oid=aaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa client_options.platform=sentinel_one client_options.hostname=s1 client_options.sensor_seed_key=s1 'domain=https://datacenter.sentinelone.net' "api_key=$S1_API_KEY" diff --git a/docs/2-sensors-deployment/adapters/types/servicenow.md b/docs/2-sensors-deployment/adapters/types/servicenow.md index 5620ebb0c..d4e0745b3 100644 --- a/docs/2-sensors-deployment/adapters/types/servicenow.md +++ b/docs/2-sensors-deployment/adapters/types/servicenow.md @@ -2,28 +2,28 @@ ## Overview -This Adapter ingests ServiceNow audit and system logs into LimaCharlie by polling the [ServiceNow REST Table API](https://www.servicenow.com/docs/r/zurich/api-reference/rest-apis/c_TableAPI.html). Events are forwarded in their original ServiceNow JSON form — the adapter does not reshape payloads. +This Adapter polls the [ServiceNow REST Table API](https://www.servicenow.com/docs/r/zurich/api-reference/rest-apis/c_TableAPI.html) and ingests ServiceNow audit and system logs into LimaCharlie. The adapter sends the events in their original ServiceNow JSON form. It does not reshape the payloads. -ServiceNow keeps its audit telemetry in plain platform tables, so the adapter is **generic by design**: each *feed* is one table plus an optional [encoded query](https://www.servicenow.com/docs/r/zurich/platform-user-interface/c_EncodedQueryStrings.html) filter — collecting an additional table is a configuration change, not a code change. +ServiceNow keeps its audit telemetry in plain platform tables, so the adapter is **generic by design**. Each *feed* is one table and an optional [encoded query](https://www.servicenow.com/docs/r/zurich/platform-user-interface/c_EncodedQueryStrings.html) filter. To collect one more table is a change of configuration, not a change of code. -By default the adapter collects **`sys_audit`**, ServiceNow's field-level change history: one record per field change on any audited table, carrying who made the change and the old/new values. Other security-relevant tables are easily added as feeds: +By default, the adapter collects **`sys_audit`**, the field-level change history of ServiceNow. This table holds one record for each field change on an audited table. Each record shows the user that made the change and the old and new values. You can add other security-relevant tables as feeds: | Table | What it carries | Caveat | | --- | --- | --- | | `sys_audit` | Field-level change history of audited records (the default feed). | Insert-only; no rotation. | -| `syslog_transaction` | Every transaction against the instance (UI, REST, scheduled jobs) with user, URL and source IP. | **High volume.** Rotates away after ~8 weeks. | +| `syslog_transaction` | Every transaction against the instance (UI, REST, scheduled jobs) with user, URL and source IP. | **High volume.** Rotates after ~8 weeks. | | `sysevent` | The event log/queue, including login activity (`login`, `login.failed`, `external.authentication.succeeded`/`failed`, ...). | Rotates after ~7 days; filter with `query`. | | `syslog` | System log (warnings/errors from instance processes). | Rotates after ~8 weeks. | | `sys_outbound_http_log` | Outbound REST/SOAP requests made by the instance. | | ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or if you create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify with LimaCharlie. - `client_options.platform`: the type of data ingested through this adapter, use `json`. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name. ### Adapter-specific Options @@ -39,8 +39,8 @@ Adapter Type: `servicenow` | `page_size` | no | Records per page (`sysparm_limit`). Default `1000`, maximum `10000`. | | `poll_interval` | no | Wait between polls of a feed, as a Go duration in **nanoseconds** (like every duration below). Default `60000000000` (1 minute). | | `backfill` | no | How far back the first poll reaches. Default 15 minutes. | -| `checkpoint_lag` | no | How long the incremental checkpoint trails the clock, bounding how late a record may become visible in the Table API (slow transactions, node clock differences) without being missed. Default 5 minutes. | -| `dedupe_ttl` | no | How long a record id is remembered to suppress re-shipping. Default 7 days. | +| `checkpoint_lag` | no | How long the incremental checkpoint stays behind the clock. This sets how late a record can become visible in the Table API (slow transactions, differences between node clocks) and still be collected. Default 5 minutes. | +| `dedupe_ttl` | no | How long the adapter remembers a record id, to stop it from shipping the record again. Default 7 days. | | `retry_base_delay` / `max_retry_delay` / `max_retry_attempts` | no | Transient-failure retry tuning. | ### Feed fields @@ -55,37 +55,37 @@ Each entry in `feeds` describes one ServiceNow table to poll. | `fields` | no | Comma-separated `sysparm_fields` restriction. Must include the feed's timestamp and id fields. | | `timestamp_field` | no | Event-time column used for the incremental checkpoint and the shipped event time. Default `sys_created_on`. | | `id_field` | no | Stable identifier used for deduplication. Default `sys_id`. | -| `max_pages` | no | Caps pages fetched per poll. Default `100`. The cap loses nothing: the next poll resumes from the advanced checkpoint. | +| `max_pages` | no | Sets the maximum number of pages for each poll. Default `100`. The cap loses no data: the next poll continues from the checkpoint. | ## Authentication The adapter authenticates with **HTTP Basic auth**. Create a dedicated service account on the instance for it. -The account must satisfy the polled tables' ACLs. Out of the box, `sys_audit` is readable by the `admin` and `security_admin` roles ([Exploring Auditing](https://www.servicenow.com/docs/r/zurich/platform-security/exploring-auditing.html)); many deployments instead create a custom read-only role/ACL for the integration account — work with your ServiceNow administrator. +The account must obey the ACLs of the polled tables. By default, the `admin` and `security_admin` roles can read `sys_audit` ([Exploring Auditing](https://www.servicenow.com/docs/r/zurich/platform-security/exploring-auditing.html)). Many deployments instead create a custom read-only role and ACL for the integration account. Work with your ServiceNow administrator. -Rejected credentials (HTTP 401) stop the adapter so a misconfiguration is surfaced loudly. A per-table ACL denial (HTTP 403) is feed-local: the feed ships nothing and keeps retrying every `poll_interval` (so a live ACL fix is picked up), while other feeds keep collecting. +Rejected credentials (HTTP 401) stop the adapter, so a bad configuration is visible immediately. An ACL denial on one table (HTTP 403) applies only to that feed. The feed ships nothing and retries at each `poll_interval`, so the adapter uses a fix to the ACL as soon as you make it. The other feeds continue to collect. -> ⚠️ ServiceNow applies `sysparm_limit` **before** ACL evaluation, so an account with partial read access silently receives partial pages. The adapter follows the API's `Link: rel="next"` header (not page sizes) and is correct either way, but an account that can read the whole table avoids wasted requests and surprises. +> ⚠️ ServiceNow applies `sysparm_limit` **before** it evaluates the ACLs, so an account with partial read access receives partial pages without a warning. The adapter uses the `Link: rel="next"` header of the API, not the page sizes, and is correct in both cases. But an account that can read the full table prevents unnecessary requests and unexpected results. ## How polling works -Each feed keeps a per-feed **checkpoint** on its timestamp column (`sys_created_on`, a UTC `yyyy-MM-dd HH:mm:ss` value). Every poll queries records at or after the checkpoint, oldest-first with the id column as a tiebreaker (timestamps have one-second granularity, and without a total order a record could slip through a page boundary between page fetches), walking pages until the API stops advertising a next page. +Each feed keeps its own **checkpoint** on its timestamp column (`sys_created_on`, a UTC `yyyy-MM-dd HH:mm:ss` value). Each poll queries the records at or after the checkpoint, oldest first, with the id column as a tiebreaker. Timestamps have a granularity of one second. Without a total order, a record can pass through a page boundary between two page requests. The poll reads pages until the API does not advertise a next page. -- A poll that fails midway does **not** advance the checkpoint — the same range is retried on the next interval. -- A completed poll advances the checkpoint to `now - checkpoint_lag`: the lag leaves room for records that become visible in the API some time after their timestamp. Records inside the lag window are re-read on later polls; an in-memory deduper keyed on `sys_id` keeps them from shipping twice. -- A poll capped by `max_pages` advances the checkpoint only to the newest record processed, so the next poll picks up exactly where it left off (with a loud warning if it cannot advance at all — more than `max_pages × page_size` records in a single second). +- A poll that fails in the middle does **not** advance the checkpoint. The adapter retries the same range at the next interval. +- A completed poll advances the checkpoint to `now - checkpoint_lag`. The lag gives time to records that become visible in the API after their timestamp. Later polls read the records inside the lag window again. A deduper in memory, keyed on `sys_id`, stops the adapter from shipping them two times. +- A poll that reaches the `max_pages` cap advances the checkpoint only to the newest record that it processed. The next poll continues at that point. If the checkpoint cannot advance at all, the adapter writes a clear warning. This occurs with more than `max_pages × page_size` records in one second. -Delivery is **at-least-once**: the checkpoint and dedup state live in memory, so a restart re-reads (and re-ships) up to `backfill` of recent history, and downtime longer than `backfill` leaves a gap — size `backfill` above your expected restart-to-recovery time. +Delivery is **at-least-once**. The checkpoint and the dedup state are in memory. After a restart, the adapter reads and ships up to `backfill` of recent history again. Downtime longer than `backfill` leaves a gap. Set `backfill` to more than your expected time from restart to recovery. -Transient API failures (HTTP 5xx, 429, network errors) are retried with exponential backoff, honoring a 429's `Retry-After` delay. ServiceNow instances have no default REST rate limit, but administrators can configure [rate limit rules](https://www.servicenow.com/docs/r/zurich/api-reference/rest-api-explorer/inbound-REST-API-rate-limiting.html). +The adapter retries transient API failures (HTTP 5xx, 429, network errors) with exponential backoff, and obeys the `Retry-After` delay of a 429 response. ServiceNow instances have no default REST rate limit, but administrators can configure [rate limit rules](https://www.servicenow.com/docs/r/zurich/api-reference/rest-api-explorer/inbound-REST-API-rate-limiting.html). -The rotating tables (`syslog*` ~8 weeks, `sysevent` ~7 days — see [Log history](https://www.servicenow.com/docs/r/zurich/platform-security/r_LogHistory.html)) bound how far `backfill` can usefully reach. +The rotating tables (`syslog*` ~8 weeks, `sysevent` ~7 days — see [Log history](https://www.servicenow.com/docs/r/zurich/platform-security/r_LogHistory.html)) limit how far `backfill` can reach. -For customers licensed for ServiceNow's [Log Export Service](https://www.servicenow.com/docs/r/zurich/platform-security/les-intro.html) (Kafka-based streaming export), that push path can be bridged into LimaCharlie instead; this adapter exists so no Store app, entitlement, MID server or Kafka consumer is required. +If you have a license for the ServiceNow [Log Export Service](https://www.servicenow.com/docs/r/zurich/platform-security/les-intro.html) (streaming export based on Kafka), you can bridge that push path into LimaCharlie instead. This adapter needs no Store app, entitlement, MID server, or Kafka consumer. ## What the data looks like -Each record ships verbatim under an `EventType` matching the feed's `name`. A `sys_audit` record: +The adapter ships each record without change, under an `EventType` that matches the `name` of the feed. This is a `sys_audit` record: ```json { @@ -104,11 +104,11 @@ Each record ships verbatim under an `EventType` matching the feed's `name`. A `s } ``` -The adapter requests database values (`sysparm_display_value=false`, always UTC) and plain sys_ids for reference fields (`sysparm_exclude_reference_link=true`), so payloads are stable regardless of the service account's locale. +The adapter requests database values (`sysparm_display_value=false`, always UTC) and plain sys_ids for reference fields (`sysparm_exclude_reference_link=true`). The payloads are therefore the same for each locale of the service account. ## CLI Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. The defaults are usually sufficient — supplying `instance`, `username` and `password` is enough to pull `sys_audit`. +[Adapter downloads](../deployment.md) are available on the deployment page. The defaults are usually enough: give `instance`, `username`, and `password` to pull `sys_audit`. ```bash chmod +x /path/to/lc_adapter @@ -146,7 +146,7 @@ servicenow: ### Custom feeds -Override `feeds` to add tables or replace the default entirely. The list is **replacing**, not merging — re-declare `sys_audit` if you want to keep it. The example below keeps the default and adds login telemetry and the transaction log: +Override `feeds` to add tables or to replace the default completely. The list **replaces** the default, it does not merge with it. Declare `sys_audit` again if you want to keep it. The example below keeps the default and adds login telemetry and the transaction log: ```yaml servicenow: @@ -170,7 +170,7 @@ servicenow: ## Sample Rule -The adapter ships each record under an `EventType` matching the feed's `name`, so D&R rules can route directly on the feed: +The adapter ships each record under an `EventType` that matches the `name` of the feed. D&R rules can therefore route directly on the feed: ```yaml # Detection — flag changes made to a user's roles in ServiceNow. diff --git a/docs/2-sensors-deployment/adapters/types/slack-audit-logs.md b/docs/2-sensors-deployment/adapters/types/slack-audit-logs.md index 14b46a095..2b8e54307 100644 --- a/docs/2-sensors-deployment/adapters/types/slack-audit-logs.md +++ b/docs/2-sensors-deployment/adapters/types/slack-audit-logs.md @@ -1,22 +1,22 @@ # Slack Audit Logs -[Slack audit logs](https://api.slack.com/admins/audit-logs) allow for ingestion of audit events in a Slack Enterprise Grid organization. Events can be ingested directly from the Slack API via a cloud-to-cloud or CLI Adapter. +[Slack audit logs](https://api.slack.com/admins/audit-logs) supply the audit events of a Slack Enterprise Grid organization. You can ingest these events directly from the Slack API with a cloud-to-cloud Adapter or with a CLI Adapter. -Slack telemetry can be addressed via the `slack` platform. +Use the `slack` platform to address Slack telemetry. -**Note**: Audit Logs via API are only available to Slack workspaces on the Enterprise Grid plan. +**Note**: Audit Logs through the API are available only to Slack workspaces on the Enterprise Grid plan. ## Adapter Deployment -Slack Audit Logs can be collected directly from the Slack API, via a cloud-to-cloud Adapter, or via the CLI Adapter. You will need a Slack App OAuth token prior to deploying this Adapter. More information on generating Slack OAuth tokens can be found [at this link](https://api.slack.com/authentication/token-types). +You can collect Slack Audit Logs directly from the Slack API, with a cloud-to-cloud Adapter or with the CLI Adapter. You need a Slack App OAuth token before you deploy this Adapter. For more information about how to generate Slack OAuth tokens, see [Slack token types](https://api.slack.com/authentication/token-types). ### Cloud-to-Cloud Adapter -Slack API telemetry can be configured directly from the LimaCharlie web application. Under `Sensors List`, select `+ Add Sensor > Slack Audit Logs`. After providing an Installation Key will be prompted to provide an Adapter Name and a Slack App OAuth Token. +Configure Slack API telemetry in the LimaCharlie web application. Under `Sensors List`, select `+ Add Sensor > Slack Audit Logs`. After you give an Installation Key, the web app asks for an Adapter Name and a Slack App OAuth Token. ### Deploying via the CLI Adapter -The LimaCharlie CLI Adapter can also be used to ingest Slack events, if you do not wish to create a cloud-to-cloud connector. The following sample configuration can be used to create a Slack CLI Adapter: +You can also use the LimaCharlie CLI Adapter to ingest Slack events if you do not want to create a cloud-to-cloud Adapter. Use the sample configuration below to create a Slack CLI Adapter: ```yaml slack: diff --git a/docs/2-sensors-deployment/adapters/types/sophos.md b/docs/2-sensors-deployment/adapters/types/sophos.md index 00a485788..6e86fe824 100644 --- a/docs/2-sensors-deployment/adapters/types/sophos.md +++ b/docs/2-sensors-deployment/adapters/types/sophos.md @@ -2,16 +2,16 @@ ## Overview -This Adapter allows you to connect to Sophos Central to fetch event logs. +This Adapter connects to Sophos Central to fetch event logs. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always specify these options if you use the binary adapter or if you create a webhook adapter. If you use an Adapter helper in the web app, you do not need to specify these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify with LimaCharlie. - `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.sensor_seed_key`: an arbitrary name for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name, see below. ### Adapter-specific Options @@ -27,14 +27,14 @@ Adapter Type: `sophos` Sophos documentation - 1. Add a new credential in [Sophos Central Settings → Credentials](https://cloud.sophos.com/manage/config/settings/credentials) -2. Get your client ID and client secret from the credentials you just created -3. Get your JWT -- be sure to replace the values with the client ID and secret from the last step +2. Get your client ID and client secret from the credentials that you created +3. Get your JWT. Replace the values with the client ID and secret from the last step ```bash curl -XPOST -H "Content-Type:application/x-www-form-urlencoded" -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=token" https://id.sophos.com/api/v2/oauth2/token ``` - Response content -- grab the `access_token` from the output: + Response content. Take the `access_token` from the output: ```json { @@ -48,13 +48,13 @@ Sophos documentation - } ``` -4. Get your tenant ID -- you will need the `access_token` (JWT) from the last step. +4. Get your tenant ID. You need the `access_token` (JWT) from the last step. ```bash curl -XGET -H "Authorization: Bearer YOUR_JWT_HERE" https://api.central.sophos.com/whoami/v1 ``` - Response content -- grab the `id` (`tenant_id`) and `dataRegion` (`url`) from the output. You will need these for your LimaCharlie Sophos adapter configuration. + Response content. Take the `id` (`tenant_id`) and the `dataRegion` (`url`) from the output. You need these values for the configuration of your LimaCharlie Sophos adapter. ```json { @@ -67,7 +67,7 @@ Sophos documentation - } ``` -5. Now you have all the pieces for your adapter: +5. You now have all the values for your adapter: 1. `client_id` 2. `client_secret` diff --git a/docs/2-sensors-deployment/adapters/types/sqs.md b/docs/2-sensors-deployment/adapters/types/sqs.md index 53dee58b8..59e00dff6 100644 --- a/docs/2-sensors-deployment/adapters/types/sqs.md +++ b/docs/2-sensors-deployment/adapters/types/sqs.md @@ -2,15 +2,15 @@ ## Overview -This Adapter allows you to ingest events received from an AWS SQS instance. +This Adapter ingests the events that it receives from an AWS SQS instance. ## Configurations Adapter Type: `sqs` - `client_options`: see [common adapter configuration](../usage.md). -- `access_key`: an Access Key from AWS used to access the queue. -- `secret_key`: the secret key associated with the `access_key` used to access the queue. +- `access_key`: an Access Key from AWS that gives access to the queue. +- `secret_key`: the secret key for the `access_key` that gives access to the queue. - `queue_url`: the queue URL for the SQS instance. ### Infrastructure as Code Deployment diff --git a/docs/2-sensors-deployment/adapters/types/stdin.md b/docs/2-sensors-deployment/adapters/types/stdin.md index 14a1540ef..24cfbde1f 100644 --- a/docs/2-sensors-deployment/adapters/types/stdin.md +++ b/docs/2-sensors-deployment/adapters/types/stdin.md @@ -2,7 +2,7 @@ ## Overview -This Adapter allows you to ingest data piped into the adapter's standard input. This is useful for integrating with tools or scripts that output log data to stdout, or for one-off ingestion of data from a command pipeline. +This Adapter ingests the data that you pipe into the standard input of the adapter. Use it with tools or scripts that write log data to stdout, or to ingest data one time from a command pipeline. ## Configurations diff --git a/docs/2-sensors-deployment/adapters/types/sublime-security.md b/docs/2-sensors-deployment/adapters/types/sublime-security.md index b5e5fa604..69e49e6ea 100644 --- a/docs/2-sensors-deployment/adapters/types/sublime-security.md +++ b/docs/2-sensors-deployment/adapters/types/sublime-security.md @@ -1,10 +1,10 @@ # Sublime Security -[Sublime Security](https://sublime.security/) is a comprehensive email security platform that allows users to create custom detections, gain visibility and control, and focus on prevention of malicious emails. +[Sublime Security](https://sublime.security/) is an email security platform. Users can create custom detections, get visibility and control, and stop malicious emails. ## Ingesting Audit Logs -Audit logs from Sublime can be ingested cloud-to-cloud via the API. +You can ingest audit logs from Sublime cloud-to-cloud through the API. ### Adapter-specific Options @@ -57,21 +57,21 @@ See the official [documentation](https://docs.sublime.security/reference/authent ## Ingesting Alerts -Sublime events can be ingested in LimaCharlie via a `json` Webhook Adapter configuration. +LimaCharlie can ingest Sublime events with a `json` Webhook Adapter configuration. ### Adapter Deployment -Sublime Security logs are ingested via a cloud-to-cloud webhook Adapter configured to receive JSON events. The steps of creating this Adapter and enabling the input include: +A cloud-to-cloud webhook Adapter that receives JSON events ingests the Sublime Security logs. To create this Adapter and enable the input, do these steps: -1. Creating the Webhook Adapter via the LimaCharlie CLI -2. Discovering the URL created for the Webhook Adapter. -3. Providing the completed URL to Sublime Security for webhook events. +1. Create the Webhook Adapter with the LimaCharlie CLI. +2. Find the URL that LimaCharlie creates for the Webhook Adapter. +3. Give the completed URL to Sublime Security for webhook events. #### 1. Creating the LimaCharlie Webhook Adapter These steps are adapted from the [generic Webhook Adapter creation guide](../tutorials/webhook-adapter.md). -Creating a Webhook Adapter requires a set of parameters, including organization ID, Installation Key, platform, and mapping details, among other parameters. The following configuration can be modified to easily configure a Webhook Adapter for ingesting Sublime Security events: +A Webhook Adapter needs a set of parameters. These include the organization ID, the Installation Key, the platform, the mapping details, and other parameters. Change the configuration below to configure a Webhook Adapter that ingests Sublime Security events: ```json { @@ -95,35 +95,35 @@ Creating a Webhook Adapter requires a set of parameters, including organization } ``` -Note that in the mapping above, we make the following changes: +The mapping above makes these changes: - `event_type_path` is mapped to the rule name from the Sublime alert - `event_time_path` is mapped to the `created_at` field from the Sublime alert #### 2. Building the Adapter URL -After creating the webhook, you'll need to retrieve the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. You'll need the following information to complete the Webhook URL: +After you create the webhook, get the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/get-org-urls) API call. You need this information to complete the Webhook URL: - Organization ID - Webhook name (from the config) - Secret (from the config) -Let's assume the returned domain looks like `9157798c50af372c.hook.limacharlie.io`, the format of the URL would be: +If the returned domain is `9157798c50af372c.hook.limacharlie.io`, the format of the URL is: `https://9157798c50af372c.hook.limacharlie.io/OID/HOOKNAME/SECRET` -Note that the `secret` value can be provided in the webhook URL or as an HTTP header named `lc-secret`. +You can give the `secret` value in the webhook URL or in an HTTP header named `lc-secret`. #### 3. Configuring the Sublime webhook Action -Within the Sublime Security console, navigate to **Manage** > **Actions**. From here, you can select **New Action** > **Webhook**. +In the Sublime Security console, go to **Manage** > **Actions**. Then select **New Action** > **Webhook**. ![image.png](../../../assets/images/image(174).png) -Within the **Configure webhook** menu, provide a name and the Adapter URL constructed in Step 2 above. +In the **Configure webhook** menu, give a name and the Adapter URL that you built in Step 2. ![image.png](../../../assets/images/image(175).png) -As mentioned in Step 2, you can configure the HTTP header `lc-secret`, if so desired. +As Step 2 explains, you can configure the HTTP header `lc-secret`. -Upon configuration of the webhook within Sublime Security, alerts can be configured to be sent to the LimaCharlie platform. To test the Webhook, select **Trigger Custom Action** from any Flagged message, and send to the LimaCharlie webhook. +After you configure the webhook in Sublime Security, you can configure alerts to go to LimaCharlie. To test the Webhook, select **Trigger Custom Action** on a Flagged message and send it to the LimaCharlie webhook. diff --git a/docs/2-sensors-deployment/adapters/types/syslog.md b/docs/2-sensors-deployment/adapters/types/syslog.md index c74b67d74..38d6cc20e 100644 --- a/docs/2-sensors-deployment/adapters/types/syslog.md +++ b/docs/2-sensors-deployment/adapters/types/syslog.md @@ -1,20 +1,20 @@ # Syslog -Syslog is both a protocol and common logging format that consolidate events to a central location for storage. On \*nix systems, Syslog often outputs to predefined locations, such as `/var/log`. The LimaCharlie Adapter can be configured as a Syslog endpoint to collect events either via TCP or UDP. +Syslog is a protocol and a common log format. It sends events to a central location for storage. On \*nix systems, Syslog usually writes to set locations, such as `/var/log`. You can configure the LimaCharlie Adapter as a Syslog endpoint that collects events over TCP or UDP. -Syslog data can also be ingested via other data platforms, such as an S3 bucket. +LimaCharlie can also ingest Syslog data through other data platforms, such as an S3 bucket. -Syslog events are observed in LimaCharlie as the `text` platform. +Syslog events appear in LimaCharlie as the `text` platform. -A more detailed guide to syslog collection can be found in the [Log Collection Guide](../../log-collection-guide.md). +The [Log Collection Guide](../../log-collection-guide.md) gives more detail about syslog collection. ## Adapter Deployment -Given its ubiquity, Syslog can be ingested via a myriad of methods in both text/log and streaming formats. For non-streaming methods, please refer to the corresponding Adapter type (such as [S3](s3.md), [GCP](google-cloud-pubsub.md), etc.) +Syslog is common, and many methods can ingest it in text/log formats and in streaming formats. For non-streaming methods, use the applicable Adapter type, such as [S3](s3.md) or [GCP](google-cloud-pubsub.md). ### Syslog-specific Configurations -All Adapters share the [common client configuration options](../usage.md). A syslog Adapter has a few unique configuration options not found with other Adapter types. These include: +All Adapters share the [common client configuration options](../usage.md). A syslog Adapter also has these unique configuration options: - `port`: port to listen for syslog from. - `iface`: the interface name to listen for new connections/packets from, defaults to all. @@ -26,7 +26,7 @@ All Adapters share the [common client configuration options](../usage.md). A sys ### Collecting Syslog via Docker -The following example walks through configuring a Docker container as a syslog Adapter. +The example below shows how to configure a Docker container as a syslog Adapter. ```bash docker run --rm -it -p 1514:1514 refractionpoint/lc-adapter:latest syslog port=1514 \ @@ -39,24 +39,24 @@ docker run --rm -it -p 1514:1514 refractionpoint/lc-adapter:latest syslog port=1 "client_options.mapping.mapping[0].dst_field=syslog_hostname" ``` -Here's a breakdown of the above example: +The example uses these options: -- `docker run --rm`: run a container and don't keep the contents around when it's stopped. -- `-it`: make the container interactive so you can ctrl-c to stop it. -- `-p 1514:1514`: allow the container to listen on port `1514` on the local host and use the same port within the container. -- `refractionpoint/lc-adapter:latest`: this is the name of the public container provided by LimaCharlie. -- `syslog`: the method the Adapter should use to collect data locally. The `syslog` value will operate as a syslog endpoint on the TCP port specified. -- `port=1514`: the TCP port the Adapter should listen on. By default this is a normal TCP connection (not SSL), although SSL options exist. +- `docker run --rm`: run a container and delete its contents when the container stops. +- `-it`: make the container interactive, so that you can stop it with ctrl-c. +- `-p 1514:1514`: let the container listen on port `1514` on the local host and use the same port in the container. +- `refractionpoint/lc-adapter:latest`: the name of the public container from LimaCharlie. +- `syslog`: the method that the Adapter uses to collect data locally. The `syslog` value operates as a syslog endpoint on the TCP port that you specify. +- `port=1514`: the TCP port that the Adapter listens on. The default is a normal TCP connection (not SSL), but SSL options exist. - `client_options.identity.installation_key=....`: the Installation Key from LimaCharlie. -- `client_options.identity.`OID`=....`: the Organization ID from LimaCharlie the installation key above belongs to. -- `client_options.platform=text`: this indicates the type of data that will be received from this adapter. In this case it's syslog, so `text` lines. -- `client_options.mapping.parsing_grok=....`: this is the grok expression describing how to interpret the text lines and how to convert them to JSON. -- `client_options.sensor_seed_key=....`: this is the value that identifies this instance of the Adapter. Record it to re-use the Sensor generated for this Adapter later if you have to re-install the Adapter. -- `client_options.mapping.rename_only=true`: only rename the field in mapping below, so keep the other original fields. +- `client_options.identity.`OID`=....`: the Organization ID from LimaCharlie that the installation key above belongs to. +- `client_options.platform=text`: the type of data that this adapter receives. For syslog, this is `text` lines. +- `client_options.mapping.parsing_grok=....`: the grok expression that shows how to interpret the text lines and how to convert them to JSON. +- `client_options.sensor_seed_key=....`: the value that identifies this instance of the Adapter. Record this value. It lets you re-use the Sensor of this Adapter if you must re-install the Adapter. +- `client_options.mapping.rename_only=true`: rename only the field in the mapping below, and keep the other original fields. - `client_options.mapping.mapping[0].src_field=....`: the source field of the first mapping record. - `client_options.mapping.mapping[0].dst_field=....`: the destination field of the first mapping record. -To test it, assuming we're on the same Debian box as the container, pipe the syslog to the container: +To test the Adapter from the same Debian machine as the container, pipe the syslog to the container: ```text journalctl -f -q | netcat 127.0.0.1 1514 @@ -64,17 +64,17 @@ journalctl -f -q | netcat 127.0.0.1 1514 ### Collecting Syslog via Binary Adapter -The LimaCharlie binary Adapter can be deployed as a syslog listener. This option allows you to configure multiple syslog outputs to a single listener, and ingest multiple types of events with a single Adapter. +You can deploy the LimaCharlie binary Adapter as a syslog listener. With this option, you can send many syslog outputs to one listener and ingest many types of events with one Adapter. #### Step 1: Create an installation key -We recommend utilizing a unique installation key for this deployment, specifically with a `syslog` Tag. This allows for a level of delineation within rules and outputs via Tags. +Use a unique installation key for this deployment, with a `syslog` Tag. Tags let you separate this data in rules and outputs. #### Step 2: Create an Adapter config file -Syslog events are typically ingested as `text`, however often have specific structures to them. Utilizing a config file allows for easy management of a regex string to extract relevant fields from syslog output. +LimaCharlie usually ingests syslog events as `text`, but the events often have a specific structure. A config file lets you manage the regex string that extracts the necessary fields from the syslog output. -The following example config file can be a starting point. However, you might need to modify the regex to match your specific message. +Use the example config file below as a start. You can change the regex to match your messages. ```yaml syslog: @@ -104,18 +104,18 @@ syslog: #### Step 3: Configure syslog output to send messages to a local listener -This step will depend on the type of syslog daemon you are using (syslog, rsyslog, syslog-ng, etc.) Within the daemon configuration file, configure the desired facility(-ies) to direct to the local listener. In the following example, we configured `auth` and `authpriv` events to write to both `/var/log/audit.log` and `127.0.0.1:1514`. +This step depends on the syslog daemon that you use (syslog, rsyslog, syslog-ng, and others). In the daemon configuration file, send the necessary facilities to the local listener. The example below writes `auth` and `authpriv` events to `/var/log/audit.log` and to `127.0.0.1:1514`. ```text auth,authpriv.* /var/log/auth.log auth,authpriv.* @@127.0.0.1:1514 ``` -After applying the appropriate configuration, restart the syslog daemon. +After you apply the configuration, restart the syslog daemon. #### Step 4: Confirm that syslog messages are sent to the correct location -Utilizing a tool like `netcat`, you can listen on the appropriate port to confirm that messages are being sent. The following command will spawn a `netcat` listener on port 1514: +Use a tool such as `netcat` to listen on the port and confirm that the daemon sends messages. The command below starts a `netcat` listener on port 1514: ```text nc -l -p 1514 @@ -123,7 +123,7 @@ nc -l -p 1514 #### Step 5: Run the LimaCharlie Adapter -Execute the binary Adapter with the syslog configuration file in order to start the LimaCharlie listener. If started correctly, you should see the following messages in `stdout`: +Run the binary Adapter with the syslog configuration file to start the LimaCharlie listener. If the Adapter starts correctly, `stdout` shows these messages: ```text DBG : usp-client connecting @@ -131,4 +131,4 @@ DBG : usp-client connected DBG : listening for connections on :1514 ``` -Double-check the LimaCharlie Sensors list, and you should see the text adapter with the respective hostname sending `Syslog` events. +Open the LimaCharlie Sensors list. The text adapter with the applicable hostname sends `Syslog` events. diff --git a/docs/2-sensors-deployment/adapters/types/tailscale.md b/docs/2-sensors-deployment/adapters/types/tailscale.md index cdd254b00..4d23b92f0 100644 --- a/docs/2-sensors-deployment/adapters/types/tailscale.md +++ b/docs/2-sensors-deployment/adapters/types/tailscale.md @@ -1,22 +1,22 @@ # Tailscale -[Tailscale](https://tailscale.com/) is a VPN service that makes devices and applications accessible anywhere in the world. Relying on the open source WireGuard protocol, Tailscale enables encrypted point-to-point connections. +[Tailscale](https://tailscale.com/) is a VPN service that makes devices and applications accessible from anywhere in the world. Tailscale uses the open source WireGuard protocol to make encrypted point-to-point connections. -Tailscale events can be ingested in LimaCharlie via a `json` Webhook Adapter. +LimaCharlie can ingest Tailscale events with a `json` Webhook Adapter. ## Adapter Deployment -Tailscale events are ingested via a cloud-to-cloud webhook Adapter configured to receive JSON events. In the creation of the Adapter, we map fields directly to the expected Tailscale webhook events. The steps of creating this Adapter and enabling the input include: +A cloud-to-cloud webhook Adapter receives Tailscale events as JSON. When you create the Adapter, you map the fields directly to the Tailscale webhook events. To create this Adapter and enable the input, do these steps: -1. Creating the Webhook Adapter via the LimaCharlie CLI. -2. Discovering the URL created for the Webhook Adapter. -3. Providing the completed URL to Tailscale for Webhook events. +1. Create the Webhook Adapter with the LimaCharlie CLI. +2. Find the URL that LimaCharlie creates for the Webhook Adapter. +3. Give the completed URL to Tailscale for Webhook events. ### 1. Creating the LimaCharlie Webhook Adapter These steps are adapted from the [generic Webhook Adapter creation guide](../tutorials/webhook-adapter.md). -Creating a Webhook Adapter requires a set of parameters, including organization ID, Installation Key, platform, and mapping details. The following configuration has been provided to configure a Webhook Adapter for ingesting Tailscale events: +A Webhook Adapter needs parameters that include the organization ID, the Installation Key, the platform, and the mapping details. The configuration below sets up a Webhook Adapter that ingests Tailscale events: ```json { @@ -39,38 +39,38 @@ Creating a Webhook Adapter requires a set of parameters, including organization } ``` -The mapping above is based on the expected Webhook event from Tailscale ([example provided here](https://tailscale.com/kb/1213/webhooks/)). Note that in the mapping above, we make the following change: +The mapping above is based on the Webhook event from Tailscale (see the [Tailscale webhook example](https://tailscale.com/kb/1213/webhooks/)). The mapping makes this change: - `event_type_path` is mapped to the `message` field ### 2. Building the Webhook URL -After creating the webhook, you'll need to retrieve the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/#/Org/get_orgs__oid___urls) API call. You'll need the following information to complete the Webhook URL: +After you create the webhook, get the webhook URL from the [Get Org URLs](https://api.limacharlie.io/static/swagger/#/Org/get_orgs__oid___urls) API call. To complete the Webhook URL, you need this information: - Organization ID - Webhook name (from the config) - Secret (from the config) -Let's assume the returned domain looks like `9157798c50af372c.hook.limacharlie.io`, the format of the URL would be: +If the returned domain is `9157798c50af372c.hook.limacharlie.io`, the URL has this format: `https://9157798c50af372c.hook.limacharlie.io/OID/HOOKNAME/SECRET` -Note that the `secret` value can be provided in the webhook URL or as an HTTP header named `lc-secret`. +You can give the `secret` value in the webhook URL or in an HTTP header named `lc-secret`. ### 3. Providing the URL to Tailscale for Webhook Events -Within the Tailscale Admin Console, navigate to **Settings** > **Webhooks**. Select **Add endpoint...** +In the Tailscale Admin Console, go to **Settings** > **Webhooks**. Select **Add endpoint...** ![image.png](../../../assets/images/image(168).png) -Provide the completed Webhook URL from Step 2, above. You can also select the various events you want sent via Webhook. Options include: +Give the completed Webhook URL from Step 2 above. You can also select the events that the Webhook sends. These options are available: ![image.png](../../../assets/images/image(170).png) -Select **Add endpoint**. Tailscale will provide you a webhook secret unique to this endpoint. You may want to keep this value, however it is not required within LimaCharlie. +Select **Add endpoint**. Tailscale gives you a webhook secret that is unique to this endpoint. You can keep this value, but LimaCharlie does not need it. #### 4. Test Webhook Output -Within the Tailscale Admin Console, you can test the webhook out and ensure that LimaCharlie is receiving events. Within the Webhook Endpoint options, select **Test endpoint...**. +In the Tailscale Admin Console, you can test the webhook and make sure that LimaCharlie receives events. In the Webhook Endpoint options, select **Test endpoint...**. -You should see the webhook event populate within the LimaCharlie Adapter a moment later. Note that the `event_type` will match the `message` field from the Tailscale webhook event. +The webhook event appears in the LimaCharlie Adapter a moment later. The `event_type` matches the `message` field from the Tailscale webhook event. diff --git a/docs/2-sensors-deployment/adapters/types/threatlocker.md b/docs/2-sensors-deployment/adapters/types/threatlocker.md index 8f5b5cfe8..aca5ddb3b 100644 --- a/docs/2-sensors-deployment/adapters/types/threatlocker.md +++ b/docs/2-sensors-deployment/adapters/types/threatlocker.md @@ -2,20 +2,20 @@ ## Overview -This Adapter ingests events from the [ThreatLocker](https://threatlocker.com) Portal API into LimaCharlie. Events are forwarded in their original ThreatLocker JSON form — the adapter does not reshape payloads. +This Adapter ingests events from the [ThreatLocker](https://threatlocker.com) Portal API into LimaCharlie. The adapter sends the events in their original ThreatLocker JSON form. It does not change the payloads. -The adapter is **generic by design**. The ThreatLocker Portal API is uniform: every queryable resource exposes a `GetByParameters` endpoint that takes a `POST` with a JSON filter body. The adapter models each such endpoint as a *feed* — adding a new event type is a configuration change, not a code change. +The adapter is **generic by design**. The ThreatLocker Portal API is uniform: each resource that you can query has a `GetByParameters` endpoint that takes a `POST` with a JSON filter body. The adapter models each such endpoint as a *feed*. To add a new event type, you change the configuration, not the code. -It pairs naturally with the [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md): the adapter delivers Application Control approval-request events into LimaCharlie, and the extension provides the actions an AI agent (or a Playbook) calls to enrich those events and write the decision back. +The adapter works with the [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md). The adapter delivers Application Control approval-request events into LimaCharlie. The extension supplies the actions that an AI agent, or a Playbook, calls to enrich those events and to write the decision back. ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always set these options when you use the binary adapter or when you create a webhook adapter. If you use an Adapter helper in the web app, you do not set these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name, as described below. ### Adapter-specific Options @@ -28,10 +28,10 @@ Adapter Type: `threatlocker` | `base_url` | no | Full API root override, e.g. `https://portalapi.g.threatlocker.com/portalapi`. Use to point the adapter at a non-standard endpoint; otherwise prefer `instance`. | | `managed_organization_id` | no | UUID of the managed (child) organization. Sent as the `managedOrganizationId` header — used by MSP **parent** tokens to scope every request to a specific child tenant. | | `feeds` | no | List of feeds to poll (see [Feed fields](#feed-fields) below). When omitted the adapter polls the three default feeds described under [Default feeds](#default-feeds). | -| `page_size` | no | Records per page. Default `100`, maximum `1000`. | +| `page_size` | no | Records for each page. Default `100`, maximum `1000`. | | `poll_interval` | no | Wait between polls of a feed, as a Go duration in **nanoseconds**. Default `60000000000` (1 minute). | -| `dedupe_ttl` | no | How long a record id is remembered to suppress re-shipping. Default 7 days. | -| `retry_base_delay` / `max_retry_delay` / `max_retry_attempts` | no | Transient-failure retry tuning. | +| `dedupe_ttl` | no | The time that the adapter keeps a record id, to stop the adapter from sending the record again. Default 7 days. | +| `retry_base_delay` / `max_retry_delay` / `max_retry_attempts` | no | Retry settings for transient failures. | ### Feed fields @@ -43,48 +43,52 @@ Each entry in `feeds` describes one ThreatLocker `*GetByParameters` endpoint to | `url` | yes | API path of the `*GetByParameters` endpoint, **relative to the API root** (e.g. `ApprovalRequest/ApprovalRequestGetByParameters`). | | `parameters` | no | JSON object merged into the request body — resource-specific filters such as `statusId`, `showChildOrganizations`, ThreatLocker query DTOs. | | `order_by` | no | Sort field. Default `dateTime`. The default request is newest-first (`isAscending = false`). | -| `items_path` | no | Key holding the records array when the response is an object envelope. Auto-detected (`data`, `pageItems`, …) when empty. | -| `timestamp_field` | no | Path to the record's event time, supports `/`-separated nested paths. Default `dateTime`. | -| `id_field` | no | Path to the record's stable identifier, used for deduplication. Falls back to common id fields, then a content hash. | -| `max_pages` | no | Caps pages fetched per poll. Default `100`. | -| `window` | no | When set (e.g. `5m`), rewrites `startDate` / `endDate` in the request body on every poll to a rolling `[now-window-poll_interval, now]` range. **Required** for endpoints that mandate a date range (`ActionLog`, `SystemAudit`). The overlap with the previous poll is absorbed by the deduper. | +| `items_path` | no | Key that holds the records array when the response is an object envelope. Auto-detected (`data`, `pageItems`, …) when empty. | +| `timestamp_field` | no | Path to the record's event time. Supports `/`-separated nested paths. Default `dateTime`. | +| `id_field` | no | Path to the record's stable identifier, used for deduplication. Falls back to common id fields, then to a content hash. | +| `max_pages` | no | Limits the pages that each poll fetches. Default `100`. | +| `window` | no | When set (for example, `5m`), rewrites `startDate` / `endDate` in the request body on every poll to a rolling `[now-window-poll_interval, now]` range. **Required** for endpoints that need a date range (`ActionLog`, `SystemAudit`). The deduper removes the overlap with the previous poll. | | `start_date_field` / `end_date_field` | no | Override the request-body field names used by `window`. Defaults: `startDate` / `endDate`. | ### Default feeds -With no `feeds` configured, the adapter polls three feeds that together cover ThreatLocker's primary telemetry surfaces: +If you do not configure `feeds`, the adapter polls three feeds. Together, these feeds cover the primary telemetry of ThreatLocker: | Default feed | ThreatLocker endpoint | What it carries | | --- | --- | --- | -| `approval_request` | `ApprovalRequest/ApprovalRequestGetByParameters` (`statusId = 1`) | Pending Application Control whitelist requests — one event per new request, shipped exactly once. The intended input to AI-driven triage via the [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md). | -| `unified_audit` | `ActionLog/ActionLogGetByParametersV2` | The **Unified Audit** — ThreatLocker's combined event stream of `execute` / `install` / `network` / `registry` / `read` / `write` / `move` / `delete` / `baseline` / `powershell` / `elevate` / web activity across every module. Polled on a 5-minute rolling window. | -| `system_audit` | `SystemAudit/SystemAuditGetByParameters` | Portal / administrator activity — logins, policy edits, approval decisions, organization changes. Polled on a 5-minute rolling window. | +| `approval_request` | `ApprovalRequest/ApprovalRequestGetByParameters` (`statusId = 1`) | Pending Application Control whitelist requests. The adapter sends one event for each new request, exactly once. This is the input to AI-driven triage with the [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md). | +| `unified_audit` | `ActionLog/ActionLogGetByParametersV2` | The **Unified Audit** — the combined event stream of ThreatLocker for `execute` / `install` / `network` / `registry` / `read` / `write` / `move` / `delete` / `baseline` / `powershell` / `elevate` / web activity across every module. The adapter polls it on a 5-minute rolling window. | +| `system_audit` | `SystemAudit/SystemAuditGetByParameters` | Portal and administrator activity — logins, policy edits, approval decisions, organization changes. The adapter polls it on a 5-minute rolling window. | -`unified_audit` and `system_audit` both *require* a `startDate`/`endDate` filter on every request; the adapter sets those automatically via the feed's `window`. The overlap between consecutive windows is absorbed by the per-feed deduper, preserving at-least-once delivery semantics. +`unified_audit` and `system_audit` both *need* a `startDate`/`endDate` filter on every request. The adapter sets these fields automatically with the feed's `window`. The deduper for each feed removes the overlap between two windows, and delivery stays at-least-once. ## Authentication -Create an API token under **Portal → Administration → API Users** in the ThreatLocker Portal. The token is sent verbatim in the `Authorization` header — there is no `Bearer` prefix and no OAuth handshake. +Create an API token under **Portal → Administration → API Users** in the ThreatLocker Portal. The adapter sends the token verbatim in the `Authorization` header. There is no `Bearer` prefix and no OAuth handshake. ### Finding your instance -ThreatLocker hosts each tenant on one of several lettered instances (`b`, `c`, `d`, …, `g`, `h`, …) and API tokens are scoped to the instance that minted them. To find yours, open the ThreatLocker Portal, click the **Help** button in the top-right corner of any page, and read the letter in parentheses next to **ThreatLocker Access** (e.g. `ThreatLocker Access (C)` → `instance: c`). +ThreatLocker hosts each tenant on one of several lettered instances (`b`, `c`, `d`, …, `g`, `h`, …). An API token is scoped to the instance that made it. To find your instance: -> ⚠️ **A token from one instance returns `403 TOKEN_REVOKED` on every other instance** — the API does not distinguish "wrong instance" from a genuinely revoked token. If you are confident the token is active and still see `TOKEN_REVOKED`, double-check the instance letter before assuming the token was revoked. An authentication failure stops the adapter so the misconfiguration is surfaced loudly. +1. Open the ThreatLocker Portal. +2. Click the **Help** button in the top-right corner of any page. +3. Read the letter in parentheses next to **ThreatLocker Access**. For example, `ThreatLocker Access (C)` gives `instance: c`. + +> ⚠️ **A token from one instance returns `403 TOKEN_REVOKED` on every other instance.** The API does not show the difference between a wrong instance and a token that is revoked. If the token is active but you still see `TOKEN_REVOKED`, check the instance letter first. An authentication failure stops the adapter, which makes the incorrect configuration visible. ## How polling works -On every poll the adapter walks a feed's pages (`pageNumber` / `pageSize`) until the result set is exhausted (a short or empty page) or the feed's `max_pages` cap is reached. An in-memory deduper, keyed per feed, guarantees each record is shipped to LimaCharlie exactly once even though pages are re-fetched on every poll. +On every poll, the adapter reads the pages of a feed (`pageNumber` / `pageSize`). It stops at the end of the result set (a short page or an empty page), or at the feed's `max_pages` limit. An in-memory deduper, keyed for each feed, sends each record to LimaCharlie exactly once, although the adapter fetches the pages again on every poll. -Transient API failures (HTTP 5xx, 429, network errors) are retried with exponential backoff. An authentication failure (401/403) stops the adapter rather than burning the token via repeated retries. +The adapter retries transient API failures (HTTP 5xx, 429, network errors) with exponential backoff. An authentication failure (401/403) stops the adapter, so that repeated retries do not burn the token. -The adapter deliberately re-walks every page rather than stopping at the first page of already-seen records: the Portal API paginates by offset over a live, mutable list, so a record can shift across a page boundary between two page fetches. Re-walking costs more requests but is correct. +The adapter reads all the pages again. It does not stop at the first page of records that it saw before. The Portal API paginates by offset over a live list that can change, so a record can move across a page boundary between two page fetches. To read all the pages again costs more requests, but it is correct. -For a large or high-churn feed, bound each poll's work with the feed's `parameters` (e.g. a date-range filter) and a `max_pages` that comfortably exceeds the feed's expected size. Querying newest-first (`isAscending = false`, the default) keeps the most recent records when `max_pages` truncates. +For a large feed, or a feed that changes quickly, limit the work of each poll. Use the feed's `parameters` (for example, a date-range filter) and a `max_pages` value that is larger than the expected size of the feed. A newest-first query (`isAscending = false`, the default) keeps the most recent records when `max_pages` truncates the result. ## CLI Deployment -[Adapter downloads](../deployment.md) are available on the deployment page. The defaults are usually sufficient — supplying `api_key` and `instance` is enough to pull the three default feeds. +You can get the [Adapter downloads](../deployment.md) on the deployment page. The defaults are usually enough. Supply `api_key` and `instance` to pull the three default feeds. ```bash chmod +x /path/to/lc_adapter @@ -126,9 +130,9 @@ threatlocker: ### Custom feeds -Override `feeds` to add new feeds or replace the defaults entirely. The list is **replacing**, not merging — re-declare the defaults you want to keep alongside any custom feed. +Override `feeds` to add new feeds or to replace all the defaults. The list **replaces** the defaults, it does not merge with them. Declare again each default that you want to keep with your custom feeds. -The example below keeps the three defaults and adds a fourth feed that ships *denied* approval requests: +The example below keeps the three defaults and adds a fourth feed that sends *denied* approval requests: ```yaml threatlocker: @@ -175,9 +179,9 @@ threatlocker: ## Configuring a ThreatLocker Adapter in the Web UI -Within the LimaCharlie web application, select `+ Add Sensor`, then choose **ThreatLocker**. +In the LimaCharlie web app, select `+ Add Sensor`. Then select **ThreatLocker**. -Pick or create an Installation Key for this adapter, then fill in: +Select or create an Installation Key for this adapter. Then complete these fields: | Field | Value | | --- | --- | @@ -186,11 +190,11 @@ Pick or create an Installation Key for this adapter, then fill in: | Managed Organization ID | *(optional)* Child-tenant UUID for MSP parent tokens. | | Feeds | *(optional)* JSON / YAML array of custom feeds. Leave empty to use the three defaults. | -Click `Complete Cloud Installation`. LimaCharlie will authenticate against the Portal and begin polling. +Click `Complete Cloud Installation`. LimaCharlie authenticates with the Portal and starts to poll. ## Sample Rule -The adapter ships each record under an `EventType` matching the feed's `name`. For the default feed set, that gives `approval_request`, `unified_audit`, and `system_audit` — so D&R rules can route directly on the feed: +The adapter sends each record with an `EventType` that matches the `name` of the feed. The default set of feeds gives `approval_request`, `unified_audit`, and `system_audit`. D&R rules can thus route directly on the feed: ```yaml # Detection — flag every new pending approval request so an AI agent @@ -202,7 +206,7 @@ event: approval_request name: ThreatLocker Approval Request ``` -To chain enrichment + decision from a rule on this event, dispatch to a [Playbook](../../../5-integrations/extensions/limacharlie/playbook.md) or an AI agent — the [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md) page walks through the action surface. +To chain the enrichment and the decision from a rule on this event, dispatch to a [Playbook](../../../5-integrations/extensions/limacharlie/playbook.md) or to an AI agent. The [ThreatLocker extension](../../../5-integrations/extensions/third-party/threatlocker.md) page describes the available actions. ## API Docs diff --git a/docs/2-sensors-deployment/adapters/types/windows-event-log.md b/docs/2-sensors-deployment/adapters/types/windows-event-log.md index 5606a1983..725b32200 100644 --- a/docs/2-sensors-deployment/adapters/types/windows-event-log.md +++ b/docs/2-sensors-deployment/adapters/types/windows-event-log.md @@ -2,14 +2,14 @@ ## Overview -This Adapter allows you to connect to the local Windows Event Logs API on Windows. This means this Adapter is only available from Windows builds and only works locally (will not connect to remote Windows instances). +This Adapter connects to the local Windows Event Logs API on Windows. The Adapter is available only in Windows builds, and it works only locally. It does not connect to remote Windows instances. ## Configurations Adapter Type: `wel` - `client_options`: see [common adapter configuration](../usage.md). -- `evt_sources`: a comma separated list of elements in the format `SOURCE:FILTER`, where `SOURCE` is an Event Source name like `Application`, `System` or `Security` and `FILTER` is an `XPath` filter value as described in the documentation linked below. +- `evt_sources`: a comma separated list of elements in the format `SOURCE:FILTER`. `SOURCE` is an Event Source name, such as `Application`, `System`, or `Security`. `FILTER` is an `XPath` filter value, as described in the documentation linked below. - `write_timeout_sec`: number of seconds before a write to LimaCharlie times out (default: 600). ### Configuration File Example @@ -64,4 +64,4 @@ Specific Provider: ## API Doc -See the [official documentation](https://learn.microsoft.com/en-us/windows/win32/wes/consuming-events). +See the [Microsoft documentation for consuming events](https://learn.microsoft.com/en-us/windows/win32/wes/consuming-events). diff --git a/docs/2-sensors-deployment/adapters/types/zendesk.md b/docs/2-sensors-deployment/adapters/types/zendesk.md index 23ed4056d..0cca9403c 100644 --- a/docs/2-sensors-deployment/adapters/types/zendesk.md +++ b/docs/2-sensors-deployment/adapters/types/zendesk.md @@ -2,28 +2,28 @@ ## Overview -This Adapter allows you to connect to Zendesk to fetch [account activity logs](https://developer.zendesk.com/api-reference/ticketing/account-configuration/audit_logs/#list-audit-logs). +This Adapter connects to Zendesk and gets [account activity logs](https://developer.zendesk.com/api-reference/ticketing/account-configuration/audit_logs/#list-audit-logs). ## Deployment Configurations -All adapters support the same `client_options`, which you should always specify if using the binary adapter or creating a webhook adapter. If you use any of the Adapter helpers in the web app, you will not need to specify these values. +All adapters support the same `client_options`. Always set these options when you use the binary adapter or when you create a webhook adapter. If you use an Adapter helper in the web app, you do not set these values. -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) that this adapter is used with. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself with LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, such as `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: a name that you choose for this adapter. LimaCharlie generates the Sensor IDs (SID) from this name, as described below. ### Adapter-specific Options Adapter Type: `zendesk` - `api_token`: your Zendesk API token -- `zendesk_domain`: your Zendesk domain, like `initech.zendesk.com` -- `zendesk_email`: your Zendesk email address that created the API token +- `zendesk_domain`: your Zendesk domain, such as `initech.zendesk.com` +- `zendesk_email`: the Zendesk email address that created the API token ### CLI Deployment -[Adapter binaries](../deployment.md#adapter-binaries) are available on the deployment page. +You can get the [Adapter binaries](../deployment.md#adapter-binaries) on the deployment page. ```bash chmod +x /path/to/lc_adapter @@ -67,4 +67,4 @@ zendesk: ## API Doc -See the official [documentation](https://developer.zendesk.com/api-reference/ticketing/account-configuration/audit_logs/#list-audit-logs). +See the official [Zendesk audit logs API reference](https://developer.zendesk.com/api-reference/ticketing/account-configuration/audit_logs/#list-audit-logs). diff --git a/docs/2-sensors-deployment/adapters/usage.md b/docs/2-sensors-deployment/adapters/usage.md index e13aed910..286cbe203 100644 --- a/docs/2-sensors-deployment/adapters/usage.md +++ b/docs/2-sensors-deployment/adapters/usage.md @@ -1,19 +1,19 @@ # Adapter Usage -The Adapter can be used to access many different sources and many different event types. The main mechanisms specifying the source and type of events are: +The Adapter can access many sources and many event types. The main mechanisms that specify the source and the type of events are: -1. Adapter Type: this indicates the technical source of the events, like `syslog` or S3 buckets. -2. Platform: the platform indicates the type of events that are acquired from that source, like `text` or `carbon_black`. +1. Adapter Type: this shows the technical source of the events, like `syslog` or S3 buckets. +2. Platform: the platform shows the type of events that come from that source, like `text` or `carbon_black`. -Depending on the Adapter Type specified, configurations that can be specified will change. Running the adapter with no command line arguments will list all available Adapter Types and their configurations. +The configurations that you can set change with the Adapter Type. To list all available Adapter Types and their configurations, run the adapter with no command line arguments. -Configurations can be provided to the adapter in one of three ways: +You can give configurations to the adapter in one of three ways: -1. By specifying a configuration file. -2. By specifying the configurations via the command line in the format `config-name=config-value`. -3. By specifying the configurations via the environment variables in the format `config-name=config-value`. +1. In a configuration file. +2. On the command line, in the format `config-name=config-value`. +3. In environment variables, in the format `config-name=config-value`. -Here's an example config as a config file for an adapter using the `file` method of collection: +This example shows a configuration file for an adapter that uses the `file` collection method: ```yaml file: // The root of the config is the adapter collection method. @@ -30,9 +30,9 @@ file: // The root of the config is the adapter collection method. ## Multi-Adapter -It is possible to execute multiple instances of adapters of the same type within the same adapter process, for example to have a single adapter process monitor files in multiple directories with slightly different configurations. +You can run more than one adapter instance of the same type in the same adapter process. For example, one adapter process can monitor files in several directories with different configurations. -This is achieved by using a configuration file (as described above) with multiple YAML "documents" within like this: +To do this, use a configuration file (as described above) that contains more than one YAML "document", like this: ```yaml file: @@ -75,23 +75,23 @@ file: ## Runtime Configuration -The Adapter runtime supports some custom behaviors to make it more suitable for specific deployment scenarios: +The Adapter runtime supports custom behaviors for specific deployments: -- `healthcheck`: an integer that specifies a port to start an HTTP server on that can be used for healthchecks. +- `healthcheck`: an integer that gives a port. The adapter starts an HTTP server on this port for healthchecks. ## Core Configuration -All Adapter types support the same `client_options`, plus type-specific configurations. The following configurations are *required* for every Adapter: +All Adapter types support the same `client_options`, plus type-specific configurations. These configurations are *required* for every Adapter: -- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) this adapter is used with. -- `client_options.identity.installation_key`: the LimaCharlie Installation Key this adapter should use to identify with LimaCharlie. -- `client_options.platform`: the type of data ingested through this adapter, like `text`, `json`, `gcp`, `carbon_black`, etc. -- `client_options.sensor_seed_key`: an arbitrary name for this adapter which Sensor IDs (SID) are generated from, see below. +- `client_options.identity.oid`: the LimaCharlie Organization ID (OID) for this adapter. +- `client_options.identity.installation_key`: the LimaCharlie Installation Key that this adapter uses to identify itself to LimaCharlie. +- `client_options.platform`: the type of data that this adapter ingests, like `text`, `json`, `gcp`, or `carbon_black`. +- `client_options.sensor_seed_key`: any name for this adapter. LimaCharlie generates Sensor IDs (SID) from this name, see below. - `client_options.hostname`: a hostname for the adapter. ### Example -Using inline parameters: +With inline parameters: ```bash ./lc-adapter file file_path=/path/to/logs.json \ @@ -103,7 +103,7 @@ Using inline parameters: client_options.hostname= ``` -Using Docker: +With Docker: ```bash docker run -d --rm -it -p 4404:4404/udp refractionpoint/lc-adapter syslog \ @@ -117,7 +117,7 @@ docker run -d --rm -it -p 4404:4404/udp refractionpoint/lc-adapter syslog \ is_udp=true ``` -Using a configuration file: +With a configuration file: ```bash ./lc-adapter file config_file.yaml @@ -127,34 +127,34 @@ Using a configuration file: ### Transformation Order -Data sent via USP can be formatted in many different ways. Data is processed in a specific order as a pipeline: +Data that you send through USP can have many formats. The data is processed as a pipeline, in this order: -1. Regular Expression with named capture groups parsing a string into a JSON object. +1. A regular expression with named capture groups parses a string into a JSON object. 2. Built-in (in the cloud) LimaCharlie parsers that apply to specific `platform` values (like `carbon_black`). 3. The various "extractors" defined, like `EventTypePath`, `EventTimePath`, `SensorHostnamePath` and `SensorKeyPath`. -4. Custom `Mappings` directives provided by the client. +4. Custom `Mappings` directives from the client. ### Configurations -The following configurations allow you to customize the way data is ingested by the platform, including mapping and redefining fields such as the event type path and time. +These configurations change how the cloud ingests the data. They also map and redefine fields such as the event type path and the event time. -- `client_options.mapping.parsing_re`: regular expression with [named capture groups](https://github.com/StefanSchroeder/Golang-Regex-Tutorial/blob/master/01-chapter2.markdown#named-matches). The name of each group will be used as the key in the converted JSON parsing. -- `client_options.mapping.parsing_grok:` grok pattern parsing for structured data extraction from unstructured log messages. Grok patterns combine regular expressions with predefined patterns to simplify log parsing and field extraction. -- `client_options.mapping.sensor_key_path`: indicates which component of the events represent unique sensor identifiers. -- `client_options.mapping.sensor_hostname_path`: indicates which component of the event represents the hostname of the resulting Sensor in LimaCharlie. -- `client_options.mapping.event_type_path`: indicates which component of the event represents the Event Type of the resulting event in LimaCharlie. It also supports template strings based on each event. -- `client_options.mapping.event_time_path`: indicates which component of the event represents the Event Time of the resulting event in LimaCharlie. -- `client_options.mapping.event_time_timezone`: specifies the timezone for parsing timestamps that don't include timezone information. Uses IANA timezone names (e.g., `America/New_York`, `Europe/London`, `UTC`). If not specified, timestamps without timezone info are treated as UTC. +- `client_options.mapping.parsing_re`: regular expression with [named capture groups](https://github.com/StefanSchroeder/Golang-Regex-Tutorial/blob/master/01-chapter2.markdown#named-matches). Each group name becomes a key in the converted JSON. +- `client_options.mapping.parsing_grok:` a grok pattern that extracts structured data from unstructured log messages. Grok patterns combine regular expressions with predefined patterns. +- `client_options.mapping.sensor_key_path`: shows which component of the events represents the unique sensor identifier. +- `client_options.mapping.sensor_hostname_path`: shows which component of the event is the hostname of the resulting Sensor in LimaCharlie. +- `client_options.mapping.event_type_path`: shows which component of the event is the Event Type of the resulting event in LimaCharlie. It also supports template strings that are based on each event. +- `client_options.mapping.event_time_path`: shows which component of the event is the Event Time of the resulting event in LimaCharlie. +- `client_options.mapping.event_time_timezone`: the timezone to use for timestamps that have no timezone information. Use IANA timezone names (for example, `America/New_York`, `Europe/London`, `UTC`). If you do not set this option, timestamps with no timezone information are UTC. - `client_options.mapping.rename_only`: *deprecated* - `client_options.mapping.mappings`: *deprecated* - `client_options.mapping.transform`: a Transform to apply to events. -- `client_options.mapping.drop_fields`: a list of field paths to be dropped from the data before being processed and retained. +- `client_options.mapping.drop_fields`: a list of field paths to remove from the data before the data is processed and kept. ### Parsing #### Named Group Parsing -If the data ingested in LimaCharlie is text (a syslog line for example), you may automatically parse it into a JSON format. To do this, you need to define one of the following: +If the data that LimaCharlie ingests is text (a syslog line, for example), you can parse it into JSON automatically. To do this, define one of these options: - a grok pattern, using the `client_options.mapping.parsing_grok` option - a regular expression, using the `client_options.mapping.parsing_re` option @@ -165,14 +165,14 @@ If the data ingested in LimaCharlie is text (a syslog line for example), you may Grok patterns use the following syntax: -The grok pattern line must start with **message:** , followed by the patterns, as in the example below +The grok pattern line must start with **message:** , and then the patterns, as in the example below - `%{PATTERN_NAME:field_name}` - Extract a pattern into a named field - `%{PATTERN_NAME}` - Match a pattern without extraction -Custom patterns can be defined using the pattern name as a key +To define custom patterns, use the pattern name as a key -This means that the patterns should not include extracted field names called message as it will conflict with the assumed root of the grok pattern called message. +The patterns must not include an extracted field name called message. That name conflicts with the assumed root of the grok pattern, which is also called message. ##### Built-in Patterns @@ -221,7 +221,7 @@ client_options: ##### Timezone Handling -Many log sources emit timestamps without timezone information (e.g., `2024-01-01 12:00:00` or `Jan 15 14:30:22`). By default, LimaCharlie interprets these as UTC. If your logs use local time, you can specify the timezone using `event_time_timezone`: +Many log sources send timestamps with no timezone information (for example, `2024-01-01 12:00:00` or `Jan 15 14:30:22`). By default, LimaCharlie reads these as UTC. If your logs use local time, set the timezone with `event_time_timezone`: ```yaml client_options: @@ -243,7 +243,7 @@ The timezone must be a valid [IANA timezone name](https://en.wikipedia.org/wiki/ | `Asia/Tokyo` | Japan Standard Time | | `UTC` | Coordinated Universal Time | -> **Note:** Unix epoch timestamps (e.g., `1704067200`) are timezone-agnostic and are not affected by this setting. +> **Note:** Unix epoch timestamps (for example, `1704067200`) have no timezone, and this setting does not change them. #### Regular Expressions @@ -259,7 +259,7 @@ Nov 09 10:57:09 penguin PackageKit[21212]: daemon quit (?P... \d\d \d\d:\d\d:\d\d) (?P.+) (?P.+?)\[(?P\d+)\]: (?P.*) ``` -which would result in the following event in LimaCharlie: +This gives the following event in LimaCharlie: ```json { @@ -273,19 +273,19 @@ which would result in the following event in LimaCharlie: #### Key/Value Parsing -Alternatively you can specify a regular expression that does NOT contain Named Groups, like this: +As an alternative, you can give a regular expression that does NOT contain Named Groups, like this: ```text (?:<\d+>\s*)?(\w+)=(".*?"|\S+) ``` -When in this mode, LimaCharlie assumes the regular expression will generate a list of matches where each match has 2 submatches, and submatch index 1 is the Key name, and submatch index 2 is the value. This is compatible with logs like CEF for example where the log could look like: +In this mode, LimaCharlie expects the regular expression to generate a list of matches. Each match has 2 submatches. Submatch index 1 is the Key name, and submatch index 2 is the value. This mode works with logs such as CEF, where the log can look like this: ```text <20>hostname=my-host log_name=http_logs timestamp=.... ``` -which would end up generating: +This generates: ```json { @@ -305,11 +305,11 @@ Namely: - Event Type - Event Time -You may specify certain fields from the JSON logs to be extracted into these common fields. +You can select fields from the JSON logs to extract into these common fields. -This process is done by specifying the "path" to the relevant field in the JSON data. Paths are like a directory path using `/` for each sub directory except that in our case, they describe how to get to the relevant field from the top level of the JSON. +To do this, give the "path" to the field in the JSON data. A path is like a directory path that uses `/` for each sub directory. In this case, the path shows how to get to the field from the top level of the JSON. -For example, using this event: +For example, with this event: ```json { @@ -323,18 +323,18 @@ For example, using this event: } ``` -The following paths would yield the following results: +These paths give these results: - `a`: `x` - `b`: `y` - `c/d/e`: `z` -The following extractors can be specified: +You can specify these extractors: -- `client_options.mapping.sensor_key_path`: indicates which component of the events represent unique sensor identifiers. -- `client_options.mapping.sensor_hostname_path`: indicates which component of the event represents the hostname of the resulting Sensor in LimaCharlie. -- `client_options.mapping.event_type_path`: indicates which component of the event represents the Event Type of the resulting event in LimaCharlie. It also supports template strings based on each event. -- `client_options.mapping.event_time_path`: indicates which component of the event represents the Event Time of the resulting event in LimaCharlie. +- `client_options.mapping.sensor_key_path`: shows which component of the events represents the unique sensor identifier. +- `client_options.mapping.sensor_hostname_path`: shows which component of the event is the hostname of the resulting Sensor in LimaCharlie. +- `client_options.mapping.event_type_path`: shows which component of the event is the Event Type of the resulting event in LimaCharlie. It also supports template strings that are based on each event. +- `client_options.mapping.event_time_path`: shows which component of the event is the Event Time of the resulting event in LimaCharlie. ### Indexing @@ -346,9 +346,9 @@ Indexing occurs in one of 3 ways: #### User Defined Indexing -An Adapter can be configured to do custom indexing on the data it feeds. +You can configure an Adapter to do custom indexing on the data that it feeds. -This is done by setting the `indexing` element in the `client_options`. This field contains a list of index descriptors. +To do this, set the `indexing` element in the `client_options`. This field contains a list of index descriptors. An index descriptor can have the following fields: @@ -367,7 +367,7 @@ path: userAgent index_type: user ``` -Put together in a client option, you could have: +In a client option, this can look like this: ```text { @@ -401,13 +401,13 @@ This is the list of currently supported index types: ### Sensor IDs -USP Clients generate LimaCharlie Sensors at runtime. The ID of those sensors (SID) is generated based on the Organization ID (OID) and the Sensor Seed Key. +USP Clients generate LimaCharlie Sensors at runtime. LimaCharlie generates the ID of those sensors (SID) from the Organization ID (OID) and the Sensor Seed Key. -This implies that if want to re-key an IID (perhaps it was leaked), you may replace the IID with a new valid one. As long as you use the same OID and Sensor Seed Key, the generated SIDs will be stable despite the IID change. +If you must re-key an IID because it leaked, replace the IID with a new valid one. If you keep the same OID and Sensor Seed Key, the generated SIDs stay stable after the IID change. ### Discovering adapter types and finding an adapter's sensor -The CLI can enumerate the supported adapter types, describe their configuration schema, and locate the sensor an adapter produced. These commands work for both `cloud-adapter` (the hosted set) and `external-adapter` (the on-prem set); the examples below use `cloud-adapter`. +The CLI can list the supported adapter types, show their configuration schema, and find the sensor that an adapter produced. These commands work for both `cloud-adapter` (the hosted set) and `external-adapter` (the on-prem set). The examples below use `cloud-adapter`. List the supported adapter/sensor type names: @@ -415,30 +415,30 @@ List the supported adapter/sensor type names: limacharlie cloud-adapter list-types ``` -Note that `external-adapter list-types` lists the on-prem set, which differs from the cloud set. +`external-adapter list-types` lists the on-prem set, which is different from the cloud set. -Show the configuration field listing for one adapter type. This indicates where each field lives (for example, `hostname` under `client_options`). Add `--output json` for the raw schema: +Show the configuration field listing for one adapter type. The listing shows where each field is (for example, `hostname` under `client_options`). Add `--output json` for the raw schema: ```bash limacharlie cloud-adapter schema --type limacharlie cloud-adapter schema --type --output json ``` -Find the live sensor(s) an adapter produced, matched by installation-key IID: +Find the live sensors that an adapter produced, matched by installation-key IID: ```bash limacharlie cloud-adapter sensors --key ``` -An empty result means the adapter has not delivered any events yet; the sensor materializes on the first event. +An empty result means that the adapter did not deliver any events yet. The sensor appears on the first event. ## Validating Configurations -Before deploying an adapter to production, you can validate your configuration and test parsing rules to ensure data will be correctly ingested. +Before you deploy an adapter to production, validate your configuration and test the parsing rules. This makes sure that the data is ingested correctly. ### Validating Adapter Configuration -The adapter binary supports a `--validate` flag that checks your configuration without actually starting the adapter: +The adapter binary supports a `--validate` flag. This flag checks your configuration, but it does not start the adapter: ```bash # Validate a YAML config file @@ -448,11 +448,11 @@ The adapter binary supports a `--validate` flag that checks your configuration w ./lc_adapter --validate wel evt_sources=Security,System client_options.identity.oid=... client_options.identity.installation_key=... client_options.platform=wel ``` -This will: +The flag does the following: -1. Parse and validate the configuration structure -2. Check for required fields (OID, installation key, platform, etc.) -3. Report any configuration errors without connecting to LimaCharlie +1. Parses and validates the configuration structure +2. Checks for required fields (OID, installation key, platform, etc.) +3. Reports configuration errors, and does not connect to LimaCharlie Exit codes: @@ -461,19 +461,19 @@ Exit codes: ### Testing Parsing with Sample Data -The adapter also supports a `--test-parsing` flag that sends sample data to the LimaCharlie validation API to verify your parsing rules work correctly: +The adapter also supports a `--test-parsing` flag. This flag sends sample data to the LimaCharlie validation API to check that your parsing rules work correctly: ```bash # Test parsing with a sample log file ./lc_adapter --test-parsing sample.log syslog config.yaml ``` -This will: +The flag does the following: -1. Read sample data from the specified file -2. Send it to the LimaCharlie validation API with your mapping configuration -3. Display the parsed events or any parsing errors -4. Exit with error (code 1) if no events were parsed (likely misconfigured parsing rules) +1. Reads sample data from the file that you specify +2. Sends the data to the LimaCharlie validation API with your mapping configuration +3. Shows the parsed events or the parsing errors +4. Exits with an error (code 1) if it parsed no events. This usually means that the parsing rules are incorrect. Exit codes: @@ -503,7 +503,7 @@ Event 1: } ``` -Example error output when no events are parsed (e.g., regex doesn't match): +Example error output when the adapter parses no events (for example, the regex does not match): ```text starting @@ -526,11 +526,11 @@ Suggestions: parsing test failed: no events parsed from sample data ``` -**Note**: The config must contain a valid API key (not just an installation key) in `client_options.identity.installation_key` for API authentication. +**Note**: For API authentication, the config must contain a valid API key in `client_options.identity.installation_key`. An installation key is not enough. ### Testing Parsing via Python CLI -You can also test parsing using the LimaCharlie Python CLI: +You can also test parsing with the LimaCharlie Python CLI: ```bash # Validate with a text file containing sample logs @@ -546,24 +546,24 @@ limacharlie usp validate --platform json --mapping-file mapping.yaml --input-fil limacharlie usp validate --platform text --mapping-file mapping.yaml --input-file sample.log --output-format json ``` -The validation API processes your sample data through the actual parsing engine and returns: +The validation API processes your sample data with the parsing engine and returns: -- **On success**: Parsed events showing how data will be transformed -- **On failure**: Specific error messages indicating what went wrong +- **On success**: the parsed events, which show how the data is transformed +- **On failure**: error messages that show the problem ### Common Validation Issues | Issue | Cause | Solution | |-------|-------|----------| -| `missing platform` | No `platform` field in client_options | Add `client_options.platform` (e.g., `text`, `json`, `cef`) | +| `missing platform` | No `platform` field in client_options | Add `client_options.platform` (for example, `text`, `json`, `cef`) | | `missing oid` | No organization ID configured | Add `client_options.identity.oid` | | `missing installation_key` | No installation key configured | Add `client_options.identity.installation_key` | -| `regex pattern did not match` | Parsing regex doesn't match input format | Test regex against actual sample data | -| `no events parsed from sample data` | Regex doesn't match, wrong platform, or empty input | Verify parsing_re matches your data, check platform type, ensure sample file has content | +| `regex pattern did not match` | The parsing regex does not match the input format | Test the regex against your sample data | +| `no events parsed from sample data` | The regex does not match, the platform is wrong, or the input is empty | Check that parsing_re matches your data, check the platform type, and make sure that the sample file has content | ### SDK Validation -For programmatic validation, the Python SDK provides the `validateUSP` method: +For programmatic validation, use the `validateUSP` method in the Python SDK: ```python from limacharlie import Manager diff --git a/docs/2-sensors-deployment/asset-tags.md b/docs/2-sensors-deployment/asset-tags.md index 5de320370..34521a73c 100644 --- a/docs/2-sensors-deployment/asset-tags.md +++ b/docs/2-sensors-deployment/asset-tags.md @@ -1,45 +1,45 @@ # Asset Tag Namespace (`lc:asset:*`) -`lc:asset:*` is a reserved sensor-tag namespace for marking endpoints with structured asset metadata — criticality, network exposure, environment, owner, compliance regimes, and OS. It is a convention layered on top of [Sensor Tags](sensor-tags.md): there is no separate field on the sensor model, no migration to run, and no per-surface schema to extend. Any LimaCharlie surface that needs asset context (Vulnerabilities, D&R, Cases, Search, Query Console, Outputs, etc.) reads the same tags and gets a consistent view. +`lc:asset:*` is a reserved namespace for sensor tags. It marks endpoints with structured asset metadata: criticality, network exposure, environment, owner, compliance regimes, and OS. The namespace is a convention on top of [Sensor Tags](sensor-tags.md). There is no separate field on the sensor model, no migration to run, and no schema to extend for each surface. Any LimaCharlie surface that needs asset context (Vulnerabilities, D&R, Cases, Search, Query Console, Outputs, etc.) reads the same tags and gets a consistent view. -The first consumer of the namespace is the [Vulnerability Reporting extension](../5-integrations/extensions/limacharlie/vulnerability-reporting.md), which uses `lc:asset:criticality:*` to drive risk scoring and SLA windows. Other surfaces will adopt the same parser as they need asset context. +The first consumer of the namespace is the [Vulnerability Reporting extension](../5-integrations/extensions/limacharlie/vulnerability-reporting.md). It uses `lc:asset:criticality:*` for risk scores and SLA windows. Other surfaces will adopt the same parser when they need asset context. ## Why tags -LimaCharlie tags are already the cross-cutting metadata mechanism for sensors: +LimaCharlie tags are already the metadata mechanism that all sensors share: - They are visible on every event under `routing.tags`. - They are queryable in D&R rules, sensor selectors, LCQL, and the API. -- They can be applied at enrollment time, by mass-tagging selectors, by D&R response actions, or manually through the web app and CLI. +- You can apply them at enrollment time, with mass-tagging selectors, with D&R response actions, or manually in the web app and the CLI. -Adding a new sensor-model field for asset metadata would require schema changes, per-surface adoption, and a separate write path. A tag convention sidesteps all of that: every surface that already understands tags inherits the new metadata for free. +A new field on the sensor model for asset metadata would need schema changes, adoption in each surface, and a separate write path. A tag convention avoids all of that. Every surface that already understands tags gets the new metadata with no more work. ## Schema -The namespace defines six tag prefixes. The value follows the prefix as a third colon-separated segment. +The namespace defines six tag prefixes. The value comes after the prefix, as a third colon-separated segment. | Tag | Values | Cardinality | Purpose | |---|---|---|---| -| `lc:asset:criticality:` | `critical`, `high`, `medium`, `low` | Singleton | Asset importance. Used as a risk-score multiplier and to drive priority sort and SLA windows. | -| `lc:asset:exposure:` | `internet-facing`, `dmz`, `internal` | Singleton | Network reachability. Feeds risk scoring and filter chips. | -| `lc:asset:env:` | `prod`, `staging`, `dev`, `test` | Singleton | Environment for filtering and suppression scoping. | -| `lc:asset:owner:` | Free text | Singleton | Routing target for assignment / paging (e.g. a team name, an email, a Slack handle). | -| `lc:asset:compliance:` | Free text (e.g. `pci`, `hipaa`, `sox`, `gdpr`) | Multi-value | Compliance regimes the asset is subject to. A sensor can carry several at once. | -| `lc:asset:os:-` | Free text (e.g. `debian-11`, `redhat-enterprise-9`) | Singleton | Linux distribution and release. Lets the [Vulnerability Reporting extension](../5-integrations/extensions/limacharlie/vulnerability-reporting.md#linux-distro-aware-matching) apply distro backport data so backported security fixes aren't flagged as vulnerable. Split on the **last** `-`. | +| `lc:asset:criticality:` | `critical`, `high`, `medium`, `low` | Singleton | Asset importance. Used as a multiplier for the risk score, and for the priority sort and the SLA windows. | +| `lc:asset:exposure:` | `internet-facing`, `dmz`, `internal` | Singleton | Network reachability. Used for the risk score and the filter chips. | +| `lc:asset:env:` | `prod`, `staging`, `dev`, `test` | Singleton | Environment. Used for filters and for the scope of suppression. | +| `lc:asset:owner:` | Free text | Singleton | The routing target for assignment and paging (for example, a team name, an email, or a Slack handle). | +| `lc:asset:compliance:` | Free text (for example, `pci`, `hipaa`, `sox`, `gdpr`) | Multi-value | The compliance regimes that apply to the asset. A sensor can have more than one. | +| `lc:asset:os:-` | Free text (for example, `debian-11`, `redhat-enterprise-9`) | Singleton | Linux distribution and release. This lets the [Vulnerability Reporting extension](../5-integrations/extensions/limacharlie/vulnerability-reporting.md#linux-distro-aware-matching) apply distro backport data, so it does not flag backported security fixes as vulnerable. Split on the **last** `-`. | ### Validation rules -The closed-set fields (`criticality`, `exposure`, `env`) only accept the values listed above. Tags with malformed or unknown values for those fields are dropped by the parser — this prevents typos like `lc:asset:criticality:hi` from creating a phantom bucket in dashboards or SLAs. +The closed-set fields (`criticality`, `exposure`, `env`) accept only the values in the table above. The parser drops tags with malformed or unknown values for those fields. This stops a typo such as `lc:asset:criticality:hi` from creating a phantom bucket in dashboards or SLAs. `owner` and `compliance` accept any non-empty value after the prefix. -If a sensor carries multiple tags for the same singleton field (for example, both `lc:asset:env:prod` and `lc:asset:env:staging`), the parser picks the first match in lexical order. This is deterministic but should be avoided — fix the tags rather than rely on the resolution order. +If a sensor has more than one tag for the same singleton field, the parser picks the first match in lexical order. For example, a sensor can have both `lc:asset:env:prod` and `lc:asset:env:staging`. The result is deterministic, but do not depend on it. Correct the tags instead. -`compliance` values are deduplicated and sorted alphabetically when emitted as JSON, so `lc:asset:compliance:pci` plus `lc:asset:compliance:hipaa` always renders as `["hipaa","pci"]` regardless of tag order. +In JSON output, `compliance` values are deduplicated and sorted alphabetically. `lc:asset:compliance:pci` and `lc:asset:compliance:hipaa` therefore always give `["hipaa","pci"]` in any tag order. ## Applying tags -Use the [`limacharlie` CLI](../6-developer-guide/cli.md) (or the API equivalents documented in [Sensor Tags](sensor-tags.md)). +Use the [`limacharlie` CLI](../6-developer-guide/cli.md), or the equivalent API calls in [Sensor Tags](sensor-tags.md). ### Tag a single sensor @@ -54,7 +54,7 @@ limacharlie tag add --sid SENSOR_ID --tag lc:asset:os:debian-11 ### Tag a fleet by selector -Mass-tagging is the practical path for any non-trivial environment. The selector uses [sensor selector expressions](../8-reference/sensor-selector-expressions.md). +Mass-tagging is the practical method for any environment that is not small. The selector uses [sensor selector expressions](../8-reference/sensor-selector-expressions.md). ```bash # All Linux production hosts: env=prod @@ -78,15 +78,15 @@ limacharlie tag mass-add \ --tag lc:asset:compliance:pci ``` -Tags applied via mass-add are persistent (no TTL) unless `--ttl` is passed. Re-running mass-add is idempotent. +Tags that you apply with mass-add are persistent (no TTL), unless you give `--ttl`. The mass-add command is idempotent, so you can run it again. ### Apply at enrollment time -Installation keys can carry a fixed list of tags applied to every sensor that enrols against them. Bake the asset metadata into separate keys per asset class — for example, one key per environment + criticality combination — so the metadata lands the moment the sensor connects. +An installation key can carry a fixed list of tags. These tags are applied to every sensor that enrolls with that key. Put the asset metadata in a separate key for each asset class, for example one key for each combination of environment and criticality. The sensor then gets the metadata when it connects. ### Apply via D&R rules -D&R rules can add or remove tags as a response action. This is useful when asset state can be inferred from telemetry — for example, tagging a host as `lc:asset:exposure:internet-facing` when it starts answering on a public IP, or as `lc:asset:env:prod` based on a hostname pattern. +A D&R rule can add or remove tags as a response action. Use this when the telemetry shows the state of the asset. For example, tag a host as `lc:asset:exposure:internet-facing` when it starts to answer on a public IP, or as `lc:asset:env:prod` from a hostname pattern. ```yaml respond: @@ -96,20 +96,20 @@ respond: ## How surfaces consume the tags -Each consumer surface uses a canonical parser that turns a sensor's tag set into a structured `AssetMetadata` object: +Each consumer surface uses a canonical parser. The parser converts the tag set of a sensor into a structured `AssetMetadata` object: -- **Go:** `ParseAssetMetadata(tags)` returns an `AssetMetadata` struct with `Criticality`, `Exposure`, `Env`, `Owner`, and `Compliance` fields. Used by extensions and backend services. -- **TypeScript:** `parseAssetMetadataFromTags(tags)` mirrors the Go shape for use in the LimaCharlie web app and any TypeScript SDK consumer. +- **Go:** `ParseAssetMetadata(tags)` returns an `AssetMetadata` struct with `Criticality`, `Exposure`, `Env`, `Owner`, and `Compliance` fields. Extensions and backend services use this function. +- **TypeScript:** `parseAssetMetadataFromTags(tags)` has the same shape as the Go function. The LimaCharlie web app and any TypeScript SDK consumer use it. -Both implementations share the same prefix list, the same closed-set validation, and the same tie-breaking rules so a tag set is interpreted identically across the platform. +The two implementations share the same prefix list, the same closed-set validation, and the same tie-breaking rules. A tag set therefore has the same interpretation across the platform. -The Vulnerability Reporting extension exposes the parsed metadata under an `asset_metadata` field on every endpoint and finding when `include_tags=true` is requested. See the [extension page](../5-integrations/extensions/limacharlie/vulnerability-reporting.md) for the response shape. +If you request `include_tags=true`, the Vulnerability Reporting extension gives the parsed metadata in an `asset_metadata` field on every endpoint and finding. For the response shape, see the [Vulnerability Reporting extension page](../5-integrations/extensions/limacharlie/vulnerability-reporting.md). ## Override hatches -Organizations that already run an asset taxonomy (for example, a long-standing `crown-jewel` / `tier-1` / `tier-3` scheme) can map their existing tags into the canonical buckets without re-tagging the fleet. +An organization that already has an asset taxonomy can map its tags into the canonical buckets. It does not have to tag the fleet again. One example is a long-standing `crown-jewel` / `tier-1` / `tier-3` scheme. -Today the override is exposed by the Vulnerability Reporting extension as a `criticality_tag_overrides` configuration field: +Today, the Vulnerability Reporting extension gives this override in a `criticality_tag_overrides` configuration field: ```json { @@ -121,11 +121,11 @@ Today the override is exposed by the Vulnerability Reporting extension as a `cri } ``` -The mapping is consulted only when no canonical `lc:asset:criticality:*` tag is present on the sensor. Explicit canonical tags always win, so an org can migrate gradually: leave the override map in place, start applying canonical tags to the most important assets, and remove the override entries as coverage grows. +The mapping is used only when the sensor has no canonical `lc:asset:criticality:*` tag. An explicit canonical tag always has priority, so an organization can migrate one step at a time. Keep the override map, apply canonical tags to the most important assets first, and remove the override entries when coverage grows. -Override values must be one of the four canonical buckets; any other value is silently ignored at read time and rejected when the configuration is written. +An override value must be one of the four canonical buckets. Any other value is ignored at read time and rejected when the configuration is written. -Other surfaces will adopt the same override pattern (or its equivalent) as they consume the namespace. +Other surfaces will adopt the same override pattern, or an equivalent, when they consume the namespace. ## Sample real-world tagging @@ -139,7 +139,7 @@ A hypothetical SaaS company runs four classes of assets. The tag plan: | Engineering laptops (internal, dev work) | `lc:asset:criticality:low`, `lc:asset:exposure:internal`, `lc:asset:env:dev`, `lc:asset:owner:it-help` | | HR file share (internal, in HIPAA + SOX scope) | `lc:asset:criticality:high`, `lc:asset:exposure:internal`, `lc:asset:env:prod`, `lc:asset:compliance:hipaa`, `lc:asset:compliance:sox`, `lc:asset:owner:hr-ops` | -Driven by `limacharlie tag mass-add` calls keyed off existing infrastructure tags (e.g. an installation key per asset class, a hostname prefix, a cloud-provider label propagated via the cloud adapters), the entire fleet can be classified in a single pass and kept current as new sensors enrol. +Use `limacharlie tag mass-add` calls that key off existing infrastructure tags. Such tags include an installation key for each asset class, a hostname prefix, or a cloud-provider label that the cloud adapters propagate. You can classify the full fleet in one pass and keep it current as new sensors enroll. ## See Also diff --git a/docs/2-sensors-deployment/connectivity.md b/docs/2-sensors-deployment/connectivity.md index 179209945..3b6484974 100644 --- a/docs/2-sensors-deployment/connectivity.md +++ b/docs/2-sensors-deployment/connectivity.md @@ -1,33 +1,33 @@ # Sensor Connectivity -The network connection required by the LimaCharlie Sensor is very simple. It requires a single TCP connection over port 443 to a specific domain, and optionally another destination for the [Artifact Collection](../4-data-queries/events/index.md) service. +The network connection that the LimaCharlie Sensor needs is simple. The sensor needs one TCP connection over port 443 to a specific domain. Optionally, it also needs another destination for the [Artifact Collection](../4-data-queries/events/index.md) service. -The specific domains are listed in the Sensor Downloads section of your Organization's dashboard. They will vary depending on the datacenter you chose to create your organization in. To find yours, see the screenshots below. +The Sensor Downloads section of the dashboard for your Organization lists the specific domains. The domains change with the datacenter that you chose for your organization. To find your domains, see the screenshots below. -Currently, web proxies are not supported, but since LimaCharlie requires a single connection to a single dedicated domain, it makes creating a single exception safe and easy. +Web proxies are not supported at this time. LimaCharlie needs one connection to one dedicated domain, so you can add one safe exception. ## Proxy Tunneling The LimaCharlie sensor supports unauthenticated proxy tunneling through [HTTP CONNECT](https://en.wikipedia.org/wiki/HTTP_tunnel). -This allows the LimaCharlie connection to go through the proxy in an opaque way (since the sensor does not support SSL interception). +The LimaCharlie connection goes through the proxy in an opaque way, because the sensor does not support SSL interception. -To activate this feature, set the `LC_PROXY` environment variable to the DNS or hostname of the proxy to use. For example you could use: `LC_PROXY=proxy.corp.com:8080`. +To enable this feature, set the `LC_PROXY` environment variable to the DNS name or the hostname of the proxy. For example: `LC_PROXY=proxy.corp.com:8080`. ### Windows -On Windows, you may use a light auto-detection of a globally-configured, unauthenticated proxy. +On Windows, you can use a simple auto-detection of a global, unauthenticated proxy. -To enable this, set the same environment variable to the `-` value, like `LC_PROXY=-`. This will make the sensor query the registry key `HKLM\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer` and use its value as the proxy destination. +To enable this, set the same environment variable to the `-` value, like `LC_PROXY=-`. The sensor then reads the registry key `HKLM\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer` and uses its value as the proxy destination. -Also on Windows, in some cases the environment variable changes do not propagate to all processes in the expected way. Usually a reboot of the machine will fix it, but for machines that cannot be rebooted you have the ability to set a special value to the environment variable (deletion is usually problematic but setting a var works) that will disable the proxy specifically: `!`. So if you set the `LC_PROXY` variable to `!` (exclamation mark), the proxy will be disabled. +Also on Windows, changes to an environment variable sometimes do not propagate to all processes. A reboot of the machine usually corrects this. If you cannot reboot the machine, set the `LC_PROXY` variable to `!` (exclamation mark). This value disables the proxy. Deletion of the variable is usually problematic, but a new value works. ## Certificate Revocation Checks on Restricted Networks (Windows) -On Windows, when the sensor verifies code signatures it performs certificate revocation checks, which can attempt to reach CRL/OCSP endpoints over the network. On air-gapped or tightly restricted networks those lookups may stall or fail. +On Windows, the sensor does certificate revocation checks when it verifies code signatures. These checks can try to reach CRL/OCSP endpoints on the network. On air-gapped or tightly restricted networks, these lookups can stall or fail. -Setting the `LC_LOCAL_CACHE_ONLY_REVOCATION_CHECK` environment variable to `1` (or `true`) on the sensor process makes these revocation checks use only the local cache and never reach out to the network. +Set the `LC_LOCAL_CACHE_ONLY_REVOCATION_CHECK` environment variable to `1` (or `true`) on the sensor process. The revocation checks then use only the local cache and do not use the network. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Like agents, Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless method to connect the endpoints of an organization to the cloud in a secure way. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives full control of security operations. This structure supports multi-tenant setups for managed security providers, or for enterprises that manage many departments or clients. diff --git a/docs/2-sensors-deployment/endpoint-agent/chrome/installation.md b/docs/2-sensors-deployment/endpoint-agent/chrome/installation.md index 090b9c30f..59cfdfe4b 100644 --- a/docs/2-sensors-deployment/endpoint-agent/chrome/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/chrome/installation.md @@ -1,40 +1,43 @@ # Chrome Agent Installation -LimaCharlie's Chrome Sensor is built as a browser extension and provides visibility for activity performed within the browser. This sensor is particularly useful for gaining affordable network visibility in organizations that make heavy use of ChromeOS. +The LimaCharlie Chrome sensor is a browser extension. It gives visibility of the activity inside the browser. The sensor is useful to get network visibility at low cost in organizations that use ChromeOS a lot. -It is delivered as the [LimaCharlie Sensor](https://chrome.google.com/webstore/detail/limacharlie-sensor/ljdgkaegafdgakkjekimaehhneieecki) extension available in the Chrome Web Store. +LimaCharlie supplies it as the [LimaCharlie Sensor](https://chrome.google.com/webstore/detail/limacharlie-sensor/ljdgkaegafdgakkjekimaehhneieecki) extension in the Chrome Web Store. ## Installation Instructions The Chrome sensor is available in the Chrome Web Store. -1. In the LimaCharlie web app (app.limacharlie.io), go to the "Installation Keys" section, select your Installation Key and click the "Chrome Key" copy icon to copy the key to your clipboard. -2. Install the sensor from: -3. A new tab will open where you can add your installation key from before. If you close it by mistake, you can re-open it by: +1. In the LimaCharlie web app (app.limacharlie.io), go to the "Installation Keys" section. +2. Select your installation key. +3. Click the "Chrome Key" copy icon. The web app copies the key to your clipboard. +4. Install the sensor from: +5. In the new tab that opens, enter the installation key from step 3. If you close the tab by mistake, open the options again: - 1. From the Extensions page at chrome://extensions/ click on the "Details" button of the LimaCharlie Sensor extension. - 2. Go to the "Extension options" section, and enter your installation key from the previous step. Click save. + 1. On the Extensions page at chrome://extensions/, click the "Details" button of the LimaCharlie Sensor extension. + 2. Go to the "Extension options" section. + 3. Enter the installation key from the previous step. Click save. -The installation key can also be pre-configured through the Managed Storage feature (key named `installation_key`) if you are using a managed Chrome deployment. +If you use a managed Chrome deployment, you can set the installation key in advance with the Managed Storage feature. The key name is `installation_key`. ## Troubleshooting the Chrome Sensor -If the Chrome extension is giving connectivity issues, the following may help. +If the Chrome extension has connectivity problems, these steps can help. -First, try uninstalling/re-installing the extension. +First, uninstall the extension and install it again. -If the extension continues to fail to connect, please provide the LimaCharlie support team with the following details: +If the extension still does not connect, send these details to the LimaCharlie support team: -1. Open a new browser tab -2. Go to `chrome://extensions/` -3. Ensure "Developer Mode" is enabled (see toggle in the top right) +1. Open a new browser tab. +2. Go to `chrome://extensions/`. +3. Make sure that "Developer Mode" is on. The toggle is in the top right. -![image.png](../../../assets/images/image(38).png) + ![image.png](../../../assets/images/image(38).png) -1. Click the `background.html` link in the LimaCharlie Sensor entry. +4. Click the `background.html` link in the LimaCharlie Sensor entry. -![image.png](../../../assets/images/image(39).png) + ![image.png](../../../assets/images/image(39).png) -1. In the window that opens, click Console and provide us with a screenshot of what appears for analysis. +5. In the window that opens, click Console. Send a screenshot of the console output for analysis. -Please also include your Organization ID, which can be found within the LimaCharlie web interface in the REST API section under `OID`. +Also include your Organization ID. You find it in the LimaCharlie web app in the REST API section under `OID`. diff --git a/docs/2-sensors-deployment/endpoint-agent/cli-reference.md b/docs/2-sensors-deployment/endpoint-agent/cli-reference.md index da2989de7..313f256c5 100644 --- a/docs/2-sensors-deployment/endpoint-agent/cli-reference.md +++ b/docs/2-sensors-deployment/endpoint-agent/cli-reference.md @@ -1,99 +1,103 @@ # Agent CLI & Environment Reference -This page is the single reference for the command-line options, environment -variables, and local files supported by the LimaCharlie endpoint agent (the -on-disk sensor binary, named `rphcp` once installed). The platform-specific -installation pages link here for the full list. +This page is the one reference for the command-line options, the environment +variables, and the local files that the LimaCharlie endpoint agent supports. +The agent is the on-disk sensor binary, named `rphcp` after installation. The +installation page for each platform links to this page for the full list. -All options below are available in the released sensor. Internal/debug-only -flags are intentionally not documented. +All options below are available in the released sensor. This page does not +document internal flags or debug-only flags. ## Command-Line Options -The same binary is used both to install/manage the service and to run it. When -run from the command line you can pass the following options. Most management -actions require **root** (Linux/macOS) or **Administrator** (Windows). +The same binary installs the service, manages the service, and runs it. When +you start the binary from the command line, you can give the options below. +Most management actions need **root** (Linux/macOS) or **Administrator** +(Windows). | Option | Long form | Description | |--------|-----------|-------------| -| `-i ` | `--install` | Install as a service using the specified installation key, then enroll. | -| `-d ` | `--deployment` | Run with the installation key without performing a permanent installation (temporary/foreground enrollment). Pass `-d -` to read the key from the environment or a local file (see [Installation key sources](#installation-key-sources)). | -| `-u` | `--upgrade` | Upgrade the installed service in place using this binary. Requires sensor **4.33.28+**. See [Service Upgrades](service-upgrades.md). | -| `-r` | `--uninstall` | Uninstall the service, leaving the identity files on disk. | -| `-c` | `--uninstall-clean` | Uninstall the service and delete the identity/config files (`hcp`, `hcp_hbs`, `hcp_conf`). | -| `-t` | `--vdi` | Write the VDI delay file to postpone enrollment by 24 hours, for use when baking golden images. See [VDI Templates](vdi/templates.md). | -| `-H` | `--health` | Run the sensor health check and write a diagnostic report. See [Sensor Troubleshooting Utility](../../8-reference/faq/troubleshooting.md#sensor-troubleshooting-utility). Requires sensor **4.33.6+**. | -| `-v` | `--verbose` | Enable verbose logging output (equivalent to setting `LC_VERBOSE=1`). | +| `-i ` | `--install` | Install as a service with the given installation key, then enroll. | +| `-d ` | `--deployment` | Run with the installation key, but do not install permanently (temporary or foreground enrollment). Give `-d -` to read the key from the environment or from a local file (see [Installation key sources](#installation-key-sources)). | +| `-u` | `--upgrade` | Upgrade the installed service in place with this binary. Needs sensor **4.33.28+**. See [Service Upgrades](service-upgrades.md). | +| `-r` | `--uninstall` | Uninstall the service. The identity files stay on disk. | +| `-c` | `--uninstall-clean` | Uninstall the service and delete the identity and configuration files (`hcp`, `hcp_hbs`, `hcp_conf`). | +| `-t` | `--vdi` | Write the VDI delay file to delay enrollment by 24 hours. Use this option when you build golden images. See [VDI Templates](vdi/templates.md). | +| `-H` | `--health` | Run the sensor health check and write a diagnostic report. See [Sensor Troubleshooting Utility](../../8-reference/faq/troubleshooting.md#sensor-troubleshooting-utility). Needs sensor **4.33.6+**. | +| `-v` | `--verbose` | Enable verbose logging output. This is the same as `LC_VERBOSE=1`. | | `-V` | `--version` | Print the sensor build version and exit. | -| `-w` | `--service` | Run as a service. This is the form used by the OS service manager (SCM, launchd, systemd); you normally do not invoke it directly. | +| `-w` | `--service` | Run as a service. The OS service manager (SCM, launchd, systemd) uses this form. You do not usually start it directly. | | `-h` | `--help` | Print the list of accepted options. | ## Environment Variables -These environment variables are read by the sensor process. For installed -services, set them through your service manager (systemd unit, launchd plist, -or the Windows service environment) so the running service inherits them — see +The sensor process reads these environment variables. For installed services, +set the variables in your service manager (systemd unit, launchd plist, or the +Windows service environment). The running service then inherits them. For the +procedure for each platform, see [Setting Environment Variables for an Installed Service](#setting-environment-variables-for-an-installed-service) -below for the per-platform procedure. +below. ### Enrollment | Variable | Platforms | Description | |----------|-----------|-------------| -| `LC_INSTALLATION_KEY` | All | Installation key used when enrolling with `-d -` (or via packaged installers). Takes priority over the local key file. | +| `LC_INSTALLATION_KEY` | All | Installation key that the sensor uses when it enrolls with `-d -` or with a packaged installer. This variable has priority over the local key file. | ### Logging & Troubleshooting | Variable | Platforms | Description | |----------|-----------|-------------| -| `LC_VERBOSE` | All | Set to `1`/`true` to enable verbose logging (same effect as the `-v` flag). | -| `RPAL_LOG_LEVEL` | All | Sets the log verbosity. Accepted values: `off`, `error` (alias `critical`), `warning` (alias `warn`), `info`, `debug`. Defaults to `warning` in release builds. **In released sensors `warning` is the most verbose level that produces output — `info` and `debug` log statements are compiled out, so those values have no additional effect.** | -| `RPAL_LOG_FILE` | All | Path to a file to write logs to. Setting this is the opt-in for logging on a release sensor — output is written to the file at `RPAL_LOG_LEVEL` (`warning` and above). Without it, a release sensor stays silent unless `LC_VERBOSE` is set. The log can contain operational details about the host; treat it as potentially sensitive and remove it once you are done troubleshooting. | +| `LC_VERBOSE` | All | Set to `1`/`true` to enable verbose logging. This has the same effect as the `-v` flag. | +| `RPAL_LOG_LEVEL` | All | Sets the log verbosity. Accepted values: `off`, `error` (alias `critical`), `warning` (alias `warn`), `info`, `debug`. The default in release builds is `warning`. **In released sensors, `warning` is the most verbose level that gives output. The `info` and `debug` log statements are compiled out, so those values have no more effect.** | +| `RPAL_LOG_FILE` | All | Path of a file for the logs. This variable is the opt-in for logging on a release sensor. The sensor writes to the file at `RPAL_LOG_LEVEL` (`warning` and above). Without it, a release sensor writes nothing unless you set `LC_VERBOSE`. The log can contain operational details about the host. Treat the log as sensitive and delete it after you complete the troubleshooting. | See [Enabling Verbose and File Logging](../../8-reference/faq/troubleshooting.md#enabling-verbose-and-file-logging) -for usage examples. +for examples. ### Connectivity | Variable | Platforms | Description | |----------|-----------|-------------| -| `LC_PROXY` | All | Route the cloud connection through an HTTP CONNECT proxy (e.g. `proxy.corp.com:8080`). Special values: `-` (Windows registry auto-detect) and `!` (disable). See [Sensor Connectivity](../connectivity.md#proxy-tunneling). | -| `LC_LOCAL_CACHE_ONLY_REVOCATION_CHECK` | Windows | Set to `1`/`true` to make code-signature revocation checks (CRL/OCSP) use only the local cache and never reach out to the network. Useful on air-gapped or tightly restricted networks. | +| `LC_PROXY` | All | Send the cloud connection through an HTTP CONNECT proxy (for example `proxy.corp.com:8080`). Special values: `-` (Windows registry auto-detect) and `!` (disable). See [Sensor Connectivity](../connectivity.md#proxy-tunneling). | +| `LC_LOCAL_CACHE_ONLY_REVOCATION_CHECK` | Windows | Set to `1`/`true` to make the code-signature revocation checks (CRL/OCSP) use only the local cache and never use the network. This is useful on air-gapped networks and on networks with strict restrictions. | | `LC_DISABLE_REVERSE_DNS_HOSTNAME` | All | Set to `1`/`true` to skip reverse-DNS hostname resolution. See [Hostname Resolution](hostname-resolution.md). | ### Data & Collection | Variable | Platforms | Description | |----------|-----------|-------------| -| `LC_DATA_DIRECTORY` | All | Override the directory where the sensor stores its data and status files (default `/opt/limacharlie` on Linux, `/Library/Application Support/limacharlie` on macOS, `C:\ProgramData\limacharlie` on Windows). Useful on non-standard or hardened distributions where the default path is not writable. | -| `LC_DNS_IFACE` | Linux | Restrict DNS tracking to a single named network interface (e.g. `eth0`). When unset, all interfaces are watched. | -| `DISABLE_NETLINK` | Linux | Set to any value to skip the netlink (`CN_PROC`) process connector and fall back to `/proc` polling. No effect when eBPF is in use. See [Disabling Netlink](linux/installation.md#disabling-netlink). | -| `LC_MOD_LOAD_LOC` | Linux/macOS | Alternate directory for the sensor's temporary module-loading files, for hosts where the default location is restricted (e.g. SELinux). | -| `HOST_FS` | Linux/macOS | Path to the host root filesystem when the sensor runs inside a container. See [Docker installation](docker/installation.md). | -| `NET_NS` | Linux/macOS | Directory containing network namespaces (default `/var/run/docker/netns`) for namespace-aware network collection in containerized hosts. | +| `LC_DATA_DIRECTORY` | All | Change the directory where the sensor keeps its data files and status files (default `/opt/limacharlie` on Linux, `/Library/Application Support/limacharlie` on macOS, `C:\ProgramData\limacharlie` on Windows). This is useful on non-standard or hardened distributions where the sensor cannot write to the default path. | +| `LC_DNS_IFACE` | Linux | Limit DNS tracking to one named network interface (for example `eth0`). If you do not set this variable, the sensor watches all interfaces. | +| `DISABLE_NETLINK` | Linux | Set to any value to skip the netlink (`CN_PROC`) process connector and use `/proc` polling instead. It has no effect when the sensor uses eBPF. See [Disabling Netlink](linux/installation.md#disabling-netlink). | +| `LC_MOD_LOAD_LOC` | Linux/macOS | Different directory for the temporary module files of the sensor. Use it on hosts where the default location is restricted (for example by SELinux). | +| `HOST_FS` | Linux/macOS | Path of the host root filesystem when the sensor runs in a container. See [Docker installation](docker/installation.md). | +| `NET_NS` | Linux/macOS | Directory that contains the network namespaces (default `/var/run/docker/netns`). The sensor uses it for network collection with namespaces on hosts that run containers. | ### Upgrades | Variable | Platforms | Description | |----------|-----------|-------------| -| `LC_UPGRADE_SKIP_VERSION_CHECK` | All | **Advanced.** Set to `1`/`true` to skip the version comparison during an in-place upgrade (`-u`), forcing the binary to replace the installed service even when it is not newer. Use only when deliberately re-applying or downgrading a known-good build. | +| `LC_UPGRADE_SKIP_VERSION_CHECK` | All | **Advanced.** Set to `1`/`true` to skip the version comparison during an in-place upgrade (`-u`). The binary then replaces the installed service even when the binary is not newer. Use it only when you apply a known-good build again, or downgrade to one, on purpose. | ## Setting Environment Variables for an Installed Service -The variables above are read by the sensor process when it starts. When the -sensor runs as a managed service it inherits its environment from the service -manager, not from your interactive shell, so `export`-ing a variable in a -terminal has no effect on the running service. To make a variable take effect -you set it in the service manager and then restart the service so it is -re-spawned with the new environment. The procedure below is the same for any -variable in the tables above — substitute the variable name and value you need. +The sensor process reads the variables above when it starts. When the sensor +runs as a managed service, it inherits its environment from the service +manager, not from your interactive shell. An `export` command in a terminal has +no effect on the running service. + +To apply a variable, set it in the service manager and then restart the +service. The service manager then starts the service again with the new +environment. The procedure below is the same for each variable in the tables +above. Use the variable name and the value that you need. ### macOS (launchd) -The installed sensor runs as the launchd daemon `com.refractionpoint.rphcp`, -defined by `/Library/LaunchDaemons/com.refractionpoint.rphcp.plist`. Add an -`EnvironmentVariables` dictionary to that plist (launchd values are always -strings): +The installed sensor runs as the launchd daemon `com.refractionpoint.rphcp`. +The file `/Library/LaunchDaemons/com.refractionpoint.rphcp.plist` defines the +daemon. Add an `EnvironmentVariables` dictionary to that plist (launchd values +are always strings): ```xml EnvironmentVariables @@ -103,10 +107,10 @@ strings): ``` -Add more ``/`` pairs to the same `` to set additional -variables. Validate the edited file, then reload the daemon so launchd -re-reads it — the environment is applied only when the process is spawned, so a -running daemon will not pick up the change until it is restarted: +To set more variables, add more ``/`` pairs to the same ``. +launchd applies the environment only when it starts the process, so a daemon +that runs does not get the change before a restart. Check the edited file, then +load the daemon again: ```bash sudo plutil -lint /Library/LaunchDaemons/com.refractionpoint.rphcp.plist @@ -114,7 +118,7 @@ sudo launchctl bootout system /Library/LaunchDaemons/com.refractionpoint.rphcp.p sudo launchctl bootstrap system /Library/LaunchDaemons/com.refractionpoint.rphcp.plist ``` -Confirm the running service picked up the variable: +Confirm that the running service has the variable: ```bash sudo launchctl print system/com.refractionpoint.rphcp | grep -A 5 environment @@ -122,20 +126,21 @@ sudo launchctl print system/com.refractionpoint.rphcp | grep -A 5 environment Notes: -- **Test without editing the plist.** To apply a variable for the *next* launch - only, use `sudo launchctl debug system/com.refractionpoint.rphcp --environment LC_DISABLE_REVERSE_DNS_HOSTNAME=1` - followed by `sudo launchctl kickstart -k system/com.refractionpoint.rphcp`. - The setting is consumed on that single launch and is not persistent — useful - for confirming a variable's effect before committing it to the plist. -- **Managed fleets.** Reinstalling the sensor recreates the plist, so re-apply - the variable after a reinstall. On hosts managed by an MDM, set the variable - through the management channel so it is not reverted when the configuration - profile is re-applied. See [MDM Profiles](macos/mdm-profiles.md). +- **Test without an edit to the plist.** To apply a variable for the *next* + launch only, use `sudo launchctl debug system/com.refractionpoint.rphcp --environment LC_DISABLE_REVERSE_DNS_HOSTNAME=1` + and then `sudo launchctl kickstart -k system/com.refractionpoint.rphcp`. + The setting applies to that one launch and is not persistent. Use it to + confirm the effect of a variable before you write it to the plist. +- **Managed fleets.** A new installation of the sensor creates the plist again, + so set the variable again after each reinstallation. On hosts that an MDM + manages, set the variable through the management channel. The variable then + stays when the MDM applies the configuration profile again. See + [MDM Profiles](macos/mdm-profiles.md). ### Linux (systemd) -The installed sensor runs as the `limacharlie` systemd unit. Add an environment -drop-in rather than editing the packaged unit file: +The installed sensor runs as the `limacharlie` systemd unit. Do not edit the +packaged unit file. Add an environment drop-in: ```bash sudo systemctl edit limacharlie @@ -148,17 +153,17 @@ In the editor that opens, add: Environment=LC_DISABLE_REVERSE_DNS_HOSTNAME=1 ``` -This writes `/etc/systemd/system/limacharlie.service.d/override.conf`. Apply it -by restarting the service: +This writes `/etc/systemd/system/limacharlie.service.d/override.conf`. To apply +it, restart the service: ```bash sudo systemctl restart limacharlie ``` -`systemctl edit` reloads the systemd daemon for you; if you create or edit the -drop-in file by hand, run `sudo systemctl daemon-reload` first. On hosts that +`systemctl edit` reloads the systemd daemon for you. If you create or edit the +drop-in file manually, run `sudo systemctl daemon-reload` first. On hosts that use a System V init service instead of systemd, export the variable from the -init script's environment. Verify the running process: +environment of the init script. Check the running process: ```bash sudo cat /proc/"$(pgrep -x rphcp)"/environ | tr '\0' '\n' | grep '^LC_' @@ -169,16 +174,16 @@ sudo cat /proc/"$(pgrep -x rphcp)"/environ | tr '\0' '\n' | grep '^LC_' The installed sensor runs as the `rphcpsvc` service. Set the variable in one of two ways, then restart the service: -- **Machine-wide (simplest):** `setx /M LC_DISABLE_REVERSE_DNS_HOSTNAME 1` (run - from an elevated prompt). This adds the variable to the system environment - that every service and new process inherits. +- **Machine-wide (simplest):** run `setx /M LC_DISABLE_REVERSE_DNS_HOSTNAME 1` + from an elevated prompt. This adds the variable to the system environment + that every service and every new process inherits. - **Scoped to the sensor service:** add a `REG_MULTI_SZ` value named `Environment` under `HKLM\SYSTEM\CurrentControlSet\Services\rphcpsvc`, with one `NAME=value` - entry per line. The Service Control Manager merges these into the service's - environment only, leaving the rest of the host untouched. + entry for each line. The Service Control Manager merges these entries into + the environment of the service only. The rest of the host does not change. -Restart the service so it is re-spawned with the new environment: +Restart the service. It then starts with the new environment: ```powershell Restart-Service rphcpsvc @@ -188,16 +193,16 @@ Restart-Service rphcpsvc | File | Default location | Purpose | |------|------------------|---------| -| `lc_installation_key.txt` | Current working directory | Optional source of the installation key when using `-d -`. | -| `hcp`, `hcp_hbs`, `hcp_conf` | `/etc` (Linux), `/usr/local` (macOS), `C:\Windows\System32` (Windows) | Identity and configuration files written at install time. Removed by `-c`; left in place by `-r`. | -| `hcp_vdi` / `hcp_vdi.dat` | `/etc` or CWD (Linux), `/usr/local` (macOS), `C:\Windows\System32` (Windows) | VDI delay file holding the epoch timestamp until which enrollment is postponed. See [VDI Templates](vdi/templates.md). | +| `lc_installation_key.txt` | Current working directory | Optional source of the installation key when you use `-d -`. | +| `hcp`, `hcp_hbs`, `hcp_conf` | `/etc` (Linux), `/usr/local` (macOS), `C:\Windows\System32` (Windows) | Identity and configuration files that the installer writes. `-c` deletes them; `-r` keeps them. | +| `hcp_vdi` / `hcp_vdi.dat` | `/etc` or CWD (Linux), `/usr/local` (macOS), `C:\Windows\System32` (Windows) | VDI delay file. It holds the epoch timestamp until which the sensor delays enrollment. See [VDI Templates](vdi/templates.md). | | `hcp.log` | `./hcp.log` (Linux), `/usr/local/hcp.log` (macOS), `C:\Windows\System32\hcp.log` (Windows) | First-connection connectivity log. See [Sensor Not Connecting](../../8-reference/faq/troubleshooting.md#sensor-not-connecting). | -| `hcp_hbs_status.json` | Sensor data directory (see `LC_DATA_DIRECTORY`) | Local status file with sensor ID, org ID, version, and uptime. | +| `hcp_hbs_status.json` | Sensor data directory (see `LC_DATA_DIRECTORY`) | Local status file with the sensor ID, the org ID, the version, and the uptime. | | `sensor_health_YYYY_MM_DD_HH_MM.json` | Sensor data directory (see `LC_DATA_DIRECTORY`) | Output of the `-H` health check. | ## Installation Key Sources -When `-i`/`-d` is given `-` instead of a literal key, the sensor looks for the +If you give `-` to `-i`/`-d` instead of a literal key, the sensor looks for the installation key in this order: 1. The `LC_INSTALLATION_KEY` environment variable. diff --git a/docs/2-sensors-deployment/endpoint-agent/containers/clusters.md b/docs/2-sensors-deployment/endpoint-agent/containers/clusters.md index daf590c4c..d42c33d1a 100644 --- a/docs/2-sensors-deployment/endpoint-agent/containers/clusters.md +++ b/docs/2-sensors-deployment/endpoint-agent/containers/clusters.md @@ -1,20 +1,20 @@ # Container Clusters -You can run LimaCharlie at the host level in a container cluster system like Kubernetes in order to monitor all running containers on the host with a single Sensor. This is the preferred method as it reduces the overhead of running LC within every single container. +You can run LimaCharlie at the host level in a container cluster system such as Kubernetes. One sensor then monitors all the containers that run on the host. This is the preferred method because it reduces the overhead of LC in each container. -This is accomplished by a combination of a few techniques: +A combination of techniques makes this possible: -1. A privileged container running LC. -2. LC runs with the `HOST_FS` environment variable pointing to the host's root filesystem mounted within the container. -3. LC runs with the `NET_NS` environment variable pointing to the host's directory listing network namespaces. -4. Running the container with the required flags and mounts to make sure it can have proper access. +1. A privileged container that runs LC. +2. LC runs with the `HOST_FS` environment variable set to the host root filesystem that is mounted in the container. +3. LC runs with the `NET_NS` environment variable set to the host directory that lists the network namespaces. +4. The container runs with the flags and mounts that give it the necessary access. ## Building the Container Image -Build your own sensor image and push it to a registry your cluster nodes can pull from. Building the image yourself guarantees you get the latest sensor version and lets you control the base distribution. +Build your own sensor image and push it to a registry that your cluster nodes can pull from. When you build the image yourself, you get the latest sensor version and you control the base distribution. !!! warning "eBPF requires a glibc-based image" - Kernel-level telemetry on Linux is delivered by an eBPF component that is only available for **glibc-based x64 sensors**. The `alpine64` (musl) sensor build does **not** receive the eBPF component and will always operate in usermode acquisition. If you want kernel-level visibility (real-time process, file, network and DNS events from eBPF), your container must use a glibc-based distribution (Debian, Ubuntu, RHEL/Rocky, etc.) with the `linux/64` sensor binary — do not use Alpine. + An eBPF component supplies the kernel-level telemetry on Linux, and this component is available only for **glibc-based x64 sensors**. The `alpine64` (musl) sensor build does **not** get the eBPF component and always operates in usermode acquisition. Do not use Alpine if you want kernel-level visibility (real-time process, file, network and DNS events from eBPF). Your container must use a glibc-based distribution (Debian, Ubuntu, RHEL/Rocky, etc.) with the `linux/64` sensor binary. This is a sample `Dockerfile` for a glibc-based sensor container: @@ -41,11 +41,11 @@ ENV NET_NS=/netns CMD ["./lc_sensor", "-d", "-"] ``` -Rebuild this image regularly (or on a schedule in your CI) so new deployments pick up the latest sensor version, and use a unique image tag per build — reusing a tag combined with a non-`Always` image pull policy can leave nodes running a stale cached image. +Build this image again at regular intervals, or on a schedule in your CI, so that new deployments get the latest sensor version. Use a unique image tag for each build. If you use a tag again with an image pull policy that is not `Always`, the nodes can keep an old cached image. ## Plain Docker -On a host running dockerd, start the container like: +On a host that runs dockerd, start the container like this: ```bash docker run --privileged --net=host \ @@ -57,20 +57,20 @@ docker run --privileged --net=host \ your-registry.example.com/lc-sensor:your-tag ``` -Note that `/var/run/docker/netns` is specific to dockerd. On hosts using containerd with CNI (including most managed Kubernetes node images), the network namespaces directory is `/var/run/netns` instead. +The path `/var/run/docker/netns` applies to dockerd only. On hosts that use containerd with CNI, including most managed Kubernetes node images, the directory of the network namespaces is `/var/run/netns`. ## Kubernetes DaemonSet (eBPF) -The recommended deployment on Kubernetes is a `DaemonSet` so that one sensor runs on every node. The manifest below is suitable for clusters with modern kernels (5.8+) supporting eBPF, and has been validated on GKE. +The recommended deployment on Kubernetes is a `DaemonSet`, so that one sensor runs on each node. The manifest below is for clusters with kernels 5.8 and later that support eBPF. The manifest is validated on GKE. -Requirements for the eBPF path, all handled by the manifest below: +The eBPF path needs these items. The manifest below supplies all of them: - A **glibc-based** sensor image (see above). - `privileged: true`, `hostPID: true` and `hostNetwork: true`. -- Kernel BTF (`/sys/kernel/btf/vmlinux`), i.e. a kernel built with `CONFIG_DEBUG_INFO_BTF`. All modern mainstream distributions and managed-Kubernetes node images ship this. -- The host's `/sys/kernel/debug` (debugfs/tracefs) mounted into the container. This one matters: debugfs and tracefs are separate filesystems that are **not** visible through the container's own `/sys` mount, and the eBPF loader needs tracefs to attach tracepoints. Without this mount the sensor silently falls back to usermode acquisition. +- Kernel BTF (`/sys/kernel/btf/vmlinux`), that is, a kernel built with `CONFIG_DEBUG_INFO_BTF`. All current mainstream distributions and managed-Kubernetes node images include it. +- The `/sys/kernel/debug` directory of the host (debugfs/tracefs), mounted into the container. This item is important: debugfs and tracefs are separate filesystems that are **not** visible through the `/sys` mount of the container, and the eBPF loader needs tracefs to attach tracepoints. Without this mount, the sensor changes to usermode acquisition and gives no message. -First, create the namespace and store your installation key in a secret (avoid committing the key to source control): +First, create the namespace and put your installation key in a secret. Do not commit the key to source control: ```bash kubectl create namespace lc-monitoring @@ -178,7 +178,7 @@ spec: ### Scheduling on tightly-packed nodes -Cluster autoscalers that optimize for utilization can leave nodes with almost no unallocated CPU, preventing the DaemonSet pod from scheduling there. The fix is to give the sensor a `PriorityClass` with a high value so it can preempt lower-priority workloads: +Cluster autoscalers that optimize utilization can leave nodes with almost no unallocated CPU. The DaemonSet pod cannot then schedule on those nodes. To correct this, give the sensor a `PriorityClass` with a high value. The sensor can then preempt workloads that have a lower priority: ```yaml apiVersion: scheduling.k8s.io/v1 @@ -193,39 +193,39 @@ description: "Host-level security monitoring agents." Then add `priorityClassName: node-monitoring-critical` to the DaemonSet pod spec. !!! note - Do not use the built-in `system-node-critical` / `system-cluster-critical` classes: on GKE (and other managed platforms) they are restricted by resource quota to the `kube-system` namespace, and pod creation will fail with a `FailedCreate` quota error. + Do not use the built-in `system-node-critical` or `system-cluster-critical` classes. On GKE and other managed platforms, a resource quota restricts them to the `kube-system` namespace, and pod creation fails with a `FailedCreate` quota error. ### Sensor identity lifecycle -The sensor stores its identity inside the container filesystem, which is ephemeral: every pod start (node reboot, DaemonSet update, pod eviction) enrolls as a **new** sensor with a new SID. This is the expected behavior for elastic node fleets — old registrations simply go offline. Use the [Sensor Cull extension](../../../5-integrations/extensions/limacharlie/sensor-cull.md) to automatically clean up stale registrations, and make sure your sensor quota accommodates the number of concurrently online nodes. +The sensor keeps its identity in the container filesystem, which is ephemeral. Each pod start (node reboot, DaemonSet update, pod eviction) enrolls a **new** sensor with a new SID. This is the expected behavior for elastic node fleets, and the old registrations go offline. Use the [Sensor Cull extension](../../../5-integrations/extensions/limacharlie/sensor-cull.md) to delete the old registrations automatically. Make sure that your sensor quota is large enough for the number of nodes that are online at the same time. ## Google Kubernetes Engine (GKE) -The manifest above works as-is on **GKE Standard** clusters and has been validated end-to-end (sensors enroll and report kernel/eBPF acquisition active): +The manifest above works without changes on **GKE Standard** clusters, and it is validated end-to-end (the sensors enroll and report that kernel/eBPF acquisition is active): -- Default node images (Container-Optimized OS and Ubuntu, containerd runtime) ship kernels with BTF enabled and debugfs mounted on the host, satisfying the eBPF requirements. -- GKE nodes use containerd, so the network namespaces hostPath is `/var/run/netns` as in the manifest above (not the dockerd path shown in some older examples). -- If your cluster uses the `optimize-utilization` autoscaling profile, add the custom `PriorityClass` described above or some nodes may never schedule the sensor. +- The default node images (Container-Optimized OS and Ubuntu, containerd runtime) have kernels with BTF enabled and debugfs mounted on the host. They obey the eBPF requirements. +- GKE nodes use containerd, so the network namespaces hostPath is `/var/run/netns`, as in the manifest above. It is not the dockerd path that some older examples show. +- If your cluster uses the `optimize-utilization` autoscaling profile, add the custom `PriorityClass` above. Without it, some nodes can fail to schedule the sensor. !!! warning "GKE Autopilot is not supported" - Autopilot clusters reject privileged containers, `hostPath` volumes, `hostPID` and `hostNetwork`, all of which are required for host-level monitoring. Deploy on GKE Standard. + Deploy on GKE Standard. Autopilot clusters reject privileged containers, `hostPath` volumes, `hostPID`, and `hostNetwork`, and host-level monitoring needs all of them. -Nodes running gVisor-sandboxed pods (GKE Sandbox) can run the sensor, but activity inside the sandboxed pods is executed by the gVisor user-space kernel and is largely invisible to host-level kernel telemetry. +Nodes that run gVisor-sandboxed pods (GKE Sandbox) can run the sensor. But the gVisor user-space kernel executes the activity in the sandboxed pods, and host-level kernel telemetry cannot see most of that activity. ## Verifying eBPF is active -After deployment, verify that sensors are using kernel-level (eBPF) acquisition and not the usermode fallback: +After deployment, check that the sensors use kernel-level (eBPF) acquisition and not the usermode fallback: -- In the web app, the sensor details show whether kernel acquisition is available. -- Via the API/SDK, the sensor information includes `is_kernel_available: true`. +- In the web app, the sensor details show if kernel acquisition is available. +- In the API/SDK, the sensor information includes `is_kernel_available: true`. - Sensor selector expressions can filter on it: `plat == linux and kernel == true`. -If `is_kernel_available` is false on a Linux deployment, the usual causes are: an Alpine-based image (no eBPF support), a missing `/sys/kernel/debug` mount, a kernel without BTF, or a non-privileged container. +If `is_kernel_available` is false on a Linux deployment, these are the usual causes: an Alpine-based image (no eBPF support), a missing `/sys/kernel/debug` mount, a kernel without BTF, or a container that is not privileged. ## Kubernetes DaemonSet (no eBPF) -For clusters with older kernels (before 5.8) or where the eBPF prerequisites cannot be met, deploy the same DaemonSet without the `/sys/kernel/debug`, `/sys/kernel/btf` and `/lib/modules` mounts. The sensor will automatically operate in usermode acquisition (process events via the kernel's process-events netlink connector, plus periodic state snapshots); `privileged`, `hostPID`, `hostNetwork` and the `HOST_FS` / `NET_NS` mounts are still required for host-level visibility. +For clusters with older kernels (before 5.8), or clusters that cannot obey the eBPF prerequisites, deploy the same DaemonSet without the `/sys/kernel/debug`, `/sys/kernel/btf` and `/lib/modules` mounts. The sensor then operates in usermode acquisition automatically. It gets the process events from the process-events netlink connector of the kernel, plus periodic state snapshots. Host-level visibility still needs `privileged`, `hostPID`, `hostNetwork` and the `HOST_FS` / `NET_NS` mounts. ## SELinux -On some hardened versions of Linux, certain file paths are prevented from loading `.so` (Shared Object) files. LimaCharlie requires a location where it can write `.so` files and load them. To enable this on hardened versions of Linux, you can specify a `LC_MOD_LOAD_LOC` environment variable containing a path to a valid directory for loading, like `/lc` for example. This environment variable needs to be set for the sensor executable (`rphcp`) at runtime. +On some hardened versions of Linux, some file paths cannot load `.so` (Shared Object) files. LimaCharlie needs a location where it can write `.so` files and load them. On these versions of Linux, set the `LC_MOD_LOAD_LOC` environment variable to the path of a directory that permits loading, for example `/lc`. Set this environment variable for the sensor executable (`rphcp`) at runtime. diff --git a/docs/2-sensors-deployment/endpoint-agent/docker/installation.md b/docs/2-sensors-deployment/endpoint-agent/docker/installation.md index e6364f3e8..5cb442975 100644 --- a/docs/2-sensors-deployment/endpoint-agent/docker/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/docker/installation.md @@ -2,24 +2,24 @@ ## Docker -The LimaCharlie agent is designed to run within a Docker container, providing seamless integration with containerized environments. Running the agent in a container allows for efficient deployment and management while ensuring security monitoring and telemetry collection. +The LimaCharlie agent can run in a Docker container and integrates with container environments. In a container, the agent is efficient to deploy and to manage, and it continues to do security monitoring and telemetry collection. -Additionally, the agent can also be deployed on various container cluster technologies, such as Kubernetes. For Kubernetes deployment details, refer to [Container Clusters](../containers/clusters.md). +You can also deploy the agent on container cluster technologies such as Kubernetes. For the Kubernetes deployment details, see [Container Clusters](../containers/clusters.md). ## Host Visibility Requirements -For the LimaCharlie agent to have full visibility into activities on the host system, the following configurations are required: +The LimaCharlie agent needs these configurations for full visibility of the activity on the host system: - The container must run in **privileged mode** to access host-level resources. -- The container must use **host networking** to observe network activity. -- The container must use **host PID mode** to track running processes. -- Various **host-level directories** must be mounted into the container, including: +- The container must use **host networking** to see network activity. +- The container must use **host PID mode** to track the processes that run. +- You must mount **host-level directories** into the container. These include: - The root filesystem (`rootfs`) - Docker network namespaces (`netns`) - - The directory containing kernel modules and debug symbols + - The directory that contains the kernel modules and the debug symbols -Additionally, on newer Linux kernel versions (5.7+), the agent leverages **eBPF** for enhanced visibility and telemetry collection. +On newer Linux kernel versions (5.7+), the agent also uses **eBPF** for more visibility and telemetry collection. ## Agent Docker Image @@ -48,24 +48,24 @@ ENV NET_NS=/netns CMD ["./lc_sensor", "-d", "-"] ``` -Rebuild the image regularly so new deployments pick up the latest agent version. +Build the image again at regular intervals so that new deployments get the latest agent version. !!! warning "eBPF requires a glibc-based image" - Kernel-level telemetry on Linux is only available for **glibc-based x64 sensors** (Debian, Ubuntu, RHEL/Rocky, etc.). An Alpine (musl) based image using the `alpine64` sensor binary will always operate in usermode acquisition, without eBPF kernel visibility. + Kernel-level telemetry on Linux is available only for **glibc-based x64 sensors** (Debian, Ubuntu, RHEL/Rocky, etc.). An Alpine (musl) image with the `alpine64` sensor binary always operates in usermode acquisition, without eBPF kernel visibility. ## Available Environment Variables -The agent supports several environment variables to control its behavior: +The agent supports several environment variables that control its behavior: -- `LC_INSTALLATION_KEY` - Specifies the installation key required to authenticate the agent. -- `HOST_FS` - Defines the path where the host's root filesystem is mounted within the container. Example: `/rootfs`. -- `NET_NS` - Specifies the path to the host's network namespace directory. Example: `/netns`. +- `LC_INSTALLATION_KEY` - Gives the installation key that authenticates the agent. +- `HOST_FS` - Gives the path where the host root filesystem is mounted in the container. Example: `/rootfs`. +- `NET_NS` - Gives the path of the host network namespace directory. Example: `/netns`. -These variables must be configured appropriately to ensure the agent functions as expected. +Set these variables correctly to make sure that the agent operates as expected. ## Running the Agent Using Docker CLI -To run the LimaCharlie agent in a Docker container, use the following command: +To run the LimaCharlie agent in a Docker container, use this command: ```bash docker run --privileged --net=host \ @@ -80,11 +80,11 @@ docker run --privileged --net=host \ your-registry.example.com/lc-sensor:your-tag ``` -Ensure that you replace `` with your actual LimaCharlie installation key. +Replace `` with your LimaCharlie installation key. ## Running the Agent Using Docker Compose -You can also manage the LimaCharlie agent using Docker Compose. Below is a sample `docker-compose.yml` file: +You can also manage the LimaCharlie agent with Docker Compose. This is a sample `docker-compose.yml` file: ```yaml services: @@ -122,4 +122,4 @@ To start the container, run: docker-compose up -d ``` -This setup ensures the agent runs as a privileged container, enabling full visibility into the host system while being managed through Docker Compose. +With this setup, the agent runs as a privileged container and has full visibility of the host system. Docker Compose manages the container. diff --git a/docs/2-sensors-deployment/endpoint-agent/edge/installation.md b/docs/2-sensors-deployment/endpoint-agent/edge/installation.md index 042ecb1a8..cd9d50cac 100644 --- a/docs/2-sensors-deployment/endpoint-agent/edge/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/edge/installation.md @@ -1,11 +1,13 @@ # Edge Agent Installation -LimaCharlie's Edge Sensor is delivered as the [LimaCharlie Sensor](https://microsoftedge.microsoft.com/addons/detail/limacharlie-sensor/nomgmkpkkncolnpbkbamfnjhbhmnjehp) extension, available as an Edge Add-on. +LimaCharlie supplies the Edge sensor as the [LimaCharlie Sensor](https://microsoftedge.microsoft.com/addons/detail/limacharlie-sensor/nomgmkpkkncolnpbkbamfnjhbhmnjehp) extension, an Edge Add-on. ## Edge Installation Instructions The Edge sensor is available in the Edge Add-ons section. -1. In the LimaCharlie web app (app.limacharlie.io), go to the "Installation Keys" section, select your Installation Key and click the "Chrome Key" copy icon to copy the key to your clipboard. -2. Install the sensor from: -3. A new tab will open where you can add your installation key from before. +1. In the LimaCharlie web app (app.limacharlie.io), go to the "Installation Keys" section. +2. Select your installation key. +3. Click the "Chrome Key" copy icon. The web app copies the key to your clipboard. +4. Install the sensor from: +5. In the new tab that opens, enter the installation key from step 3. diff --git a/docs/2-sensors-deployment/endpoint-agent/hostname-resolution.md b/docs/2-sensors-deployment/endpoint-agent/hostname-resolution.md index 24fe5690f..cdc165aa6 100644 --- a/docs/2-sensors-deployment/endpoint-agent/hostname-resolution.md +++ b/docs/2-sensors-deployment/endpoint-agent/hostname-resolution.md @@ -1,24 +1,24 @@ # Hostname Resolution -The Endpoint Agent reports its hostname to the LimaCharlie cloud where it shows up as the `hostname` field for the Sensor. +The Endpoint Agent reports its hostname to the LimaCharlie cloud, where it shows in the `hostname` field for the Sensor. -The resolution of that hostname is done in a few different ways: +The Endpoint Agent resolves that hostname in these steps: -1. The main local interface is detected by looking for the route to `8.8.8.8`. -2. A `getnameinfo()` with `NI_NAMEREQD` is performed to resolve the FQDN of the box. -3. If the above hostname resolved is valid (no failure, and it is not equal to the static hostname of a few VPN and virtualization providers), this is the hostname we use. -4. If the FQDN could not be resolved, the local hostname of the box is used. +1. The Endpoint Agent finds the main local interface. It looks for the route to `8.8.8.8`. +2. The Endpoint Agent calls `getnameinfo()` with `NI_NAMEREQD` to resolve the FQDN of the box. +3. If that hostname is valid, the Endpoint Agent uses it. The hostname is valid if the call does not fail, and if the hostname is not the static hostname of one of a few VPN and virtualization providers. +4. If the Endpoint Agent cannot resolve the FQDN, it uses the local hostname of the box. -This method allows the endpoint agent to better resolve its hostname in large environments where different regions re-use the same hostname. +This method helps the Endpoint Agent to resolve its hostname in large environments where different regions use the same hostname. ## Disabling Reverse DNS Resolution -In some environments the reverse DNS lookup is undesirable (for example, when it is slow, unreliable, or returns a hostname that is not meaningful for the deployment). The reverse DNS step can be disabled by setting the following environment variable on the host before the Endpoint Agent starts: +In some environments, the reverse DNS lookup is not wanted. For example, the lookup is slow, or it is unreliable, or it gives a hostname that has no meaning for the deployment. To disable the reverse DNS step, set this environment variable on the host before the Endpoint Agent starts: ```text LC_DISABLE_REVERSE_DNS_HOSTNAME=1 ``` -The variable must be explicitly set to `1` or `true` (case-insensitive) — simply defining the variable with an empty or other value is not enough and will be treated as disabled. When enabled, the agent skips steps 2 and 3 above and directly uses the local hostname of the box (step 4). +Set the variable to `1` or `true` (case-insensitive). A variable with an empty value or a different value is not enough, and the Endpoint Agent treats it as disabled. When the variable is enabled, the Endpoint Agent skips steps 2 and 3 above and uses the local hostname of the box (step 4). -For a sensor that is already installed and running as a service, set the variable through the service manager (launchd plist, systemd unit, or the Windows service) and restart the service. See [Setting Environment Variables for an Installed Service](cli-reference.md#setting-environment-variables-for-an-installed-service) for the per-platform procedure. +For an Endpoint Agent that is installed and runs as a service, set the variable in the service manager (launchd plist, systemd unit, or the Windows service). Then restart the service. For the procedure for each platform, see [Setting Environment Variables for an Installed Service](cli-reference.md#setting-environment-variables-for-an-installed-service). diff --git a/docs/2-sensors-deployment/endpoint-agent/linux/installation.md b/docs/2-sensors-deployment/endpoint-agent/linux/installation.md index 14f9a55b0..9cd77735d 100644 --- a/docs/2-sensors-deployment/endpoint-agent/linux/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/linux/installation.md @@ -1,44 +1,44 @@ # Linux Agent Installation -The LimaCharlie Linux Sensor runs on every mainstream Linux distribution and architecture (x86_64, i386, ARM64, Alpine/musl). It is shipped as a single binary that adapts at runtime to the kernel features available on the host — there is no separate build or installer per mode. On modern kernels it uses eBPF for in-kernel telemetry; on older kernels it transparently falls back to lighter mechanisms. +The LimaCharlie Linux Sensor runs on every mainstream Linux distribution and architecture (x86_64, i386, ARM64, Alpine/musl). LimaCharlie ships it as one binary. The binary adapts at run time to the kernel features that the host supplies, so there is no separate build or installer for each mode. On modern kernels, the sensor uses eBPF for in-kernel telemetry. On older kernels, it falls back to lighter mechanisms. ## Linux Distribution Support -The agent is regularly tested against current Debian, Ubuntu, CentOS/RHEL/Rocky/Alma, Amazon Linux, and Alpine releases on x86_64 and ARM64. Because of the diversity of the Linux ecosystem it usually runs unmodified on other distributions as well — if you need to validate a specific platform, contact us. +LimaCharlie tests the sensor against current Debian, Ubuntu, CentOS/RHEL/Rocky/Alma, Amazon Linux, and Alpine releases on x86_64 and ARM64. Linux distributions differ, but the sensor usually runs on other distributions without changes. To validate a specific platform, contact LimaCharlie. ### Kernel Feature Tiers -The agent picks the most capable acquisition mode supported by the host kernel and degrades gracefully when newer features are not available. All tiers run **the same binary** — selection happens at startup. +The sensor picks the best acquisition mode that the host kernel supports. If newer features are not available, the sensor uses a lower mode. All tiers run **the same binary**. The sensor makes the selection at startup. | Tier | Minimum kernel | Acquisition path | What you get | |------|----------------|------------------|--------------| -| User-mode only | any (incl. 2.4 / 2.6 era) | `/proc` polling | Inventory of running processes, host metadata, live response, file integrity, USB monitoring, YARA scans, network isolation, and all detection-and-response features that operate from user space. **No real-time process / file / network / DNS kernel events.** | -| User-mode + netlink connector | 2.6.15 | `/proc` polling + netlink `CN_PROC` connector | Adds real-time process create / exit notifications from the kernel. Process command-line and executable path are still scraped post-event from `/proc`, so very short-lived processes can be missed. | -| User-mode + eBPF (default when available) | 5.7+ recommended | eBPF programs (CO-RE / BTF) attached for processes, files, network, DNS | Full in-kernel telemetry: process exec with reliable cmdline capture, file I/O, TCP / UDP connections, DNS queries — collected synchronously and attributed to the originating task. This is the mode used on supported modern systems. | +| User-mode only | any (incl. 2.4 / 2.6 era) | `/proc` polling | Inventory of running processes, host metadata, live response, file integrity, USB monitoring, YARA scans, network isolation, and all detection-and-response features that work from user space. **No real-time process / file / network / DNS kernel events.** | +| User-mode + netlink connector | 2.6.15 | `/proc` polling + netlink `CN_PROC` connector | Adds real-time process create / exit notifications from the kernel. The sensor still reads the process command line and executable path from `/proc` after the event, so a process with a very short life can be missed. | +| User-mode + eBPF (default when available) | 5.7+ recommended | eBPF programs (CO-RE / BTF) attached for processes, files, network, DNS | Full in-kernel telemetry: process exec with reliable cmdline capture, file I/O, TCP / UDP connections, and DNS queries. The sensor collects these synchronously and attributes them to the task that caused them. Modern supported systems use this mode. | -The agent does **not** require eBPF, kernel headers, or `bpftool` to be installed on the target host — the eBPF programs are pre-compiled into the binary and loaded via libbpf using BTF when the kernel exposes it (`/sys/kernel/btf/vmlinux`). On kernels without BTF / CO-RE the agent automatically remains in the netlink or user-mode tier. +The sensor does **not** need eBPF, kernel headers, or `bpftool` on the target host. The eBPF programs are pre-compiled into the binary. libbpf loads them with BTF when the kernel exposes it (`/sys/kernel/btf/vmlinux`). On kernels without BTF / CO-RE, the sensor stays in the netlink or user-mode tier. -Use `uname -r` to check the host kernel version. If it is below 5.4, expect the agent to run in netlink (2.6.15+) or user-mode-only (anything older) tier with reduced kernel telemetry but full agent control-plane functionality. +Use `uname -r` to check the host kernel version. If the version is below 5.4, the sensor runs in the netlink tier (2.6.15+) or in the user-mode-only tier (older kernels). These tiers give less kernel telemetry, but the full control plane of the sensor still works. ### Forcing a lower tier -The agent exposes one runtime override for compatibility scenarios (the eBPF tier has no opt-out — it is selected only when the kernel actually supports it): +The sensor has one run-time override for compatibility. The eBPF tier has no opt-out, because the sensor selects it only when the kernel supports it. -- `DISABLE_NETLINK` — set to any value in the sensor process environment to skip the netlink connector. Used when an unrelated component on the host already consumes netlink proc events or when the connector behaves unexpectedly. Has no effect when eBPF is in use. +- `DISABLE_NETLINK` — set this to any value in the environment of the sensor process to skip the netlink connector. Use it when another component on the host already consumes netlink proc events, or when the connector does not behave correctly. It has no effect when the sensor uses eBPF. ## Installation Instructions ### System Requirements -The agent runs on glibc-based distributions back to glibc 2.17 (RHEL 7 / CentOS 7 / Debian 8 era and newer). For older or non-glibc systems use the **Alpine / musl** build, which is statically linked and has no host libc dependency. Older distributions like RHEL 5 / 6 are not supported by the standard glibc build because of the libc baseline; the musl build can be evaluated for those cases but kernel telemetry will be limited to whatever the host kernel exposes (see the tier table above). +The sensor runs on glibc distributions back to glibc 2.17 (RHEL 7 / CentOS 7 / Debian 8 and newer). For older systems, or for systems without glibc, use the **Alpine / musl** build. This build is statically linked and does not depend on the host libc. The standard glibc build does not support older distributions such as RHEL 5 / 6, because of the libc baseline. You can evaluate the musl build for those systems, but the kernel telemetry is limited to what the host kernel exposes. See the tier table above. ### Deb Package -If you are deploying on a Debian Linux system, we recommend using the `.deb` package. You can find a link to the Debian package for various architectures at [Downloading the Agent](../../index.md). +On a Debian Linux system, use the `.deb` package. [Downloading the Agent](../../index.md) gives a link to the Debian package for each architecture. -The deb package will install the LimaCharlie sensor using a `systemd` service, or if unavailable a `system V` service. +The deb package installs the LimaCharlie sensor as a `systemd` service. If `systemd` is not available, it installs a `system V` service. -The Installation Key is required by the installer via the `debconf` configuration mechanism. By default, installing the package interactively will request the installation key via a local command/GUI interface. To perform large scale installations, we recommend setting the installation key programmatically. +The installer needs the Installation Key through the `debconf` configuration mechanism. By default, an interactive install requests the installation key through a local command or GUI interface. For large installations, set the installation key programmatically. **Installing interactively:** @@ -76,23 +76,23 @@ echo "limacharlie limacharlie/installation_key string INSTALLATION_KEY_HERE" | s echo "limacharlie limacharlie/installation_key string INSTALLATION_KEY_HERE" | sudo debconf-set-selections && sudo apt install ./limacharlie.deb -y ``` -Debian packages are offered for the various architectures the Linux sensor supports, like: +LimaCharlie supplies Debian packages for the architectures that the Linux sensor supports, like: - **x64**: - **arm64**: ### RPM Package -If you are deploying on an RPM-based Linux distribution (RHEL, CentOS, Rocky, AlmaLinux, Fedora, openSUSE, Amazon Linux), use the `.rpm` package. +On an RPM-based Linux distribution (RHEL, CentOS, Rocky, AlmaLinux, Fedora, openSUSE, Amazon Linux), use the `.rpm` package. -The rpm package will install the LimaCharlie sensor as a `systemd` service. +The rpm package installs the LimaCharlie sensor as a `systemd` service. -Unlike the `.deb` package, RPM has no native interactive prompt mechanism — the installation key cannot be requested at install time. Instead, the post-install scriptlet looks for the key in one of two locations, in this order: +RPM has no interactive prompt mechanism, unlike the `.deb` package, and cannot request the installation key at install time. The post-install scriptlet looks for the key in two locations, in this order: 1. The `LC_INSTALLATION_KEY` environment variable. 2. The file `/etc/limacharlie/installation_key`. -If neither is present the package install will abort with an explanatory error before any system state is changed, so a missing key never leaves the host in a half-configured state. +If the key is in neither location, the package install stops with an error that explains the cause. The install changes no system state before it stops, so a missing key never leaves the host partly configured. **Installing with the environment variable:** @@ -115,7 +115,7 @@ sudo chmod 600 /etc/limacharlie/installation_key sudo rpm -i limacharlie.rpm ``` -The key file is read once during install. You can delete it afterwards if you don't want the key sitting on disk — the sensor's own enrollment files take over from there. +The install reads the key file one time. You can delete the file after the install to keep the key off the disk. The sensor then uses its own enrollment files. **Uninstalling:** @@ -129,16 +129,16 @@ or sudo dnf remove limacharlie ``` -Uninstall stops the service and removes the sensor binary, identity files, and the package staging directory. +The uninstall stops the service and removes the sensor binary, the identity files, and the package staging directory. -RPM packages are offered for the architectures the Linux sensor supports, like: +LimaCharlie supplies RPM packages for the architectures that the Linux sensor supports, like: - **x64**: - **arm64**: ### Custom Installation -For systems where neither the `.deb` nor the `.rpm` package fits (e.g. distributions without `dpkg` or `rpm`, or installs that need a non-standard layout), download the installer directly using the following command: +Some systems cannot use the `.deb` package or the `.rpm` package. Examples are distributions without `dpkg` or `rpm`, and installs that need a non-standard layout. On these systems, download the installer directly with this command: ```python wget https://downloads.limacharlie.io/sensor/linux/64 -O /tmp/lc_sensor @@ -146,60 +146,60 @@ wget https://downloads.limacharlie.io/sensor/linux/64 -O /tmp/lc_sensor > Other Linux Versions > -> If installing on an ARM64 or Alpine64 system, replace the URL in the command above with the respective URL from the installation wizard within LimaCharlie +> To install on an ARM64 or Alpine64 system, replace the URL in the command above with the URL for that system from the installation wizard in LimaCharlie -Executing the installer via the command line, pass the `-d INSTALLATION_KEY` argument where `INSTALLATION_KEY` is the key mentioned above. +When you run the installer from the command line, pass the `-d INSTALLATION_KEY` argument. `INSTALLATION_KEY` is the key above. -Because Linux supports a plethora of service management frameworks, by default the LC sensor does not install itself onto the system. Rather it assumes the "current working directory" is the installation directory and immediately begins enrollment from there. +Linux has many frameworks that manage services. Because of this, the LC sensor does not install itself onto the system by default. It uses the current working directory as the installation directory and starts enrollment from there. -This means you can wrap the executable using the specific service management technology used within your Organization by simply specifying the location of the installer, the `-d INSTALLATION_KEY` parameter and making sure the current working directory is the directory where you want the few sensor-related files written to disk to reside. +You can therefore wrap the executable with the service management technology of your Organization. Give the location of the installer and the `-d INSTALLATION_KEY` parameter. Make sure that the current working directory is the directory for the few sensor files that go to disk. -A common methodology for Linux is to use `init.d`, if this is sufficient for your needs, see this [sample install script](https://github.com/refractionPOINT/lce_doc/blob/master/docs/lc_linux_installer.sh). -You can invoke it like this: +Many Linux systems use `init.d`. If `init.d` is enough for your needs, see the [sample install script](https://github.com/refractionPOINT/lce_doc/blob/master/docs/lc_linux_installer.sh). +Run it like this: ```bash sudo chmod +x ./lc_linux_installer.sh sudo ./lc_linux_installer.sh ``` -You may also pass the value `-` instead of the `INSTALLATION_KEY` like: `-d -`. This will make the installer look for the installation key in an alternate place in the following order: +You can also pass the value `-` in place of the `INSTALLATION_KEY`, like this: `-d -`. The installer then looks for the installation key in these locations, in this order: - Environment variable `LC_INSTALLATION_KEY` - Text file in current working directory: `lc_installation_key.txt` ### Disabling Netlink -By default, when running on a kernel where eBPF is unavailable, the Linux sensor uses the netlink proc connector (`CN_PROC`) to receive real-time process events. In some rare configurations this auto-detection may be unwanted — for example when another agent on the host already consumes the same connector — and netlink usage can be disabled by setting the environment variable `DISABLE_NETLINK` to any value on the sensor process. With netlink disabled and no eBPF available, the agent falls back to user-mode `/proc` polling. This setting has no effect when eBPF is the active acquisition path. +On a kernel without eBPF, the Linux sensor uses the netlink proc connector (`CN_PROC`) to receive real-time process events. A few configurations do not want this auto-detection. For example, another agent on the host can already consume the same connector. To disable netlink, set the environment variable `DISABLE_NETLINK` to any value on the sensor process. If netlink is disabled and eBPF is not available, the sensor falls back to user-mode `/proc` polling. This setting has no effect when eBPF is the active acquisition path. ### Custom Data Directory -The sensor stores its data and status files under `/opt/limacharlie` by default. On non-standard or hardened distributions where that path is not writable, you can point the sensor at a different directory by setting the `LC_DATA_DIRECTORY` environment variable on the sensor process to an absolute path. The directory must exist and be writable by the sensor. +By default, the sensor stores its data and status files under `/opt/limacharlie`. If that path is not writable on a non-standard or hardened distribution, point the sensor at a different directory. Set the `LC_DATA_DIRECTORY` environment variable on the sensor process to an absolute path. The directory must exist, and the sensor must be able to write to it. ### Restricting DNS Tracking to an Interface -By default DNS tracking watches all network interfaces. To restrict it to a single interface, set the `LC_DNS_IFACE` environment variable to the interface name (for example `LC_DNS_IFACE=eth0`) on the sensor process. +By default, DNS tracking watches all network interfaces. To limit it to one interface, set the `LC_DNS_IFACE` environment variable on the sensor process to the interface name (for example `LC_DNS_IFACE=eth0`). For the complete list of supported options, see the [Agent CLI & Environment Reference](../cli-reference.md). ## Uninstalling the Agent -For additional agent uninstall options, see [Endpoint Agent Uninstallation](../uninstallation.md) +For more uninstall options, see [Endpoint Agent Uninstallation](../uninstallation.md) -Linux agent uninstallation depends on how the sensor was installed. For example, if installed via a Debian package (`dpkg` file) or an RPM package (`rpm` / `dnf` / `yum`), you should uninstall via the same package manager. If you installed via the SystemV installation method, please utilize the bottom of [this script](https://github.com/refractionPOINT/lce_doc/blob/master/docs/lc_linux_installer.sh#L97). +The uninstall method depends on how you installed the sensor. If you installed a Debian package (`dpkg` file) or an RPM package (`rpm` / `dnf` / `yum`), uninstall with the same package manager. If you used the SystemV installation method, use the bottom of the [SystemV install script](https://github.com/refractionPOINT/lce_doc/blob/master/docs/lc_linux_installer.sh#L97). ### Sensor Command -The `uninstall` command does not work for Linux systems. However, there is a chained command that can be run from the Sensor Console: +The `uninstall` command does not work for Linux systems. But you can run a chained command from the Sensor Console: ```powershell run --shell-command "service limacharlie stop; rm /bin/rphcp; update-rc.d limacharlie remove -f; rm -rf /etc/init.d/limacharlie; rm /etc/hcp ; rm /etc/hcp_conf; rm /etc/hcp_hbs" ``` -The above command removes LimaCharlie and associated files from the system when run remotely. Note that the above command could also be coupled with a rule for automated sensor uninstallation, if necessary. +The command above removes LimaCharlie and its files from the system when you run it remotely. You can also join the command to a rule that uninstalls the sensor automatically. ### Debian Systems -If the sensor was originally installed with the .deb file, this option is the cleanest uninstall method. +If you installed the sensor with the .deb file, this option is the cleanest uninstall method. ```bash apt remove limacharlie @@ -207,7 +207,7 @@ apt remove limacharlie ### RPM-based Systems -If the sensor was originally installed with the .rpm file, use the matching package manager: +If you installed the sensor with the .rpm file, use the matching package manager: ```bash sudo dnf remove limacharlie diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/installation-older.md b/docs/2-sensors-deployment/endpoint-agent/macos/installation-older.md index 6240db056..c806835d1 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/installation-older.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/installation-older.md @@ -1,10 +1,10 @@ # macOS Agent Installation - Older Versions (macOS 10.14 and prior) -This document provides details of how to install, verify, and uninstall the LimaCharlie sensor on macOS (versions 10.14 and prior). We also offer [documentation for macOS 10.15 and newer](installation.md). +This document explains how to install, check, and uninstall the LimaCharlie sensor on macOS (version 10.14 and earlier). There is also [documentation for macOS 10.15 and newer](installation.md). ## Installer Options -When running the installer from the command line, you can pass the following arguments: +When you run the installer from the command line, you can pass these arguments: ```text -v: verbose logging output. @@ -23,36 +23,40 @@ For the complete list of options, environment variables, and local files, see th ## Installation Flow 1. Download the [Sensor installer file](https://downloads.limacharlie.io/sensor/mac/64) -2. Add execute permission to the installer file via the command line -> chmod +x hcp\_osx\_x64\_release\_4.23.0 +2. Add execute permission to the installer file from the command line. -1. Run the installer via the command line. You'll pass the argument -i and your Installation Key. + > chmod +x hcp\_osx\_x64\_release\_4.23.0 -> sudo ./hcp\_osx\_x64\_release\_4.23.0 -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE +3. Run the installer from the command line. Pass the -i argument and your Installation Key. -![Basic installation](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/01-Basic_installation.png) + > sudo ./hcp\_osx\_x64\_release\_4.23.0 -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE -You can obtain the installation key from the Installation Keys section of the LimaCharlie web application. [More information about installation keys](../../installation-keys.md). + ![Basic installation](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/01-Basic_installation.png) -The sensor will be installed as a launchctl service. Installation will trigger the sensors enrollment with the LimaCharlie cloud. + Get the installation key from the Installation Keys section of the LimaCharlie web app. [More information about installation keys](../../installation-keys.md). -![Installation success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/02-Installation_success.png) + The installer installs the sensor as a launchctl service. The installation starts the enrollment of the sensor with the LimaCharlie cloud. -1. You will be prompted to grant permissions for system extensions to be installed. + ![Installation success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/02-Installation_success.png) -![Permissions required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/03_Older_Systems-System_Extension_Notice.png) +4. Answer the prompt that asks for permission to install system extensions. -1. Click the "Open System Preferences" button -2. Unlock the preference pane using the padlock in the bottom left corner, then click the Allow button next to `System software from developer "Refraction Point, Inc" was blocked from loading.` + ![Permissions required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/03_Older_Systems-System_Extension_Notice.png) -![Unlocked](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/04-Older_Systems-System_Software_Approval.png) +5. Click the "Open System Preferences" button. -The installation is now complete and you should see a message indicating that the installation was successful. +6. Unlock the preference pane with the padlock in the bottom left corner. + +7. Click the Allow button next to `System software from developer "Refraction Point, Inc" was blocked from loading.` + + ![Unlocked](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/04-Older_Systems-System_Software_Approval.png) + +The installation is now complete. A message shows that the installation was successful. ## Verifying Installation -To verify that the sensor was installed successfully, you can log into the LimaCharlie web application and see if the device has appeared in the Sensors section. Additionally, you can check the following on the device itself: +To check that the installation was successful, log in to the LimaCharlie web app and look for the device in the Sensors section. You can also do these checks on the device: ### Ensure the process is running @@ -62,38 +66,36 @@ In a Terminal, run the command: ![Successful installation verification](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/Installed_correctly.png) -If the agent is running, this command should return a record as shown above. +If the sensor runs, this command returns a record as shown above. ### Ensure the Kernel Extension is loaded -You can confirm that the kernel extension is loaded by running the command: +To confirm that the kernel extension is loaded, run the command: > kextstat | grep com.refractionpoint. ![Successful installation verification](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/verifying-extension.png) -If the extension is loaded, this command should return a record as shown above. +If the extension is loaded, this command returns a record as shown above. ### A note on permissions -Apple has purposely made installing extensions (like the ones used by LimaCharlie) a process that requires several clicks on macOS. The net effect of this is that the first time the sensor is installed on a macOS system, permissions will need to be granted via System Preferences +Apple deliberately makes the installation of extensions on macOS a process that needs several clicks. LimaCharlie uses such extensions. Thus, the first time that you install the sensor on a macOS system, you must grant permissions in System Preferences. -Currently, the only way to automate the installation is to use an Apple-approved MDM solution. These solutions are often used by large organizations to manage their Mac fleet. If you are using such a solution, see your vendor's documentation on how to add extensions to the allow list which can be applied to your entire fleet. +At present, the only way to automate the installation is an MDM solution that Apple approves. Large organizations often use these solutions to manage their macOS computers. If you use such a solution, see the documentation of your vendor. It explains how to add extensions to an allow list that applies to all your computers. -We're aware this is an inconvenience and hope Apple will provide better solutions for security vendors in future. +LimaCharlie knows that this is an inconvenience and hopes that Apple gives better solutions to security vendors in the future. ## Uninstallation Flow To uninstall the sensor: -1. Run the installer via the command line. - -You'll pass the argument -c +1. Run the installer from the command line. Pass the -c argument. -> sudo ./hcp\_osx\_x64\_release\_4.23.0 -c + > sudo ./hcp\_osx\_x64\_release\_4.23.0 -c -![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/Installed_correctly.png) + ![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/macOS_10.14/Installed_correctly.png) -1. You should see a message indicating that the uninstallation was successful. +2. Look for the message that shows that the uninstallation was successful. -![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) + ![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/installation.md b/docs/2-sensors-deployment/endpoint-agent/macos/installation.md index fb5f3a055..dd1ae7344 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/installation.md @@ -1,10 +1,10 @@ # macOS Agent Installation - Older Versions (macOS 10.15 Catalina to macOS 14 Sonoma) -This document provides details of how to install, verify, and uninstall the LimaCharlie Endpoint Agent on macOS (versions 10.15 Catalina though to macOS 14 Sonoma). We also offer documentation for [macOS 10.14 and prior](installation-older.md), and [macOS 10.15 and newer](sequoia.md). +This document explains how to install, check, and uninstall the LimaCharlie Endpoint Agent on macOS (version 10.15 Catalina through macOS 14 Sonoma). There is also documentation for [macOS 10.14 and prior](installation-older.md), and [macOS 10.15 and newer](sequoia.md). ## Installer Options -When running the installer from the command line, you can pass the following arguments: +When you run the installer from the command line, you can pass these arguments: ```text -v: verbose logging output. @@ -23,49 +23,52 @@ For the complete list of options, environment variables, and local files, see th ## Installation Flow 1. Download the Sensor installer file. Installer for: [Intel Mac](https://downloads.limacharlie.io/sensor/mac/64) -or- [Apple Silicon Mac](https://downloads.limacharlie.io/sensor/mac/arm64). -2. Add execute permission to the installer file via the command line -> chmod +x lc\_sensor +2. Add execute permission to the installer file from the command line. -1. Run the installer via the command line. You'll pass the argument -i and your Installation Key. + > chmod +x lc\_sensor -> sudo ./lc\_sensor -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE +3. Run the installer from the command line. Pass the -i argument and your Installation Key. -![Basic installation](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/01-Basic_installation.png) + > sudo ./lc\_sensor -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE -You can obtain the installation key from the [Installation Keys](../../installation-keys.md) section of the LimaCharlie web application. + ![Basic installation](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/01-Basic_installation.png) -The sensor will be installed as a launchctl service. Installation will trigger the sensors enrollment with the LimaCharlie cloud. + Get the installation key from the [Installation Keys](../../installation-keys.md) section of the LimaCharlie web app. -![Installation success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/02-Installation_success.png) + The installer installs the sensor as a launchctl service. The installation starts the enrollment of the sensor with the LimaCharlie cloud. -1. An application (`RPHCP.app`) will be installed in the /Applications folder and will automatically launch. You will be prompted to grant permissions for system extensions to be installed. + ![Installation success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/02-Installation_success.png) -![Permissions required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/03-Permissions_Required.png) +4. Answer the prompt that asks for permission to install system extensions. The installer puts an application (`RPHCP.app`) in the /Applications folder and starts it. -1. Click the "Open System Preferences" button + ![Permissions required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/03-Permissions_Required.png) -![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/04-System_Extension_Required.png) +5. Click the "Open System Preferences" button. -1. Unlock the preference pane using the padlock in the bottom left corner, then click the Allow button next to `System software from application "RPHCP" was blocked from loading.` + ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/04-System_Extension_Required.png) -![Unlocked](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/06-Allow_System_Software_Unlocked.png) +6. Unlock the preference pane with the padlock in the bottom left corner. -1. You'll be prompted to allow the application to Filter Network Content. Click the Allow button. +7. Click the Allow button next to `System software from application "RPHCP" was blocked from loading.` -![Network filter](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/07--Network_Filter.png) + ![Unlocked](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/06-Allow_System_Software_Unlocked.png) -1. You'll be prompted to grant Full Disk Access. Check the checkbox next to the RPHCP app in System Preferences -> Privacy -> Full Disk Access +8. Click the Allow button when the prompt asks you to let the application Filter Network Content. -![Full disk access](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/08-Full_Disk_Access.png) + ![Network filter](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/07--Network_Filter.png) -The installation is now complete and you should see a message indicating that the installation was successful. +9. Select the checkbox next to the RPHCP app in System Preferences -> Privacy -> Full Disk Access when the prompt asks you to grant Full Disk Access. + + ![Full disk access](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/08-Full_Disk_Access.png) + +The installation is now complete. A message shows that the installation was successful. ![Success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/09-Success.png) ## Verifying Installation -To verify that the sensor was installed successfully, you can log into the LimaCharlie web application and see if the device has appeared in the Sensors section. Additionally, you can check the following on the device itself: +To check that the installation was successful, log in to the LimaCharlie web app and look for the device in the Sensors section. You can also do these checks on the device: In a Terminal, run the command: @@ -73,46 +76,46 @@ In a Terminal, run the command: ![Successful installation verification](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Verification/Verification-installation-successful.png) -If the agent is running, this command should return records as shown above. +If the sensor runs, this command returns records as shown above. -You can also check the /Applications folder and launch the RPHCP.app. +You can also open the /Applications folder and start the RPHCP.app. ![Applications folder](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/10-Applications.png) -The application will show a message to indicate if the required permissions have been granted. +The application shows a message that tells you if the necessary permissions are granted. ![App installed correctly](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/11-App_Installed_Correctly.png) -As described in the dialog, the RPHCP.app application must be left in the /Applications folder in order for it to continue operating properly. +Keep the RPHCP.app application in the /Applications folder, as the dialog says. If you move it, the application does not continue to operate correctly. ### A note on permissions -Apple has purposely made installing extensions (like the ones used by LimaCharlie) a process that requires several clicks on macOS. The net effect of this is that the first time the sensor is installed on a macOS system, permissions will need to be granted via System Preferences +Apple deliberately makes the installation of extensions on macOS a process that needs several clicks. LimaCharlie uses such extensions. Thus, the first time that you install the sensor on a macOS system, you must grant permissions in System Preferences. -Currently, the only way to automate the installation is to use an Apple-approved MDM solution. These solutions are often used by large organizations to manage their Mac fleet. If you are using such a solution, see your vendor's documentation on how to add extensions to the allow list which can be applied to your entire fleet. +At present, the only way to automate the installation is an MDM solution that Apple approves. Large organizations often use these solutions to manage their macOS computers. If you use such a solution, see the documentation of your vendor. It explains how to add extensions to an allow list that applies to all your computers. -We're aware this is an inconvenience and hope Apple will provide better solutions for security vendors in future. +LimaCharlie knows that this is an inconvenience and hopes that Apple gives better solutions to security vendors in the future. ## Uninstallation Flow To uninstall the sensor: -1. Run the installer via the command line. You'll pass the argument -c +1. Run the installer from the command line. Pass the -c argument. -> sudo ./hcp\_osx\_x64\_release\_4.23.0 -c + > sudo ./hcp\_osx\_x64\_release\_4.23.0 -c -![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/1-Uninstall_Progress.png) + ![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/1-Uninstall_Progress.png) -1. You will be prompted for credentials to modify system extensions. Enteryour password and press OK. +2. Enter your password at the prompt for credentials to change system extensions. Then press OK. -![Uninstall permissions](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/2-Uninstaller_Permissions.png) + ![Uninstall permissions](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/2-Uninstaller_Permissions.png) -The related system extension will be removed and the `RPHCP.app` will be removed from the /Applications folder. + The uninstaller removes the related system extension. It also removes the `RPHCP.app` from the /Applications folder. -1. You should see a message indicating that the uninstallation was successful. +3. Look for the message that shows that the uninstallation was successful. -![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) + ![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) ## Install Using MDM Solutions -See our document [macOS Agent Installation with MDM Solutions](mdm-profiles.md) for the Mobile Device Management (MDM) Configuration Profile that can be used to deploy the LimaCharlie agent to an enterprise fleet. +For the Mobile Device Management (MDM) Configuration Profile that deploys the LimaCharlie agent to an enterprise fleet, see [macOS Agent Installation with MDM Solutions](mdm-profiles.md). diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/intune.md b/docs/2-sensors-deployment/endpoint-agent/macos/intune.md index 482550abb..e4d3c6aeb 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/intune.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/intune.md @@ -1,61 +1,61 @@ # macOS Agent Installation via Microsoft Intune -You can deploy the LimaCharlie Sensor for macOS using the MDM provider of your choice. Below are instructions for deploying the LimaCharlie Sensor for macOS using Microsoft Intune. +You can deploy the LimaCharlie Sensor for macOS with the MDM provider that you choose. These instructions show how to deploy the LimaCharlie Sensor for macOS with Microsoft Intune. ## MDM Profile -Set up the installation script by following these steps: +Set up the installation script with these steps: 1. In the [Microsoft Intune admin center](https://intune.microsoft.com/), go to Devices → Manage Devices → Configuration. -![Screenshot of MS Intune -> Devices | Configuration](../../../assets/images/Configurations.png) + ![Screenshot of MS Intune -> Devices | Configuration](../../../assets/images/Configurations.png) -1. Choose [Policies](https://intune.microsoft.com/?ref=AdminCenter#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration), click the Create button and choose New Policy +2. Choose [Policies](https://intune.microsoft.com/?ref=AdminCenter#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration), click the Create button, and choose New Policy. - 1. Set the Platform to be macOS + 1. Set the Platform to macOS. - 2. Set the Profile Type to be Templates, then choose the template name "Custom" + 2. Set the Profile Type to Templates, then choose the template name "Custom". - 3. Click Create + 3. Click Create. -2. Enter the custom policy details as follows: +3. Enter the custom policy details as follows: - 1. Name: LimaCharlie + 1. Name: LimaCharlie - 2. Custom configuration profile name: LimaCharlie + 2. Custom configuration profile name: LimaCharlie - 3. Deployment channel: Device channel + 3. Deployment channel: Device channel - 4. Configuration profile file: Download and use the [LimaCharlie MDM profile](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/LimaCharlie.mobileconfig.zip). + 4. Configuration profile file: Download and use the [LimaCharlie MDM profile](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/LimaCharlie.mobileconfig.zip). -Set the Assignments to include all users who need the profile installed. +Set the Assignments to include all users that need the profile. ![Screenshot of MS Intune -> Devices | Configuration | Details](../../../assets/images/Configuration-details.png) ## Installation Script -Set up the installation script by following these steps: +Set up the installation script with these steps: 1. In the [Microsoft Intune admin center](https://intune.microsoft.com/), go to Devices → Manage Devices → Scripts and remediations. -![Screenshot of MS Intune -> Devices | Scripts](../../../assets/images/Scripts.png) + ![Screenshot of MS Intune -> Devices | Scripts](../../../assets/images/Scripts.png) -1. Choose [Platform scripts](https://intune.microsoft.com/?ref=AdminCenter#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/scripts), click the Add button and choose macOS +2. Choose [Platform scripts](https://intune.microsoft.com/?ref=AdminCenter#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/scripts), click the Add button, and choose macOS. -2. Set up the script with the following parameters: +3. Set up the script with these parameters: -Name: Install LimaCharlie + Name: Install LimaCharlie -Shell script: [Download this template shell script](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/sample-install-limacharlie.sh); be sure to edit it to include your Installation Key before uploading it in MS Intune. + Shell script: Download the [template shell script](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/sample-install-limacharlie.sh). Edit it to add your Installation Key before you upload it in MS Intune. -Run script as signed-in user: No + Run script as signed-in user: No -Hide script notifications on devices: Yes + Hide script notifications on devices: Yes -Script frequency: Not configured + Script frequency: Not configured -Max number of times to retry if script fails: 3 + Max number of times to retry if script fails: 3 -Assignments: Set the `Included groups` to be `All Users` if you wish all users to get the application to be installed, or simply select the correct group to whom you wish to have LimaCharlie be installed for. + Assignments: To install the application for all users, set the `Included groups` to `All Users`. To install it for some users, select the correct group. ![Screenshot of MS Intune -> Devices | Scripts | Details](../../../assets/images/Script-details.png) diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/jamf.md b/docs/2-sensors-deployment/endpoint-agent/macos/jamf.md index 9cbec8f50..a17d64f48 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/jamf.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/jamf.md @@ -1,12 +1,12 @@ # macOS Agent Installation via Jamf Now -[Jamf Now](https://www.jamf.com/products/jamf-now/) is an MDM solution that provides an easy way to manage Apple devices for small and medium-sized businesses. LimaCharlie sensors can be deployed via Jamf Now for easy app distribution and inventory capabilities. +[Jamf Now](https://www.jamf.com/products/jamf-now/) is an MDM solution that manages Apple devices for small and medium businesses. You can deploy LimaCharlie sensors with Jamf Now to distribute applications and to keep an inventory of devices. ## Prerequisites - a Jamf Now account; -- a provisioning profile that grants the necessary pre-authorizations (such as is [available here](installation.md)) for deployment on the clients; -- a LimaCharlie Mac Sensor installer package (`.pkg`) that's configured as desired for deployment on the clients. +- a provisioning profile that gives the necessary pre-authorizations for deployment on the clients (see [macOS Agent Installation](installation.md)); +- a LimaCharlie Mac Sensor installer package (`.pkg`) that is configured for deployment on the clients. ## Set up your account on Jamf Now @@ -14,138 +14,144 @@ 2. Choose the "APNs" tab in the sidebar, and click "Get Started". 3. Click "Download Certificate Signing Request.plist" and save the plist. 4. Click Next in the lower right. -5. As per the "Create an Apple Push Certificate" checklist shown, click "Open the Apple Push Certificates Portal". +5. In the "Create an Apple Push Certificate" checklist, click "Open the Apple Push Certificates Portal". 6. Log in with your Apple ID. -7. On the "Apple Push Certificates Portal" page to which you are redirected, click the green "Create Certificate" button. +7. On the "Apple Push Certificates Portal" page that opens, click the green "Create Certificate" button. 8. Accept the Terms of Use, and click Continue. -9. On the "Create a New Push Certificate" page to which you're redirected, specify the plist you downloaded in step 2 and click Upload. +9. On the "Create a New Push Certificate" page that opens, specify the plist that you downloaded in step 2, and click Upload. 10. On the "Confirmation" page, click Download and save the new PEM certificate file. -11. Navigate back to the Jamf Now page as at step 5, and click Next in the lower right. -12. On the "Upload Push Certificate" page, specify the PEM you downloaded in step 10. -13. Under "Save Your Apple ID", annotate same as Jamf invites to do so, and click Save. +11. Go back to the Jamf Now page from step 5, and click Next in the lower right. +12. On the "Upload Push Certificate" page, specify the PEM file that you downloaded in step 10. +13. Under "Save Your Apple ID", record the Apple ID as Jamf asks, and click Save. ## Prepare the LimaCharlie sensor installer package on Jamf -As a prerequisite you must have on hand a LimaCharlie Sensor installer package (.pkg) that's configured as desired. +Before you start, you must have a LimaCharlie Sensor installer package (.pkg) that is configured as you need it. + +1. Choose the "Apps" tab in the Jamf Now sidebar. It shows "No apps yet, let's fix that." -1. Choose the "Apps" tab in the Jamf Now sidebar. It will show "No apps yet, let's fix that." 2. Click "Add an App". -![image.png](../../../assets/images/image(117).png) + ![image.png](../../../assets/images/image(117).png) + +3. On the "Add an App" page, click "Upload Your App" in the top menu. -1. On the "Add an App" page, click "Upload Your App" in the top menu. + ![image.png](../../../assets/images/image(118).png) -![image.png](../../../assets/images/image(118).png) +4. Drag your LC Sensor package installer onto the page to upload it to Jamf. You can also click "browse" to find the file. -1. Drag your LC Sensor package installer onto the page (or click "browse" to locate it) to upload it to Jamf. -2. Give the package an appropriate name, and click Done. +5. Give the package a suitable name, and click Done. -![image.png](../../../assets/images/image(119).png) + ![image.png](../../../assets/images/image(119).png) ## Prepare the LimaCharlie sensor provisioning on Jamf 1. Choose the "Blueprints" tab in the Jamf Now sidebar. + 2. Click "Create New Blueprint" at the top. -![image.png](../../../assets/images/image(120).png) + ![image.png](../../../assets/images/image(120).png) -1. Enter a meaningful Name and Description as prompted, and click Save Blueprint. +3. Enter a Name and a Description as prompted, and click Save Blueprint. -![image.png](../../../assets/images/image(121).png) + ![image.png](../../../assets/images/image(121).png) -1. Click on the entry for your new Blueprint. +4. Click the entry for your new Blueprint. -![image.png](../../../assets/images/image(122).png) + ![image.png](../../../assets/images/image(122).png) -1. On the inner tab bar that appears, click "Custom Profiles", and then "Add a Custom Profile". +5. On the inner tab bar that appears, click "Custom Profiles", and then "Add a Custom Profile". -![image.png](../../../assets/images/image(123).png) + ![image.png](../../../assets/images/image(123).png) -1. Drag your LimaCharlie mobileconfig file onto the page (or click "browse" to locate it) to upload it to Jamf. +6. Drag your LimaCharlie mobileconfig file onto the page to upload it to Jamf. You can also click "browse" to find the file. -![image.png](../../../assets/images/image(124).png) + ![image.png](../../../assets/images/image(124).png) -1. Click "Add Custom Profile" in the lower right. +7. Click "Add Custom Profile" in the lower right. -![image.png](../../../assets/images/image(125).png) + ![image.png](../../../assets/images/image(125).png) -1. On the inner tab bar, click "Apps", and then click "Add App". +8. On the inner tab bar, click "Apps", and then click "Add App". -![image.png](../../../assets/images/image(126).png) + ![image.png](../../../assets/images/image(126).png) -1. In the list, enable the "Install Automatically" checkbox for with the installer package that you uploaded earlier. +9. In the list, select the "Install Automatically" checkbox for the installer package that you uploaded before. -![image.png](../../../assets/images/image(127).png) + ![image.png](../../../assets/images/image(127).png) -1. Click "Save Changes" in the lower right. +10. Click "Save Changes" in the lower right. ## Prepare Jamf Now to enroll devices -1. Choose the "Devices" tab in the Jamf Now sidebar. It will show "No devices yet, let's fix that." +1. Choose the "Devices" tab in the Jamf Now sidebar. It shows "No devices yet, let's fix that." 2. Click "Enable Open Enrollment". -3. On the "Open Enrollment" page, activate the "Enable Open Enrollment" checkbox, enter an Access Code as prompted, and click Save Settings. -4. Take note of the indicated enrollment link. +3. On the "Open Enrollment" page, select the "Enable Open Enrollment" checkbox, enter an Access Code as prompted, and click Save Settings. +4. Record the enrollment link that the page shows. ## Enroll a Mac for management in Jamf -The following recipe presumes the use of MacOS 13 (Ventura). +These steps assume MacOS 13 (Ventura). -1. On a subject Mac, visit the enrollment link from step 4 in the section above. -2. Enter the appropriate Access Code and user name, and click Start Enrollment. +1. On a subject Mac, open the enrollment link from step 4 in the section above. -![image.png](../../../assets/images/image(128).png) +2. Enter the correct Access Code and user name, and click Start Enrollment. -1. Save the "enroll.mobileconfig" file that begins to download, and then open it in the Finder by double-clicking. -2. Open the System Settings app and navigate to the newly-installed profile. + ![image.png](../../../assets/images/image(128).png) - 1. Choose "Privacy & Security". - 2. Scroll to the bottom, and under the "Others" heading, click "Profiles". +3. Save the "enroll.mobileconfig" file that starts to download, then double-click it in the Finder to open it. -![image.png](../../../assets/images/image(129).png) +4. Open the System Settings app and go to the newly-installed profile. -1. Double-click on the " Profile". + 1. Choose "Privacy & Security". + 2. Scroll to the bottom, and under the "Others" heading, click "Profiles". -![image.png](../../../assets/images/image(130).png) + ![image.png](../../../assets/images/image(129).png) -1. Click "Install…" in the lower left. +5. Double-click the " Profile". -![image.png](../../../assets/images/image(131).png) + ![image.png](../../../assets/images/image(130).png) -1. Authenticate with the appropriate password when prompted with "Profiles is trying to enroll you in a remote management (MDM) service". +6. Click "Install…" in the lower left. -![image.png](../../../assets/images/image(132).png) + ![image.png](../../../assets/images/image(131).png) -1. Observe that System Settings declares "This Mac is supervised and managed by ". +7. Authenticate with the correct password at the prompt "Profiles is trying to enroll you in a remote management (MDM) service". -![image.png](../../../assets/images/image(133).png) + ![image.png](../../../assets/images/image(132).png) + +8. Check that System Settings shows "This Mac is supervised and managed by ". + + ![image.png](../../../assets/images/image(133).png) ## Provision a Mac with the LimaCharlie sensor 1. Choose the "Blueprints" tab in the Jamf Now sidebar. -2. Click the entry for the custom Blueprint you created from Step 6 onward in the "Prepare the LC sensor package on Jamf" section above. -![image.png](../../../assets/images/image(134).png) +2. Click the entry for the custom Blueprint that you created from Step 6 onward in the "Prepare the LC sensor package on Jamf" section above. + + ![image.png](../../../assets/images/image(134).png) -1. On the inner tab bar that appears, click "Devices", and then "Add a Device". +3. On the inner tab bar that appears, click "Devices", and then "Add a Device". -![image.png](../../../assets/images/image(135).png) + ![image.png](../../../assets/images/image(135).png) -1. Click on a device you want to provision, and then click "Add Devices" in the lower right corner. +4. Click a device that you want to provision, and then click "Add Devices" in the lower right corner. -![image.png](../../../assets/images/image(136).png) + ![image.png](../../../assets/images/image(136).png) -1. Observe after a few moments that both the provisioning profile and the LimaCharlie sensor have been installed on the subject Mac. +5. After a few moments, check that the provisioning profile and the LimaCharlie sensor are installed on the subject Mac. - 1. The Mac appear in the Jamf Devices list on the Blueprints tab with the label "Settings applied". (It may initially appear as "Settings not applied"; simply refresh the page.) + 1. The Mac appears in the Jamf Devices list on the Blueprints tab with the label "Settings applied". At first it can show "Settings not applied". Refresh the page. -![image.png](../../../assets/images/image(137).png) + ![image.png](../../../assets/images/image(137).png) -1. On the Mac itself, an additional profile appears in System Settings > Privacy & Security > Profiles. + 2. On the Mac itself, one more profile appears in System Settings > Privacy & Security > Profiles. -![image.png](../../../assets/images/image(138).png) + ![image.png](../../../assets/images/image(138).png) -1. A "Background Items Added" notification is displayed. + 3. A "Background Items Added" notification is displayed. -![image.png](../../../assets/images/image(139).png) + ![image.png](../../../assets/images/image(139).png) -1. The RPHCP.app appears in the Mac's Applications folder, and the rphcp daemon is running. + 4. The RPHCP.app appears in the Applications folder of the Mac, and the rphcp daemon runs. diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/mdm-profiles.md b/docs/2-sensors-deployment/endpoint-agent/macos/mdm-profiles.md index bae82d871..fd3a27cf6 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/mdm-profiles.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/mdm-profiles.md @@ -1,10 +1,10 @@ # macOS Agent Installation - MDM Configuration Profiles -This document provides details of the Mobile Device Management (MDM) Configuration Profile that can be used to deploy the LimaCharlie agent to your enterprise fleet on macOS (versions 10.15 and newer). +This document describes the Mobile Device Management (MDM) Configuration Profile. Use the profile to deploy the LimaCharlie agent to a macOS fleet (versions 10.15 and newer). ## Affected Dialogs -Once the configuration profile is deployed using an approved MDM server, users will not need to provide approval to complete the agent installation. In particular, the following three system approval dialogs will no longer be presented: +After you deploy the configuration profile with an approved MDM server, users do not need to approve the agent installation. macOS no longer shows these three system approval dialogs: System Extension ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/04-System_Extension_Required.png) @@ -20,11 +20,11 @@ Application Installation ## Configuration Profile Details -We have provided a sample configuration profile for reference: [![MobileConfig icon](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/mobileconfig-icon.png)](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/LimaCharlie.mobileconfig.zip) +A sample configuration profile is available for reference: [![MobileConfig icon](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/mobileconfig-icon.png)](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/LimaCharlie.mobileconfig.zip) [Download LimaCharlie.mobileconfig sample configuration profile](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/LimaCharlie.mobileconfig.zip) -This profile includes the following permissions: +The profile includes these permissions: - System Extension - Full Disk Access @@ -32,17 +32,17 @@ This profile includes the following permissions: ## Silent Installation Preference -In addition to the MDM profile, you will also want to place the following preference file in the /Library/Preferences folder on the endpoint prior to installation. With this preference file in place the application will provide for a silent installation. +Put the preference file below in the /Library/Preferences folder on the endpoint before you install the agent. The preference file makes the installation silent. Use the preference file with the MDM profile. -The required preference file can be downloaded here: [![Preference file icon](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/preference-icon.png)](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/com.refractionpoint.rphcp.client.plist.zip) +Download the preference file: [![Preference file icon](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/preference-icon.png)](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/com.refractionpoint.rphcp.client.plist.zip) [Download com.refractionpoint.rphcp.client.plist preference file (to be placed in the /Library/Preferences folder on the endpoint)](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/com.refractionpoint.rphcp.client.plist.zip) ## Installation Scripts -We have made a sample installation and uninstallation script available. You can use these with MDM providers to mass install/remove LimaCharlie. Note that the installation script should be edited prior to use as it requires your unique Installation Key to be entered. +A sample installation script and a sample uninstallation script are available. Use them with MDM providers to install or remove LimaCharlie on many machines. Edit the installation script before you use it, because it needs your unique Installation Key. -These scripts will determine the machine architecture (Intel or Apple Silicon), download the appropriate installer, and then perform the installation or uninstallation. They also will automatically add (or remove, for uninstallations) the Silent Installation Preference File. +The scripts find the machine architecture (Intel or Apple Silicon), download the correct installer, and then install or uninstall the agent. The scripts also add the Silent Installation Preference File, or remove it for an uninstallation. [Sample Installation Script](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/sample-install-limacharlie.sh) @@ -50,68 +50,68 @@ These scripts will determine the machine architecture (Intel or Apple Silicon), ## Example Jamf Pro Setup -While any Apple / user approved MDM provider may be used, we have provided specific instructions for Jamf Pro as a matter of convenience. +You can use any Apple-approved or user-approved MDM provider. These instructions are for Jamf Pro. -1. Log into Jamf Pro and go to Computers -> Configuration Profiles -2. Add a new profile -3. In the General section choose a name for the profile and set Level to "Computer Level" +1. Log in to Jamf Pro and go to Computers -> Configuration Profiles. +2. Add a new profile. +3. In the General section, enter a name for the profile and set Level to "Computer Level". -![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-1-General.png) + ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-1-General.png) -1. Add a Privacy Preferences Policy Control configuration and set the parameters as follows: +4. Add a Privacy Preferences Policy Control configuration and set these parameters: -Identifier: -com.refractionpoint.rphcp.extension + Identifier: + com.refractionpoint.rphcp.extension -Identifier Type: -Bundle ID + Identifier Type: + Bundle ID -Code Requirement: -anchor apple generic and identifier "com.refractionpoint.rphcp.extension" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) + Code Requirement: + anchor apple generic and identifier "com.refractionpoint.rphcp.extension" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) -App or Service: -SystemPolicyAllFiles + App or Service: + SystemPolicyAllFiles -Access: -Allow + Access: + Allow -![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-2-PPPC.png) + ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-2-PPPC.png) -1. Add a System Extensions configuration and set the parameters as follows: +5. Add a System Extensions configuration and set these parameters: -Enter your desired display name + Enter your display name -System Extension Types: Allowed System Extensions + System Extension Types: Allowed System Extensions -Team Identifier: N7N82884NH + Team Identifier: N7N82884NH -Allowed System Extensions: com.refractionpoint.rphcp.extension + Allowed System Extensions: com.refractionpoint.rphcp.extension -![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-2-SystemExtensions.png) + ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-2-SystemExtensions.png) -1. Add a Content Filter configuration and set the parameters as follows: +6. Add a Content Filter configuration and set these parameters: -Enter your desired filter name + Enter your filter name -Identifier: com.refractionpoint.rphcp.client + Identifier: com.refractionpoint.rphcp.client -Filter Order: Firewall + Filter Order: Firewall -Add a Socket Filter with the following details: -Socket Filter Bundle Identifier: -com.refractionpoint.rphcp.client + Add a Socket Filter with these details: + Socket Filter Bundle Identifier: + com.refractionpoint.rphcp.client -Socket Filter Designated Requirement -anchor apple generic and identifier "com.refractionpoint.rphcp.client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) + Socket Filter Designated Requirement + anchor apple generic and identifier "com.refractionpoint.rphcp.client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) -Add a Network Filter with the following details: + Add a Network Filter with these details: -Network Filter Bundle Identifier: -com.refractionpoint.rphcp.client + Network Filter Bundle Identifier: + com.refractionpoint.rphcp.client -Network Filter Designated Requirement: -anchor apple generic and identifier "com.refractionpoint.rphcp.client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) + Network Filter Designated Requirement: + anchor apple generic and identifier "com.refractionpoint.rphcp.client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /\* exists \*/ or certificate 1[field.1.2.840.113635.100.6.2.6] /\* exists \*/ and certificate leaf[field.1.2.840.113635.100.6.1.13] /\* exists \*/ and certificate leaf[subject.OU] = N7N82884NH) -![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-4-ContentFilter.png) + ![System Extensions Required](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/MDM_profiles/JamfPro-4-ContentFilter.png) -1. Deploy the configuration profile to your devices. +7. Deploy the configuration profile to your devices. diff --git a/docs/2-sensors-deployment/endpoint-agent/macos/sequoia.md b/docs/2-sensors-deployment/endpoint-agent/macos/sequoia.md index 033098300..81a70b18f 100644 --- a/docs/2-sensors-deployment/endpoint-agent/macos/sequoia.md +++ b/docs/2-sensors-deployment/endpoint-agent/macos/sequoia.md @@ -1,10 +1,10 @@ # macOS Agent Installation - Latest Versions (macOS 15 Sequoia and newer) -This document provides details of how to install, verify, and uninstall the LimaCharlie Endpoint Agent on macOS (version 15 Sequoia). We also offer separate documentation for older versions. +This document explains how to install, check, and uninstall the LimaCharlie Endpoint Agent on macOS (version 15 Sequoia). Separate documentation covers older versions. ## Installer Options -When running the installer from the command line, you can pass the following arguments: +When you run the installer from the command line, you can pass these arguments: ```text -v: verbose logging output. @@ -22,54 +22,54 @@ For the complete list of options, environment variables, and local files, see th ## Installation Flow -1. Download the Sensor installer file. Installer for: [Intel Mac](https://downloads.limacharlie.io/sensor/mac/64) -or- [Apple Silicon Mac](https://downloads.limacharlie.io/sensor/mac/arm64). -2. Add execute permission to the installer file via the command line +1. Download the sensor installer file. Use the installer for [Intel Mac](https://downloads.limacharlie.io/sensor/mac/64) or [Apple Silicon Mac](https://downloads.limacharlie.io/sensor/mac/arm64). +2. Add execute permission to the installer file from the command line. -> chmod +x lc\_sensor + > chmod +x lc\_sensor -1. Run the installer via the command line. You'll pass the argument -i and your Installation Key. +3. Run the installer from the command line. Pass the argument -i and your Installation Key. -> sudo ./lc\_sensor -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE + > sudo ./lc\_sensor -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE -You can obtain the installation key from the [Installation Keys](../../installation-keys.md) section of the LimaCharlie web application. + Get the installation key from the [Installation Keys](../../installation-keys.md) section of the LimaCharlie web application. -The sensor will be installed as a launchctl service. Installation will trigger the sensors enrollment with the LimaCharlie cloud + The installer installs the sensor as a launchctl service. The installation starts the enrollment of the sensor with the LimaCharlie cloud. -![macOS Terminal application showing LimaCharlie installation](../../../assets/images/1-Terminal_install.png) + ![macOS Terminal application showing LimaCharlie installation](../../../assets/images/1-Terminal_install.png) -1. An application (`RPHCP.app`) will be installed in the /Applications folder and will automatically launch. Note that it may take a few minutes before you see this happened after installation. +4. Wait for the application (`RPHCP.app`) to install in the /Applications folder and start. This can take a few minutes after the installation. - You will be prompted to grant permissions for system extensions to be installed. Click the "**Open System Settings**" button + macOS asks you to grant permission to install system extensions. Click the "**Open System Settings**" button. -![Endpoint Extension Installation Dialog](../../../assets/images/2-Endpoint_Extension_Installation_Dialog.png) + ![Endpoint Extension Installation Dialog](../../../assets/images/2-Endpoint_Extension_Installation_Dialog.png) -1. Ensure the toggle for "Allow in the Background" next to "Refraction Point, Inc." is toggled On. +5. Set the toggle for "Allow in the Background" next to "Refraction Point, Inc." to On. -![Login Items and Extensions](../../../assets/images/2.5-Login_Items_and_Extensions.png) + ![Login Items and Extensions](../../../assets/images/2.5-Login_Items_and_Extensions.png) -1. Click the "i" info icon next to "Endpoint Security Extensions", then ensure the toggle next to "RPHCP" is on. +6. Click the "i" info icon next to "Endpoint Security Extensions", then set the toggle next to "RPHCP" to on. -![Endpoint Extension Enablement](../../../assets/images/3-Endpoint_Extension_Enablement.png) + ![Endpoint Extension Enablement](../../../assets/images/3-Endpoint_Extension_Enablement.png) -![EndpointSecurityExtension Enabled](../../../assets/images/EndpointSecurityExtension-Enabled.png) + ![EndpointSecurityExtension Enabled](../../../assets/images/EndpointSecurityExtension-Enabled.png) -1. After enabling that toggle you'll need to click the "Allow" button to allow RPHCP to filter network content. +7. Click the "Allow" button after you set that toggle. This lets RPHCP filter network content. -![Network Filter Enablement](../../../assets/images/4-Network_Filter_Enablement.png) + ![Network Filter Enablement](../../../assets/images/4-Network_Filter_Enablement.png) -1. You'll be prompted to grant Full Disk Access. Check the checkbox next to the RPHCP app in System Preferences -> Privacy -> Full Disk Access +8. Select the checkbox next to the RPHCP app in System Preferences -> Privacy -> Full Disk Access. macOS asks you to grant Full Disk Access. -![Full Disk Access Permission Dialog](../../../assets/images/5-Full_Disk_Access_Permission_Dialog.png) + ![Full Disk Access Permission Dialog](../../../assets/images/5-Full_Disk_Access_Permission_Dialog.png) -![Full Disk Access Enablement](../../../assets/images/6-Full_Disk-Access_Enablement.png) + ![Full Disk Access Enablement](../../../assets/images/6-Full_Disk-Access_Enablement.png) -The installation is now complete and you should see a message indicating that the installation was successful. +The installation is complete. A message shows that the installation was successful. ![Success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/09-Success.png) ## Verifying Installation -To verify that the sensor was installed successfully, you can log into the LimaCharlie web application and see if the device has appeared in the Sensors section. Additionally, you can check the following on the device itself: +To check that the sensor installed correctly, log in to the LimaCharlie web application and look for the device in the Sensors section. You can also check the device itself. In a Terminal, run the command: @@ -77,52 +77,52 @@ In a Terminal, run the command: ![Successful installation verification](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Verification/Verification-installation-successful.png) -If the agent is running, this command should return records as shown above. +If the sensor runs, the command returns records as shown above. -You can also check the /Applications folder and launch the RPHCP.app. +You can also open the /Applications folder and start RPHCP.app. ![Applications folder](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/10-Applications.png) -You can confirm the network filter was properly installed and enabled by going to System Settings → Network → VPN & Filters. You should expect to see "RPHCP" in the list with the status showing as Enabled. +To confirm that the network filter is installed and enabled, go to System Settings → Network → VPN & Filters. "RPHCP" shows in the list with the status Enabled. ![Network Filter Confirmation](../../../assets/images/7-Network_Filter_Confirmation(1).png) -The application will show a message to indicate if the required permissions have been granted. +The application shows a message that tells you if the necessary permissions are granted. ![App installed correctly](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Installation/11-App_Installed_Correctly.png) -As described in the dialog, the RPHCP.app application must be left in the /Applications folder in order for it to continue operating properly. +Keep the RPHCP.app application in the /Applications folder, as the dialog describes. The application does not continue to operate correctly in another folder. ### A note on permissions -Apple has purposely made installing extensions (like the ones used by LimaCharlie) a process that requires several clicks on macOS. The net effect of this is that the first time the sensor is installed on a macOS system, permissions will need to be granted via System Preferences +Apple designed the installation of extensions on macOS to need several clicks. LimaCharlie uses these extensions. The first time that you install the sensor on a macOS system, you must grant permissions in System Preferences. -Currently, the only way to automate the installation is to use an Apple-approved MDM solution. These solutions are often used by large organizations to manage their Mac fleet. If you are using such a solution, see your vendor's documentation on how to add extensions to the allow list which can be applied to your entire fleet. +An Apple-approved MDM solution is the only way to automate the installation. Large organizations often use these solutions to manage a Mac fleet. If you use such a solution, see your vendor's documentation about how to add extensions to the allow list for the full fleet. -We're aware this is an inconvenience and hope Apple will provide better solutions for security vendors in future. +LimaCharlie knows that this process is an inconvenience, and hopes that Apple supplies better solutions for security vendors in the future. ## Uninstallation Flow To uninstall the sensor: -1. Run the installer via the command line. You'll pass the argument -c +1. Run the installer from the command line. Pass the argument -c. -> sudo ./hcp\_osx\_x64\_release\_4.23.0 -c + > sudo ./hcp\_osx\_x64\_release\_4.23.0 -c -![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/1-Uninstall_Progress.png) + ![Uninstall progress](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/1-Uninstall_Progress.png) -1. You will be prompted for credentials to modify system extensions. Enteryour password and press OK. +2. Enter your password and press OK when macOS asks for credentials to change system extensions. -![Uninstall permissions](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/2-Uninstaller_Permissions.png) + ![Uninstall permissions](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/2-Uninstaller_Permissions.png) -The related system extension will be removed and the `RPHCP.app` will be removed from the /Applications folder. + macOS removes the related system extension and removes `RPHCP.app` from the /Applications folder. -1. You should see a message indicating that the uninstallation was successful. +3. Look for the message that shows that the uninstallation was successful. -![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) + ![Uninstall success](https://storage.googleapis.com/limacharlie-io/doc/sensor-installation/macOS/images/Uninstallation/3-Uninstall_Success.png) -Note: After uninstallation the LimaCharlie sensor along with the related extensions will be removed. macOS requires a reboot to fully unload and remove extensions. +Note: The uninstallation removes the LimaCharlie sensor and the related extensions. macOS needs a reboot to unload and remove the extensions completely. ## Install Using MDM Solutions -See our document [macOS Agent Installation with MDM Solutions](mdm-profiles.md) for the Mobile Device Management (MDM) Configuration Profile that can be used to deploy the LimaCharlie agent to an enterprise fleet. +For the Mobile Device Management (MDM) Configuration Profile that deploys the LimaCharlie agent to an enterprise fleet, see [macOS Agent Installation with MDM Solutions](mdm-profiles.md). diff --git a/docs/2-sensors-deployment/endpoint-agent/payloads.md b/docs/2-sensors-deployment/endpoint-agent/payloads.md index c63dcd334..c3135d849 100644 --- a/docs/2-sensors-deployment/endpoint-agent/payloads.md +++ b/docs/2-sensors-deployment/endpoint-agent/payloads.md @@ -2,40 +2,40 @@ ## Overview -Payloads are executables or scripts that can be delivered and executed through LimaCharlie's Endpoint Agent. +Payloads are executables or scripts that LimaCharlie's Endpoint Agent delivers and runs. -Those payloads can be any executable or script natively understood by the endpoint. The main use case is to run something with specific functionality not available in the main LimaCharlie functionality. For example: custom executables provided by another vendor to cleanup a machine, forensic utilities or firmware-related utilities. +A payload can be any executable or script that the endpoint understands. Use a payload to run a function that LimaCharlie does not supply. Examples are custom executables from another vendor that clean a machine, forensic utilities, and firmware utilities. -We encourage you to look at LimaCharlie native functionality first as it has several advantages: +Look at the native LimaCharlie functions first. They have these advantages: -- Usually has better performance. -- Data returned is always well structured JSON. -- Can be tasked automatically and [Detection & Response Rules](../../3-detection-response/index.md) can be created from their data. -- Data returned is indexed and searchable. +- Performance is usually better. +- The data that they return is always well structured JSON. +- You can task them automatically, and you can create [Detection & Response Rules](../../3-detection-response/index.md) from their data. +- The data that they return is indexed and searchable. -It is possible to set the Payload's file extension on the endpoint by making the Payload name end with that extension. For example, naming a Payload `extract_everything.bat`, the Payload will be sent as a batch file (`.bat`) and executed as such. This is also true for PowerShell files (`.ps1`). +To set the file extension of the Payload on the endpoint, end the Payload name with that extension. For example, if you name a Payload `extract_everything.bat`, LimaCharlie sends it as a batch file (`.bat`) and runs it as one. This also applies to PowerShell files (`.ps1`). ## Lifecycle -Payloads are uploaded to the LimaCharlie platform and given a name. The task `run` can then be used with the `--payload-name MY-PAYLOAD --arguments "-v EulaAccepted"` can be used to run the payload with optional arguments. +You upload Payloads to the LimaCharlie cloud and give each one a name. Then use the `run` task with `--payload-name MY-PAYLOAD --arguments "-v EulaAccepted"` to run the payload with optional arguments. -The STDOUT and STDERR data will be returned in a related `RECEIPT` event, up to 1 MB. If your payload generates more data, we recommend to pipe the data to a file on disk and use the `log_get` command to retrieve it. +A related `RECEIPT` event returns the STDOUT and STDERR data, up to 1 MB. If your payload makes more data, send the data to a file on disk. Then use the `log_get` command to get the file. -The payload is retrieved by the endpoint agent over HTTPS to the Ingestion API DNS endpoint. This DNS entry is available from the Sensor Download section of the web app if you need to allow it. +The endpoint agent gets the payload over HTTPS from the Ingestion API DNS endpoint. If you must allow this DNS entry, find it in the Sensor Download section of the web app. ## Upload / Download via REST -Creating and getting Payloads is done asynchronously. The relevant REST APIs will return specific signed URLs instead of the actual Payload. In the case of a retrieving an existing payload, simply doing an HTTP GET using the returned URL will download the payload content. When creating a Payload the returned URL should be used in an HTTP PUT using the URL like: +LimaCharlie creates and gets Payloads asynchronously. The REST APIs return signed URLs, not the Payload. To get an existing payload, do an HTTP GET on the returned URL. To create a Payload, do an HTTP PUT on the returned URL: ```bash curl -X PUT "THE-SIGNED-URL-HERE" -H "Content-Type: application/octet-stream" --upload-file your-file.exe ``` -Note that the signed URLs are only valid for a few minutes. +The signed URLs are valid for a few minutes only. ## Permissions -Payloads are managed with two permissions: +Two permissions manage Payloads: -- `payload.ctrl` allows you to create and delete payloads. -- `payload.use` allows you to run a given payload. +- `payload.ctrl` lets you create and delete payloads. +- `payload.use` lets you run a payload. diff --git a/docs/2-sensors-deployment/endpoint-agent/service-upgrades.md b/docs/2-sensors-deployment/endpoint-agent/service-upgrades.md index 19abe6eeb..5d3a01101 100644 --- a/docs/2-sensors-deployment/endpoint-agent/service-upgrades.md +++ b/docs/2-sensors-deployment/endpoint-agent/service-upgrades.md @@ -1,15 +1,15 @@ # Service Upgrades -The LimaCharlie endpoint agent consists of two components that are versioned independently: +The LimaCharlie endpoint agent has two components with independent version numbers: -- **On-disk agent** — the service binary installed on the host. It handles core identity, cryptography, and transport. This component rarely changes and is what gets replaced during a service upgrade. -- **Over-the-air core** — the main functional component that delivers detection and response capabilities. It is downloaded from the LimaCharlie cloud and updated frequently. See [Versioning & Upgrades](versioning-upgrades.md) for managing over-the-air updates. +- **On-disk agent** — the service binary on the host. It does core identity, cryptography, and transport. This component changes rarely, and a service upgrade replaces it. +- **Over-the-air core** — the main component that supplies detection and response functions. It is downloaded from the LimaCharlie cloud and updated often. To manage over-the-air updates, see [Versioning & Upgrades](versioning-upgrades.md). -The procedures on this page upgrade the **on-disk agent** only. This is useful when a new service binary is needed for bug fixes, platform compatibility, or to gain support for new on-disk features. Over-the-air core updates happen separately through the LimaCharlie cloud and do not require a service upgrade. +The procedures on this page upgrade the **on-disk agent** only. Use them when you need a new service binary for bug fixes, platform compatibility, or support for new on-disk features. The LimaCharlie cloud updates the over-the-air core separately, and that update does not need a service upgrade. -The upgrade process stops the running service, replaces the binary with the new version, and restarts the service. If the new version fails to start, an automatic rollback to the previous version occurs. +The upgrade stops the service, replaces the binary with the new version, and starts the service again. If the new version does not start, the upgrade rolls back to the previous version automatically. -!!! note "Prerequisites" - The command must be run with **root** (Linux/macOS) or **Administrator** (Windows) privileges. - No installation key is required for upgrades. +!!! note "Prerequisites" - Run the command with **root** (Linux/macOS) or **Administrator** (Windows) privileges. - Upgrades do not need an installation key. ## Upgrade to Latest Version @@ -27,10 +27,10 @@ The upgrade process stops the running service, replaces the binary with the new ## Upgrade or Downgrade to a Specific Version -The `--version` flag can be used to move to any available sensor version, whether newer or older than the currently installed version. This is useful for rolling back to a known-good version or pinning to a specific release. +Use the `--version` flag to move to any available sensor version, newer or older than the installed version. Use the flag to roll back to a known-good version or to pin a specific release. !!! note -The `--version` flag requires sensor version **4.33.28 or later**. +The `--version` flag needs sensor version **4.33.28 or later**. === "Linux / macOS" @@ -46,10 +46,10 @@ The `--version` flag requires sensor version **4.33.28 or later**. ## Upgrade Using a Downloaded Sensor Binary -If you have already downloaded a sensor binary, you can upgrade the installed service directly by running it with the `-u` flag. This performs the same in-place upgrade without needing the shell installer. +If you already downloaded a sensor binary, run it with the `-u` flag to upgrade the installed service. This does the same in-place upgrade, but it does not need the shell installer. !!! note -The `-u` flag requires sensor version **4.33.28 or later**. +The `-u` flag needs sensor version **4.33.28 or later**. === "Linux / macOS" @@ -65,9 +65,9 @@ The `-u` flag requires sensor version **4.33.28 or later**. ## Upgrade from the Cloud with the `upgrade_core` Command (Beta) -Instead of running an installer on the host, you can task a sensor to upgrade its own on-disk agent with the `upgrade_core` sensor command. The sensor downloads, verifies, and installs the requested release itself — no local shell access or installer download is required. The automatic rollback on a failed start applies here as well. +You can task a sensor to upgrade its own on-disk agent with the `upgrade_core` sensor command, instead of running an installer on the host. The sensor downloads, checks, and installs the requested release. Local shell access and an installer download are not necessary. The automatic rollback on a failed start also applies here. -The native upgrade procedure is currently in beta, so the `--beta` flag is required; the command is rejected without it. +The native upgrade procedure is in beta, so you must give the `--beta` flag. Without the flag, the command is rejected. ```bash limacharlie sensor task upgrade_core --beta @@ -76,16 +76,16 @@ limacharlie sensor task upgrade_core --beta Optional flags: - `--force`: upgrade even if the sensor already reports the latest available release. -- `--version`: pin the exact release to install (e.g. `5.3.3`) instead of the latest; downgrades are allowed. +- `--version`: pin the exact release to install (e.g. `5.3.3`) instead of the latest. Downgrades are allowed. !!! note -The `upgrade_core` command requires sensor version **5.3.3 or later**. Sensors running an older version silently drop the request and no upgrade takes place. +The `upgrade_core` command needs sensor version **5.3.3 or later**. A sensor with an older version drops the request without a message, and no upgrade occurs. See the [endpoint commands reference](../../8-reference/endpoint-commands.md#upgrade_core) for more detail. ## Advanced: Forcing an Upgrade -By default an in-place upgrade (`-u`) only replaces the installed service when the supplied binary is newer than what is installed. To re-apply or move to a build that is not strictly newer (for example to re-deploy a known-good version), set the `LC_UPGRADE_SKIP_VERSION_CHECK` environment variable to `1` (or `true`) on the upgrade process. This bypasses the version comparison and replaces the installed service unconditionally. +By default, an in-place upgrade (`-u`) replaces the installed service only when the supplied binary is newer than the installed binary. To re-apply a build, or to move to a build that is not newer, set the `LC_UPGRADE_SKIP_VERSION_CHECK` environment variable to `1` (or `true`) on the upgrade process. For example, use the variable to deploy a known-good version again. The variable skips the version comparison and always replaces the installed service. !!! warning -Use this only when you intend to override the version check. The automatic rollback on a failed start still applies, but skipping the check makes it possible to deliberately downgrade the on-disk agent. +Set this variable only when you want to override the version check. The automatic rollback on a failed start still applies. But without the version check, you can downgrade the on-disk agent deliberately. diff --git a/docs/2-sensors-deployment/endpoint-agent/sleeper.md b/docs/2-sensors-deployment/endpoint-agent/sleeper.md index 8535420f0..94f829997 100644 --- a/docs/2-sensors-deployment/endpoint-agent/sleeper.md +++ b/docs/2-sensors-deployment/endpoint-agent/sleeper.md @@ -1,30 +1,30 @@ # Sleeper Deployment -LimaCharlie's usage-based billing enables incident responders to offer pre-deployments to their customers at almost zero cost. That is, they can deploy across an Organization's entire fleet and lay dormant in 'sleeper mode' at a cost of just $0.10 per 30 days. With agents deployed ahead of an incident, responders can offer competitive SLAs. +The usage-based billing of LimaCharlie lets incident responders offer pre-deployments to their customers at almost no cost. Responders can deploy across the full fleet of an Organization. The sensors stay dormant in 'sleeper mode' at a cost of $0.10 per 30 days. Agents that are deployed before an incident let responders offer competitive SLAs. -> Have more questions? +> More questions? > -> For more details on sleeper mode deployments, feel free to contact us at [answers@limacharlie.io](mailto:answers@limacharlie.io) or book a quick call with the engineering team to discuss your use case. +> For more details about sleeper mode deployments, contact LimaCharlie at [answers@limacharlie.io](mailto:answers@limacharlie.io). You can also book a call with the engineering team to discuss your use case. -Sleeper billing uses the following metrics: +Sleeper billing uses these metrics: | Connected Time | Events Processed | Events Retained | | --- | --- | --- | | $0.10 per 30 days | $0.67 per 100,000 events | $0.17 per 100,000 events | -Using sleeper deployments is done via Sensor tagging. Applying the `lc:sleeper` Tag to a Sensor will stop LimaCharlie telemetry collection activity on the host. Within 10 minutes of the tag being applied, the sensor will enter sleeper mode and will be billed only for its "Connected Time" as outlined above. If the tag is removed, normal operations resume within 10 minutes. +You control sleeper deployments with Sensor tags. The `lc:sleeper` Tag on a Sensor stops the collection of LimaCharlie telemetry on the host. The sensor enters sleeper mode in 10 minutes or less after you apply the tag. LimaCharlie then bills only the "Connected Time" shown above. If you remove the tag, normal operation returns in 10 minutes or less. -Using sleeper mode requires the organization in question to have billing enabled (a quota of at least 3 to be outside of the free tier). +Sleeper mode needs the organization to have billing enabled. The quota must be at least 3 to be outside the free tier. -This means a sample scenario around pre-deploying in an enterprise could look something like this: +An example of a pre-deployment in an enterprise can be: 1. Create a new Organization in LimaCharlie. 2. Set the Quota to 3 to enable billing. 3. Create a new Installation Key, and set the `lc:sleeper` tag on the key. -4. Enroll any number of EDR sensors. Charges will apply as specified above. For example, if you deploy 100 Sensors in sleeper mode, total monthly costs will be $10. -5. Whenever you need to "wake up" and use some of the EDRs, set the Quota to the number of Sensors you need (e.g. if you want to wake up 5 sensors, set the quota to at least 5), remove the `lc:sleeper` tag from the specific Sensors, and within 10 minutes they will be online, billed according to the quota. -6. When you're done, just re-add the `lc:sleeper` tag and lower the Quota back down. +4. Enroll any number of EDR sensors. The charges above apply. For example, 100 Sensors in sleeper mode cost $10 each month. +5. Set the Quota to the number of Sensors that you need to "wake up". For example, to wake up 5 sensors, set the quota to at least 5. Remove the `lc:sleeper` tag from those Sensors. The Sensors come online in 10 minutes or less, and LimaCharlie bills them against the quota. +6. Add the `lc:sleeper` tag again when you finish, then lower the Quota. -Switching to sleeper mode does not change the binary on disk, however, the code running in memory does change. Whether putting an org into sleeper mode or changing versions, the binary on disk remains as-is. +A change to sleeper mode does not change the binary on disk, but the code in memory does change. The binary on disk stays the same when you put an org into sleeper mode and when you change versions. -The changes to sleeper mode go into effect without the need for a reboot. In sleeper mode, activities such as read other process' memory (e.g. [YARA](../../5-integrations/extensions/third-party/yara.md)) will stop. +The changes to sleeper mode take effect without a reboot. In sleeper mode, operations that read the memory of other processes stop. A [YARA](../../5-integrations/extensions/third-party/yara.md) scan is an example of such an operation. diff --git a/docs/2-sensors-deployment/endpoint-agent/uninstallation.md b/docs/2-sensors-deployment/endpoint-agent/uninstallation.md index 913bb7059..6acf3fdd2 100644 --- a/docs/2-sensors-deployment/endpoint-agent/uninstallation.md +++ b/docs/2-sensors-deployment/endpoint-agent/uninstallation.md @@ -1,12 +1,12 @@ # Endpoint Agent Uninstallation -There are multiple options available to uninstall the LimaCharlie Sensor, depending on the operating system and/or method of installation. macOS and Windows systems allow for easy uninstallation via sensor commands or rules. Linux systems may require additional steps, as detailed below. +You can uninstall the LimaCharlie Sensor in more than one way. The method depends on the operating system and on the installation method. On macOS and Windows, you can uninstall with sensor commands or with rules. Linux systems can need more steps, as described below. ## Manually Uninstalling the Endpoint Agent -When uninstalling macOS and Windows Sensors, please attempt to utilize a method similar to sensor deployment. For example, if sensors were deployed via a package manager, then the same package manager may have uninstall options as well. This will help keep software inventories up to date. +To uninstall macOS and Windows Sensors, use a method that is similar to the deployment method. For example, if you deployed the sensors with a package manager, the same package manager can have uninstall options. This keeps software inventories up to date. -Details on manual uninstallation is found at the bottom of each respective OS' installation procedures. +The installation procedure for each operating system gives details about manual uninstallation at the end. ## Uninstalling Endpoint Agents from the Platform @@ -14,26 +14,26 @@ Details on manual uninstallation is found at the bottom of each respective OS' i For macOS and Windows operating systems, you can uninstall a sensor with the `uninstall` command. See the [endpoint commands reference](../../8-reference/endpoint-commands.md#uninstall) for more detail. -On Windows, the command defaults to uninstalling the sensor as if installed from the direct installer exe. If an MSI was used for installation, you can add a `--msi` flag to the `uninstall` command to trigger an uninstallation that is compatible with MSI. +On Windows, the command uninstalls the sensor as if you installed it from the direct installer exe. If you installed the sensor with an MSI, add the `--msi` flag to the `uninstall` command. The flag starts an uninstallation that is compatible with MSI. #### Native vs Legacy Uninstall -By default, the `uninstall` command uses the legacy procedure: the sensor runs a shell command that invokes the on-disk agent's own uninstaller. This works on every sensor version. +By default, the `uninstall` command uses the legacy procedure. The sensor runs a shell command that calls the uninstaller of the on-disk agent. This works on every sensor version. -Adding the `--native` flag instead instructs the sensor to uninstall itself using its built-in (native) uninstall procedure, without spawning a shell command: +The `--native` flag tells the sensor to uninstall itself with its built-in (native) uninstall procedure. The sensor does not start a shell command: ```bash uninstall --is-confirmed --native ``` !!! note - The `--native` flag requires sensor version **5.3.3 or later**. Sensors running an older version silently ignore the native uninstall request — the task appears to be sent successfully, but nothing happens on the endpoint. If you are unsure of a sensor's version, omit `--native` to use the legacy procedure. + The `--native` flag needs sensor version **5.3.3 or later**. A sensor with an older version ignores the native uninstall request without a message. The task looks successful, but nothing occurs on the endpoint. If you do not know the version of a sensor, omit `--native` to use the legacy procedure. -The `--msi` flag takes precedence over `--native`: the native procedure does not unregister the MSI product, so sensors installed via MSI should continue to use `--msi`. +The `--msi` flag takes precedence over `--native`. The native procedure does not unregister the MSI product. For sensors that you installed with an MSI, continue to use `--msi`. ### SDK -To run the uninstall command against *all* Sensors, a simple loop with the SDK in Python would work: +To run the uninstall command against *all* Sensors, use a loop with the Python SDK: ```python from limacharlie.client import Client @@ -49,7 +49,7 @@ for sensor_info in org.list_sensors(): ### Using a D&R Rule -As an alternative approach, you can also use a Detection & Response (D&R) rule to automatically trigger an uninstall of the LimaCharlie sensor when a sensor connects to the LimaCharlie cloud. Below is an example of the rule you can use for this purpose. This example is specific to Windows-based endpoints, but can be modified based on your needs: +You can also use a Detection & Response (D&R) rule to start an uninstall of the LimaCharlie sensor automatically. The rule runs when a sensor connects to the LimaCharlie cloud. The example rule below is for Windows endpoints, but you can change it for your needs: ```yaml # Detect @@ -65,4 +65,4 @@ op: is windows ## Package Management Tools -For Package Management tools, and other enterprise application-management tools, we recommend utilizing the integrated program removal options, rather than installing from LimaCharlie. This will help keep software inventories up to date. +For Package Management tools, and other enterprise tools that manage applications, use the integrated options that remove programs, and not an installation from LimaCharlie. This keeps software inventories up to date. diff --git a/docs/2-sensors-deployment/endpoint-agent/vdi/templates.md b/docs/2-sensors-deployment/endpoint-agent/vdi/templates.md index 33c10fbc4..5fad45a92 100644 --- a/docs/2-sensors-deployment/endpoint-agent/vdi/templates.md +++ b/docs/2-sensors-deployment/endpoint-agent/vdi/templates.md @@ -1,25 +1,25 @@ # VDI & Virtual Machine Templates -The LimaCharlie Endpoint Agent can be installed in template-based environments whether they're VMs or VDIs. +You can install the LimaCharlie Endpoint Agent in template-based environments, both VMs and VDIs. -The methodology is the same as described above, but you need to be careful to stage the Endpoint Agent install properly in your templates. +The method is the same as the method described above. But you must stage the installation of the Endpoint Agent correctly in your templates. -The most common mistake is to install the Sensor directly in the template, and then instantiate the rest of the infrastructure from this template. This will result in "cloned sensors", sensors running using the same Sensor ID on different hosts/VMs/Containers. +The most common mistake is to install the Sensor directly in the template and then create the rest of the infrastructure from that template. The result is "cloned sensors": sensors that run with the same Sensor ID on different hosts, VMs, or containers. -If these occur, a [sensor\_clone](../../../8-reference/platform-events.md#sensor_clone) event will be generated as well as an error in your dashboard. If this happens you have two choices: +If cloned sensors occur, LimaCharlie generates a [sensor\_clone](../../../8-reference/platform-events.md#sensor_clone) event and shows an error in your dashboard. You then have two choices: 1. Fix the installation process and re-deploy. -2. Run a de-duplication process with a Detection & Response rule [like this](../../../3-detection-response/examples.md#de-duplicate-cloned-sensors). +2. Run a de-duplication process with a [Detection & Response rule that de-duplicates cloned sensors](../../../3-detection-response/examples.md#de-duplicate-cloned-sensors). -Preparing sensors to run properly from templates can be done by creating a special `hcp_vdi` (macOS and Linux) or `hcp_vdi.dat` (Windows) file in the relevant configuration directory: +To prepare sensors to run correctly from templates, create a special `hcp_vdi` (macOS and Linux) or `hcp_vdi.dat` (Windows) file in the applicable configuration directory: - Windows: `%SYSTEMROOT%\system32\` - macOS: `/usr/local/` -- Linux: usually `/etc/` but fundamentally the current working directory of the sensor execution. +- Linux: usually `/etc/`, but it is the current working directory of the sensor process. -The contents of the `hcp_vdi` file should be a string representation of the second-based epoch timestamp when you want the sensors to begin enrolling. For example if the current time is `1696876542`, setting a value of `1696882542` will mean the sensor will only attempt to enroll in 10 minutes in the future. This allows you to install the sensor without risking it enrolling right away before the base image is created. +The content of the `hcp_vdi` file must be a string with the epoch timestamp in seconds when the sensors start to enroll. For example, if the current time is `1696876542`, a value of `1696882542` makes the sensor try to enroll 10 minutes later. You can then install the sensor without a risk that it enrolls before you create the base image. -A shortcut for creating this file is to invoke the LimaCharlie EDR binary (like `lc_sensor.exe`) with the `-t` option, which will create a `hcp_vdi.dat` file with a value +1 day. This is usually plenty of time to finish the creation of the base image, submit it to a VDI platform (which often boots up the image) etc. The next day, any machine generated from this base image will start enrolling. +To create this file quickly, run the LimaCharlie EDR binary (for example `lc_sensor.exe`) with the `-t` option. The option creates a `hcp_vdi.dat` file with a value of +1 day. This is usually enough time to create the base image and to submit it to a VDI platform, which often starts the image. The next day, each machine that comes from this base image starts to enroll. Example `hcp_vdi.dat` file content: @@ -27,4 +27,4 @@ Example `hcp_vdi.dat` file content: 1696882542 ``` -Note that if a sensor is already enrolled, the presence of the `hcp_vdi` file will be completely ignored. +If a sensor is already enrolled, the sensor ignores the `hcp_vdi` file completely. diff --git a/docs/2-sensors-deployment/endpoint-agent/versioning-upgrades.md b/docs/2-sensors-deployment/endpoint-agent/versioning-upgrades.md index 54dedd62f..ae95b4074 100644 --- a/docs/2-sensors-deployment/endpoint-agent/versioning-upgrades.md +++ b/docs/2-sensors-deployment/endpoint-agent/versioning-upgrades.md @@ -1,36 +1,36 @@ # Endpoint Agent Versioning and Upgrades -LimaCharlie frequently releases new versions of the endpoint agent (typically every few weeks), giving you full control over which version runs in your Organization. Sensors are not updated by default, allowing you to manage versioning and deployment as needed. +LimaCharlie releases new versions of the endpoint agent often, usually every few weeks. You control which version runs in your Organization. Sensors do not update by default, so you manage versions and deployment yourself. ## Endpoint Agent Components -The LimaCharlie endpoint agent consists of two main components, each versioned independently: +The LimaCharlie endpoint agent has two main components, each with an independent version: -1. **On-disk agent**: Implements core identity, cryptography, and transport mechanisms. This component rarely requires updates and typically remains static. -2. **Over-the-air core**: The main component that receives frequent updates and delivers advanced functionality. It can be easily updated via the LimaCharlie cloud. +1. **On-disk agent**: Supplies core identity, cryptography, and transport mechanisms. This component needs updates rarely and usually stays the same. +2. **Over-the-air core**: The main component that gets frequent updates and supplies advanced functions. You can update it through the LimaCharlie cloud. -When updates occur, they impact the over-the-air component, as it's the easiest to modify, with the update size generally being around 3-5 MB. +Updates change the over-the-air component, because it is the easiest component to change. The update size is usually about 3-5 MB. ## Version Labels -LimaCharlie provides three version labels to simplify version management: +LimaCharlie has three version labels that make version management easier: 1. **Latest**: The most recent release with new fixes and features. -2. **Stable**: A less frequently updated version, ideal for maintaining slower update cadences. +2. **Stable**: A version with fewer updates. Use it to keep a slower update rate. 3. **Experimental**: The beta version of the next "Latest" release. -You can upgrade to any of these version labels for your organization by using the LimaCharlie web interface or the [API](https://api.limacharlie.io/static/swagger/#/Modules/upgradeOrg). +You can upgrade your organization to any of these version labels. Use the LimaCharlie web interface or the [API](https://api.limacharlie.io/static/swagger/#/Modules/upgradeOrg). ### Upgrading to Specific Versions -In addition to using version labels, you can upgrade your organization to a specific sensor version using semantic version strings (e.g., `4.33.20`). This is useful when: +You can also upgrade your organization to a specific sensor version with a semantic version string (for example, `4.33.20`). Use a specific version when: -- You need to pin your organization to a specific tested version -- You want to maintain version consistency across multiple organizations -- You need to rollback to a previous version for compatibility reasons -- You're testing a specific version before broader deployment +- You must pin your organization to a specific tested version +- You want the same version in many organizations +- You must roll back to a previous version for compatibility +- You test a specific version before a wider deployment -To upgrade or manage sensors using the API: +To upgrade or manage sensors with the API: ```bash # Upgrade to a specific version @@ -54,34 +54,42 @@ curl -X POST "https://api.limacharlie.io/v1/modules/{oid}?is_sleep=true" \ -H "Content-Type: application/json" ``` -**Note**: Specific version strings follow semantic versioning format (MAJOR.MINOR.PATCH) and must correspond to an available LimaCharlie sensor release. If you specify an invalid or unavailable version, the API will return an error. +**Note**: Specific version strings use the semantic versioning format (MAJOR.MINOR.PATCH). The string must match an available LimaCharlie sensor release. If you give an invalid or unavailable version, the API returns an error. ## Managing Versioning for Sensors -To manage the versioning of sensors, you can leverage LimaCharlie's **System** Tags: +To manage the versions of sensors, use LimaCharlie's **System** Tags: - `lc:latest`: Tags the Sensor to receive the most recent version. - - This tag is primarily intended for testing `latest` sensor version against a small set of representative sensors before org-wide upgrades to `latest`. + - Use this tag mainly to test the `latest` sensor version on a small set of representative sensors, before you upgrade the full org to `latest`. - `lc:stable`: Tags the sensor to receive a stable version. - `lc:experimental`: Tags the sensor to receive the experimental version. -These tags can be applied to individual sensors to alter version behavior, and updates take effect within 10 minutes. This method also enables staging deployments to test updates on a small group of sensors before organization-wide rollouts. +Apply these tags to individual sensors to change the version behavior. The updates take effect in 10 minutes or less. You can also stage deployments with these tags, and test updates on a small group of sensors before an organization-wide rollout. ## Updating Endpoint Agents ### Best Practices -When deploying new sensor versions, follow a controlled testing approach by first applying the `lc:latest` tag to a small subset of representative systems across different operating systems and workloads. Monitor these test systems for a period of time, evaluating stability, performance, and telemetry quality. If testing is successful, update the organization-level sensor version and remove the `lc:latest` tag from test systems, while maintaining a rollback plan and monitoring system health during the deployment. Note that the `lc:latest` sensor tag should primarily be used for upgrade testing purposes, as it automatically updates sensors to new versions as they are released. +To deploy a new sensor version, use a controlled test: + +1. Apply the `lc:latest` tag to a small set of representative systems. Include different operating systems and workloads. +2. Monitor these test systems for a period of time. Evaluate stability, performance, and the quality of the telemetry. +3. If the test is successful, update the sensor version at the organization level. +4. Remove the `lc:latest` tag from the test systems. +5. Keep a rollback plan, and monitor the health of the systems during the deployment. + +Use the `lc:latest` sensor tag mainly for upgrade tests, because it updates sensors to each new version automatically at its release. ### Manual Update -You can manually trigger an update for all endpoint agents in your organization by simply clicking a button in the web interface. This action updates the over-the-air component of the sensors within 20 minutes, with no need to re-download installers, as the installer remains unchanged. +To start an update for all endpoint agents in your organization, click a button in the web interface. The action updates the over-the-air component of the sensors in 20 minutes or less. You do not download the installers again, because the installer does not change. ### Auto-Update -To automate updates, apply the `lc:stable` tag to your sensors. This will ensure that sensors automatically update to the latest stable version upon release. +To automate updates, apply the `lc:stable` tag to your sensors. The sensors then update to the latest stable version automatically at its release. ### Staged Deployment -For testing new versions, tag specific sensors with `lc:latest` to run the latest version without affecting the rest of your organization. This allows you to test new releases on selected hosts before proceeding with a full rollout. +To test new versions, tag specific sensors with `lc:latest`. These sensors run the latest version, and the rest of your organization does not change. You can test new releases on selected hosts before a full rollout. diff --git a/docs/2-sensors-deployment/endpoint-agent/windows/custom-msi.md b/docs/2-sensors-deployment/endpoint-agent/windows/custom-msi.md index 29593f901..3dcd3550f 100644 --- a/docs/2-sensors-deployment/endpoint-agent/windows/custom-msi.md +++ b/docs/2-sensors-deployment/endpoint-agent/windows/custom-msi.md @@ -1,15 +1,15 @@ # Building a custom MSI installer for Windows -> **Looking for basic installation instructions?** See the [Windows Agent Installation](installation.md) guide for standard EXE and MSI installation methods. +> **For basic installation instructions**, see the [Windows Agent Installation](installation.md) guide. It gives the standard EXE and MSI installation methods. -You can white label the LimaCharlie installer for Windows by using an MSI wrapper. By going through this process you can not only brand the installer to show your name / details, but you can also make installation of the Sensor easier for end users. We have provided instructions below on how to use a 3rd party tool called [exemsi](https://www.exemsi.com/). +You can white label the LimaCharlie installer for Windows with an MSI wrapper. The wrapper shows your name and your details on the installer. It also makes the installation of the Sensor easier for end users. The instructions below use a third-party tool, [exemsi](https://www.exemsi.com/). ## Prerequisites -1. An MSI wrapper application, such as the exemsi application referenced in the instructions below +1. An MSI wrapper application, such as the exemsi application in the instructions below 2. A digital code signing certificate (optional, but highly recommended) -Without a digital code signing certificate the installer will show a warning that it is from an unknown publisher. +Without a digital code signing certificate, the installer shows a warning that it is from an unknown publisher. ![UAC Signed](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/uac-signed.png) @@ -21,35 +21,35 @@ Without a digital code signing certificate the installer will show a warning tha 1. Download the [LimaCharlie sensor EXE](https://downloads.limacharlie.io/sensor/windows/64) 2. Download the [MSI Wrapper application from exemsi.com](https://exemsi.com) 3. Install the exemsi application on your computer -4. Launch the exemsi application and go through the EXE to MSI Converter Wizard steps as shown below: +4. Start the exemsi application. Do the steps of the EXE to MSI Converter Wizard that follow. -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_1_-_First_screen_after_launch.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_1_-_First_screen_after_launch.png) -1. Select the executable +5. Select the executable -- Set the `Setup executable input file name` to be the LimaCharlie EXE that you'd downloaded -- Optionally, specify a MSI output file name of your choosing (e.g. Acme\_Installer.msi) -- Set the MSI platform architecture to match the executable (i.e. x86 for 32-bit, and x64 for 64-bit) + - Set the `Setup executable input file name` to the LimaCharlie EXE that you downloaded + - Optionally, set an MSI output file name of your choice (for example, Acme\_Installer.msi) + - Set the MSI platform architecture to match the executable (x86 for 32-bit, and x64 for 64-bit) -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_2_-__Select_the_executable.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_2_-__Select_the_executable.png) -1. Set the visibility in Apps & features +6. Set the visibility in Apps & features -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_3_-_Visibility_in_Apps_&_features.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_3_-_Visibility_in_Apps_&_features.png) -1. Set the Security and User Context +7. Set the Security and User Context -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_4_-_Security_and_User_Context.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_4_-_Security_and_User_Context.png) -1. Specify Application IDs +8. Specify Application IDs -- In the Upgrade Code section, click the "Create New" button next to generate a code. This will be used to allow uninstallation. + - In the Upgrade Code section, click the "Create New" button to generate a code. The code allows uninstallation. -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_5_-_Application_Ids.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_5_-_Application_Ids.png) -1. Specify Properties (optional: customize options here to have the installer show your brand) +9. Specify Properties (optional: change these options to show your brand on the installer) -- You can change the drop-down menu of each line item from "Executable" to "Manual" in order to set your own values for the Product Name, Manufacturer, Version, Comments, and Product icon + - Change the drop-down menu of each line item from "Executable" to "Manual" to set your own values for the Product Name, Manufacturer, Version, Comments, and Product icon ### Original @@ -61,41 +61,41 @@ Without a digital code signing certificate the installer will show a warning tha 1. Specify More Properties (optional) -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_7_-_More_properties.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_7_-_More_properties.png) 1. Specify Parameters -- In the "Install arguments" box, enter "-i", add a space and then enter your [installation key](../../installation-keys.md) -- -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE + - In the "Install arguments" box, enter "-i", then a space, then your [installation key](../../installation-keys.md) + - -i YOUR\_INSTALLATION\_KEY\_GOES\_HERE -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_8b_-_Parameters_-_filled.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_8b_-_Parameters_-_filled.png) -To provide the option to uninstall, set the Uninstall argument to "-c" (note that you do not need to specify your Installation Key for uninstallation). +To allow uninstallation, set the Uninstall argument to "-c". You do not need your Installation Key to uninstall. 1. Actions -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_9_-_Actions.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_9_-_Actions.png) 1. Summary -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_10_-_Summary.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_10_-_Summary.png) 1. Status -![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_11_-_Status.png) + ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Wrapper_-_11_-_Status.png) -Once you have created the MSI package you should sign it using your digital signature. You can [learn more about signing the MSI on the exemsi website](https://www.exemsi.com/documentation/sign-your-msi/). +After you create the MSI package, sign it with your digital signature. For more information, see [how to sign the MSI on the exemsi website](https://www.exemsi.com/documentation/sign-your-msi/). ## Experience when running the MSI -When installing the application using the MSI you'll see your application name in the title bar. +When you install the application with the MSI, the title bar shows your application name. ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/MSI_Installation.png) -When inspecting the properties of the MSI you'll see the details you'd specified. +When you inspect the properties of the MSI, you see the details that you specified. ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/Created_MSI_Properties-Details.png) -In the Apps & Features section of Windows, you'll see the application listed under your name. +In the Apps & Features section of Windows, the application shows under your name. ![exemsi](https://storage.googleapis.com/limacharlie-io/doc/white-label/exemsi-instructions/Shown_in_Control_Panel_-_Apps_and_Features.png) diff --git a/docs/2-sensors-deployment/endpoint-agent/windows/installation.md b/docs/2-sensors-deployment/endpoint-agent/windows/installation.md index 01224386f..e5872e800 100644 --- a/docs/2-sensors-deployment/endpoint-agent/windows/installation.md +++ b/docs/2-sensors-deployment/endpoint-agent/windows/installation.md @@ -1,6 +1,6 @@ # Windows Agent Installation -This guide walks you through installing the LimaCharlie Endpoint Detection and Response (EDR) sensor on Windows systems. The sensor provides deep visibility into your Windows endpoints, enabling real-time threat detection and response. +This guide explains how to install the LimaCharlie Endpoint Detection and Response (EDR) sensor on Windows systems. The sensor gives visibility into your Windows endpoints for threat detection and response in real time. ## Supported Windows Versions @@ -20,7 +20,7 @@ This guide walks you through installing the LimaCharlie Endpoint Detection and R ## Prerequisites -Before installing the LimaCharlie sensor, ensure you have: +Before you install the LimaCharlie sensor, make sure that you have: 1. **Administrator privileges** on the Windows system 2. **An Installation Key** from your LimaCharlie organization @@ -28,17 +28,17 @@ Before installing the LimaCharlie sensor, ensure you have: ## Getting Your Installation Key -An Installation Key is required to enroll your sensor with the LimaCharlie cloud. To obtain your key: +You need an Installation Key to enroll your sensor with the LimaCharlie cloud. To get your key: 1. Log in to the [LimaCharlie web application](https://app.limacharlie.io) 2. Select your organization -3. Navigate to **Sensors** > **Installation Keys** in the left sidebar -4. Copy an existing key, or create a new one by clicking **Create Installation Key** -5. Keep this key ready - you'll need it during installation +3. Go to **Sensors** > **Installation Keys** in the left sidebar +4. Copy an existing key, or click **Create Installation Key** to make a new key +5. Keep this key ready. You need it during the installation -For more details on managing keys, see [Installation Keys](../../installation-keys.md). +For more information about how to manage keys, see [Installation Keys](../../installation-keys.md). -> **Tip:** Installation keys can have tags associated with them. When a sensor enrolls using a key with tags, those tags are automatically applied to the sensor. +> **Tip:** An installation key can have tags. When a sensor enrolls with a key that has tags, the cloud applies those tags to the sensor. ## Downloading the Sensor @@ -52,7 +52,7 @@ Choose the correct download for your system architecture: | 32-bit (x86) | [https://downloads.limacharlie.io/sensor/windows/32](https://downloads.limacharlie.io/sensor/windows/32) | | ARM64 | [https://downloads.limacharlie.io/sensor/windows/arm64](https://downloads.limacharlie.io/sensor/windows/arm64) | -> **Note:** A native ARM64 build is available for Windows on ARM devices (sensor 4.33.26 or later). Earlier sensor versions ran under x64 emulation; this is no longer required. +> **Note:** A native ARM64 build is available for Windows on ARM devices (sensor 4.33.26 or later). Earlier sensor versions ran under x64 emulation. Emulation is no longer necessary. ### MSI Installer Downloads @@ -62,9 +62,9 @@ Choose the correct download for your system architecture: | 32-bit (x86) | [https://downloads.limacharlie.io/sensor/windows/msi32](https://downloads.limacharlie.io/sensor/windows/msi32) | | ARM64 | [https://downloads.limacharlie.io/sensor/windows/msiarm64](https://downloads.limacharlie.io/sensor/windows/msiarm64) | -> **Note about downloaded filenames:** The downloaded file will have a versioned name like `hcp_win_x64_release_4.33.23.exe`. You can rename it to `rphcp.exe` for convenience, or use the original filename in commands. +> **Note about downloaded filenames:** The downloaded file has a versioned name such as `hcp_win_x64_release_4.33.23.exe`. You can rename it to `rphcp.exe`, or use the original filename in commands. > -> **How do I know which architecture I need?** +> **How to find the architecture that you need** > > On Windows 10/11: Go to **Settings** > **System** > **About** and look at **System type**. > @@ -72,7 +72,7 @@ Choose the correct download for your system architecture: ## Command-Line Options -When running the installer from the command line, you can use the following options: +When you run the installer from the command line, you can use these options: | Option | Description | |--------|-------------| @@ -80,10 +80,10 @@ When running the installer from the command line, you can use the following opti | `-d ` | Run with installation key (temporary, no permanent installation) | | `-r` | Uninstall the service | | `-c` | Uninstall the service and delete identity files (clean uninstall) | -| `-V` | Display the sensor version | +| `-V` | Show the sensor version | | `-v` | Enable verbose logging output | -| `-H` | Verify sensor health and installation | -| `-h` | Display help message | +| `-H` | Check sensor health and installation | +| `-h` | Show the help message | For the complete list of options, environment variables, and local files, see the [Agent CLI & Environment Reference](../cli-reference.md). @@ -91,7 +91,7 @@ For the complete list of options, environment variables, and local files, see th ### Method 1: Executable (EXE) Installation -This method is recommended for installing on individual systems. +This method is recommended for the installation on individual systems. **Step 1:** Download the appropriate EXE for your architecture (see download links above). @@ -99,7 +99,7 @@ This method is recommended for installing on individual systems. > To run as Administrator: Right-click Command Prompt or PowerShell and select **Run as administrator**. -**Step 3:** Navigate to the folder where you downloaded the installer: +**Step 3:** Go to the folder where you downloaded the installer: ```bash cd C:\Users\YourUsername\Downloads @@ -111,27 +111,27 @@ cd C:\Users\YourUsername\Downloads rphcp.exe -i YOUR_INSTALLATION_KEY_GOES_HERE ``` -Replace `YOUR_INSTALLATION_KEY_GOES_HERE` with the actual key you copied from the LimaCharlie web application. +Replace `YOUR_INSTALLATION_KEY_GOES_HERE` with the key that you copied from the LimaCharlie web application. -**Step 5:** Wait for the installation to complete. You should see output indicating successful installation and service start. +**Step 5:** Wait for the installation to complete. The output shows that the installation is successful and that the service started. -The sensor is now installed and running as a Windows service. It will start automatically when Windows boots. +The sensor is now installed and runs as a Windows service. It starts automatically when Windows boots. ### Method 2: MSI Installation -MSI installers are ideal for enterprise deployment using tools like Group Policy, SCCM, or Intune. +MSI installers are best for enterprise deployment with tools such as Group Policy, SCCM, or Intune. #### Interactive Installation -1. Download the appropriate MSI for your architecture -2. Double-click the MSI file to launch the installer -3. Follow the installation prompts +1. Download the correct MSI for your architecture +2. Double-click the MSI file to start the installer +3. Obey the installation prompts -> **Note:** The MSI installation will require you to provide the Installation Key. Ensure you have it ready. +> **Note:** The MSI installation asks you for the Installation Key. Make sure that you have it ready. #### Silent Installation (Command Line) -For automated deployments, use the following command in an elevated Command Prompt or PowerShell: +For automated deployments, use this command in an elevated Command Prompt or PowerShell: ```batch msiexec /i "path\to\installer.msi" /qn INSTALLATIONKEY="YOUR_INSTALLATION_KEY_GOES_HERE" @@ -151,9 +151,9 @@ Options explained: ### Method 3: PowerShell Script (Automated) -This script automates the download and installation process. It detects your system architecture and downloads the correct installer. +This script does the download and the installation automatically. It detects your system architecture and downloads the correct installer. -> **Note:** This script requires PowerShell 3.0 or later. Windows 7 and Server 2008 R2 ship with PowerShell 2.0 by default; you may need to install [Windows Management Framework 3.0+](https://www.microsoft.com/en-us/download/details.aspx?id=34595) first. +> **Note:** This script needs PowerShell 3.0 or later. Windows 7 and Server 2008 R2 include PowerShell 2.0 by default. On these systems, it is possible that you must first install [Windows Management Framework 3.0+](https://www.microsoft.com/en-us/download/details.aspx?id=34595). Save this script as `Install-LimaCharlie.ps1`: @@ -235,7 +235,7 @@ Remove-Item $InstallerPath -Force -ErrorAction SilentlyContinue **To run the script:** 1. Open PowerShell as Administrator -2. If you haven't already, allow script execution: +2. If script execution is not yet allowed, allow it: ```powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser @@ -249,13 +249,13 @@ Remove-Item $InstallerPath -Force -ErrorAction SilentlyContinue ## Verifying Installation -After installation, verify that the sensor is running correctly using any of these methods: +After the installation, check that the sensor runs correctly. Use any of these methods: ### Windows Services GUI 1. Press `Win + R`, type `services.msc`, and press Enter 2. Scroll down to find **LimaCharlie** in the list -3. Verify that the **Status** is **Running** and **Startup Type** is **Automatic** +3. Check that the **Status** is **Running** and the **Startup Type** is **Automatic** ### PowerShell @@ -285,7 +285,7 @@ Look for `STATE : 4 RUNNING` in the output. ### Verification Script -Save and run this PowerShell script for a quick status check: +Save and run this PowerShell script to check the status: ```powershell # Verify LimaCharlie installation @@ -306,56 +306,56 @@ if ($null -eq $service) { ### LimaCharlie Web Application 1. Log in to [app.limacharlie.io](https://app.limacharlie.io) -2. Navigate to **Sensors** in the left sidebar -3. Your newly installed sensor should appear in the list within a few minutes +2. Go to **Sensors** in the left sidebar +3. The new sensor shows in the list after a few minutes ## Troubleshooting ### "Access Denied" Error -**Cause:** The installer must be run with Administrator privileges. +**Cause:** You must run the installer with Administrator privileges. -**Solution:** Right-click Command Prompt or PowerShell and select **Run as administrator** before running the installer. +**Solution:** Right-click Command Prompt or PowerShell and select **Run as administrator**. Then run the installer. ### Architecture Mismatch Error -**Cause:** Using a 32-bit installer on a 64-bit system (or vice versa). +**Cause:** You used a 32-bit installer on a 64-bit system, or a 64-bit installer on a 32-bit system. -**Solution:** Download and use the correct installer for your system architecture. The sensor will display an error message indicating the mismatch. +**Solution:** Download and use the correct installer for your system architecture. The sensor shows an error message about the mismatch. ### Antivirus Blocking Installation -**Cause:** Some antivirus software may flag the sensor installer. +**Cause:** Some antivirus software can flag the sensor installer. **Solution:** -1. Temporarily disable your antivirus during installation, OR +1. Disable your antivirus for the time of the installation, OR 2. Add an exclusion for `rphcp.exe` and `C:\Windows\System32\rphcp.exe` -3. Contact your antivirus vendor if issues persist +3. If the problem continues, contact your antivirus vendor ### Firewall Blocking Connection **Cause:** The sensor cannot reach LimaCharlie cloud services. -**Solution:** Ensure outbound HTTPS (port 443) traffic is allowed to: +**Solution:** Allow outbound HTTPS traffic on port 443 to: - `*.limacharlie.io` ### Installation Key Errors -**Cause:** The installation key is invalid, expired, or incorrectly copied. +**Cause:** The installation key is invalid, expired, or copied incorrectly. **Solution:** -1. Verify the key in the LimaCharlie web application -2. Ensure you copied the entire key without extra spaces -3. Check that the key hasn't been revoked or expired +1. Check the key in the LimaCharlie web application +2. Make sure that you copied the full key with no extra spaces +3. Check that the key is not revoked and not expired ### Service Won't Start -**Cause:** Various issues including file permission problems or system configuration. +**Cause:** Different problems, such as file permissions or the system configuration. **Solution:** 1. Check Windows Event Viewer (Application and System logs) for errors -2. Ensure the system meets minimum requirements -3. Try reinstalling with the `-c` flag first to clean up, then install fresh +2. Make sure that the system meets the minimum requirements +3. Run the installer with the `-c` flag to clean up, then install again ## Uninstallation @@ -371,7 +371,7 @@ rphcp.exe -c This removes the service and deletes all identity files. -To uninstall but keep identity files (for potential reinstallation): +To uninstall but keep the identity files for a later installation: ``` @@ -385,7 +385,7 @@ rphcp.exe -r 2. Find **LimaCharlie** in the list 3. Click **Uninstall** -Or via command line: +Or use the command line: ``` @@ -395,9 +395,9 @@ msiexec /x "path\to\installer.msi" /qn ### Using LimaCharlie Console -You can remotely uninstall the sensor from the LimaCharlie web application: +You can uninstall the sensor remotely from the LimaCharlie web application: -1. Navigate to the sensor in the Sensors list +1. Go to the sensor in the Sensors list 2. Open the **Console** tab 3. Run the command: `uninstall` @@ -407,7 +407,7 @@ For more uninstallation options, see [Endpoint Agent Uninstallation](../uninstal ## Next Steps -Now that your sensor is installed, you can: +After the sensor is installed, you can: - [Configure Detection & Response rules](../../../3-detection-response/index.md) to detect threats - [Explore Sensor Commands](../../../8-reference/endpoint-commands.md) to interact with your endpoints diff --git a/docs/2-sensors-deployment/enterprise-deployment/chrome-enterprise.md b/docs/2-sensors-deployment/enterprise-deployment/chrome-enterprise.md index 171cf7534..885ae0b20 100644 --- a/docs/2-sensors-deployment/enterprise-deployment/chrome-enterprise.md +++ b/docs/2-sensors-deployment/enterprise-deployment/chrome-enterprise.md @@ -1,36 +1,37 @@ # ChromeOS with Google Chrome Enterprise -You can mass deploy the LimaCharlie Sensor for ChromeOS with Google Workspace and [Google Chrome Enterprise](https://chromeenterprise.google/). +You can deploy the LimaCharlie Sensor for ChromeOS to many devices with Google Workspace and [Google Chrome Enterprise](https://chromeenterprise.google/). ## Configuration 1. Log into Google Workspace Admin and go to [Devices -> Chrome -> Apps & extensions -> Users & Browsers](https://admin.google.com/ac/chrome/apps/user). -2. In the **Users & browsers** tab click the "+" button in the bottom right, then choose the option to "Add from Chrome Web Store". +2. In the **Users & browsers** tab, click the "+" button in the bottom right. Then select "Add from Chrome Web Store". 3. Search for the [LimaCharlie Sensor](https://chrome.google.com/webstore/detail/limacharlie-sensor/ljdgkaegafdgakkjekimaehhneieecki) extension and click Select. -4. Click on the LimaCharlie Sensor app to show the installation policy. +4. Click the LimaCharlie Sensor app to show the installation policy. 5. Set the "Installation Policy" to "Force install". -6. Set the "Policy for extensions" value as follows: +6. Set the "Policy for extensions" value to this: -```json -{ - "installation_key": { - "Value": "\"KEY\"" + ```json + { + "installation_key": { + "Value": "\"KEY\"" + } } -} -``` + ``` -IMPORTANT: Replace the text "KEY" with the actual value of your Installation Key, in particular the **Chrome Key** which you can obtain from within the LimaCharlie web app. + IMPORTANT: Replace the text "KEY" with the value of your Installation Key. Use the **Chrome Key**, which you can get from the LimaCharlie web app. *Example* ![App_Management_-_Admin_Console.png](../../assets/images/App_Management_-_Admin_Console.png) ## Verifying Configuration -ChromeOS endpoints should now start appearing within the related LimaCharlie Organization's sensor list. +ChromeOS endpoints now show in the sensor list of the related LimaCharlie Organization. -You can verify that the configuration was completed successfully by verifying on an individual endpoint. +To check that the configuration is correct, examine an individual endpoint. -1. Confirm that the LimaCharlie Sensor extension appears in the list of extensions. -2. Verify that the installation key got applied on the endpoint by going to: `chrome://policy` and look for the LimaCharlie Sensor. There you should see the Policy name set to `installation_key` and the Policy Value set with your installation key. The Source should list "Cloud". +1. Confirm that the LimaCharlie Sensor extension shows in the list of extensions. +2. Open `chrome://policy` and find the LimaCharlie Sensor. +3. Check that the Policy name is `installation_key` and that the Policy Value is your installation key. The Source is "Cloud". ![endpoint.png](../../assets/images/endpoint.png) diff --git a/docs/2-sensors-deployment/enterprise-deployment/intune.md b/docs/2-sensors-deployment/enterprise-deployment/intune.md index 4de7512ce..5bf2468e8 100644 --- a/docs/2-sensors-deployment/enterprise-deployment/intune.md +++ b/docs/2-sensors-deployment/enterprise-deployment/intune.md @@ -1,8 +1,8 @@ # Agent Deployment via Microsoft Intune -[Microsoft Intune](https://learn.microsoft.com/en-us/mem/) is a cloud-based endpoint management solution that integrates with Microsoft Azure. It allows for simplified app and device management across a wide range of devices, including mobile devices, desktop computers, and virtual endpoints. +[Microsoft Intune](https://learn.microsoft.com/en-us/mem/) is a cloud endpoint management solution that integrates with Microsoft Azure. It manages apps and devices on many device types, which include mobile devices, desktop computers, and virtual endpoints. -Intune can be used to simplify LimaCharlie Sensor deployment within enterprise environments. To add a custom App to Intune, select the `+ Add` button within the Intune admin center: +You can use Intune to deploy the LimaCharlie Sensor in enterprise environments. To add a custom App to Intune, select the `+ Add` button in the Intune admin center: ![image.png](../../assets/images/image(61).png) @@ -10,14 +10,14 @@ InTune supports Windows and macOS package deployment. ## Windows Deployment via Intune -Deploying Windows applications via Intune requires creating an Intune application package (`.intunewin` file extension). To do this, please utilize Microsoft's IntuneWinAppUtil.exe file. See Microsoft's [`.intunewin` packaging documentation](https://learn.microsoft.com/en-us/mem/intune/apps/apps-win32-prepare). +To deploy Windows applications with Intune, you must create an Intune application package (`.intunewin` file extension). Use Microsoft's IntuneWinAppUtil.exe file. See Microsoft's [`.intunewin` packaging documentation](https://learn.microsoft.com/en-us/mem/intune/apps/apps-win32-prepare). ### Intune Package Contents -Intune packages may need to be created for each Organization, as the Installation Key must be provided at the time of installation. +It is possible that you must create an Intune package for each Organization, because you must give the Installation Key at the time of installation. -We recommend first creating a [custom MSI installer](../endpoint-agent/windows/custom-msi.md), bundled with the appropriate installation key, and then including that in your `.intunewin` file. +LimaCharlie recommends that you first create a [custom MSI installer](../endpoint-agent/windows/custom-msi.md) with the correct installation key. Then include that installer in your `.intunewin` file. -After clicking `+ Add`, choose `Windows app (Win32)`: +After you click `+ Add`, select `Windows app (Win32)`: ![image.png](../../assets/images/image(63).png) diff --git a/docs/2-sensors-deployment/installation-keys.md b/docs/2-sensors-deployment/installation-keys.md index 631da228d..9ef7eff6f 100644 --- a/docs/2-sensors-deployment/installation-keys.md +++ b/docs/2-sensors-deployment/installation-keys.md @@ -1,48 +1,48 @@ # Installation Keys -Installation keys are Base64-encoded strings provided to Sensors and Adapters in order to associate them with the correct Organization. Installation keys are created per-organization and offer a way to label and control your deployment population. +Installation keys are Base64-encoded strings that you give to Sensors and Adapters to associate them with the correct Organization. You create installation keys for each organization. The keys let you label and control your deployment population. There are four components of an Installation Key: -- Organization ID **(**OID**)**: The Organization ID that this key should enroll into. -- **Installer ID (IID)**: Installer ID that is generated and associated with every Installation Key. -- **Tags**: A list of Tags automatically applied to sensors enrolling with the key. -- **Description**: The description used to help you differentiate uses of various keys. +- **Organization ID (OID)**: The Organization ID that this key enrolls into. +- **Installer ID (IID)**: The Installer ID that the cloud generates and associates with each Installation Key. +- **Tags**: A list of Tags that the cloud applies automatically to sensors that enroll with the key. +- **Description**: The description that helps you identify the use of each key. ## Management -Installation keys can be managed on the **Sensors > Installation Keys** page in the web app. +You manage installation keys on the **Sensors > Installation Keys** page in the web app. -On this page, under the `Connectivity` section, you will see the various URLs associated with Sensor and Adapter connectivity. +On this page, the `Connectivity` section shows the URLs for Sensor and Adapter connectivity. ### Pinned Certificates -Typically, Sensors require access over port 443 and use pinned SSL certificates. This is the default deployment option, and does not support traffic interception. +Typically, Sensors need access over port 443 and use pinned SSL certificates. This is the default deployment option. It does not support traffic interception. -If you need to install sensors without pinned certificates, an installation key must be created with a specific flag. This must be done via the REST API, by setting the `use_public_root_ca` flag to `true`. +If you must install sensors without pinned certificates, create an installation key with a specific flag. Use the REST API and set the `use_public_root_ca` flag to `true`. See the [Python SDK Manager.replicantRequest source](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Manager.py#L1386) for more detail. ## Use of Tags -Generally speaking, we use at least one Installation Key per organization. Then we use different keys to help differentiate parts of our infrastructure. For example, you may create a key with Tag "server" that you will use to install on your servers, a key with "vip" for executives in your organization, or a key with "sales" for the sales department, etc. This way you can use the tags on various sensors to figure out different detection and response rules for different types of hosts on your infrastructure. +Use at least one Installation Key for each organization. Then use different keys to identify the parts of your infrastructure. For example, create a key with the Tag "server" for your servers, a key with "vip" for the executives in your organization, or a key with "sales" for the sales department. You can then use the tags on the sensors to apply different detection and response rules to different types of hosts. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives you full control of security operations. This structure supports multi-tenant setups for managed security providers, and for enterprises with many departments or clients. -Installation keys are Base64-encoded strings provided to Sensors and Adapters in order to associate them with the correct Organization. Installation keys are created per-organization and offer a way to label and control your deployment population. +Installation keys are Base64-encoded strings that you give to Sensors and Adapters to associate them with the correct Organization. You create installation keys for each organization. The keys let you label and control your deployment population. -In LimaCharlie, an Organization ID is a unique identifier assigned to each tenant or customer account. It distinguishes different organizations within the platform, enabling LimaCharlie to manage resources, permissions, and data segregation securely. The Organization ID ensures that all telemetry, configurations, and operations are kept isolated and specific to each organization, allowing for multi-tenant support and clear separation between different customer environments. +In LimaCharlie, an Organization ID is a unique identifier for each tenant or customer account. It separates the different organizations in LimaCharlie, so LimaCharlie can manage resources, permissions, and data segregation securely. The Organization ID keeps all telemetry, configurations, and operations isolated and specific to each organization. This gives multi-tenant support and a clear separation between customer environments. -In LimaCharlie, an Organization ID (OID) is a unique identifier assigned to each tenant or customer account. It distinguishes different organizations within the platform, enabling LimaCharlie to manage resources, permissions, and data segregation securely. The Organization ID ensures that all telemetry, configurations, and operations are kept isolated and specific to each organization, allowing for multi-tenant support and clear separation between different customer environments. +In LimaCharlie, an Organization ID (OID) is a unique identifier for each tenant or customer account. It separates the different organizations in LimaCharlie, so LimaCharlie can manage resources, permissions, and data segregation securely. The Organization ID keeps all telemetry, configurations, and operations isolated and specific to each organization. This gives multi-tenant support and a clear separation between customer environments. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Like agents, Sensors send telemetry to the LimaCharlie cloud as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. -Adapters serve as flexible data ingestion mechanisms for both on-premise and cloud environments. +Adapters ingest data from on-premise environments and from cloud environments. ## Programmatic Management !!! info "Prerequisites" - All programmatic examples require an API key with `ikey.list`, `ikey.set`, and `ikey.del` permissions. See [API Keys](../7-administration/access/api-keys.md) for setup instructions. + All programmatic examples need an API key with the `ikey.list`, `ikey.set`, and `ikey.del` permissions. For setup instructions, see [API Keys](../7-administration/access/api-keys.md). ### List Installation Keys diff --git a/docs/2-sensors-deployment/log-collection-guide.md b/docs/2-sensors-deployment/log-collection-guide.md index 871c5d484..da90328f1 100644 --- a/docs/2-sensors-deployment/log-collection-guide.md +++ b/docs/2-sensors-deployment/log-collection-guide.md @@ -1,21 +1,21 @@ # Log Collection Guide -This guide covers how to collect system logs into LimaCharlie using USP adapters. While the examples focus on common Linux log paths, the same adapter configurations work on any supported platform (FreeBSD, macOS, etc.) — just adjust the file paths for your OS. +This guide explains how to collect system logs into LimaCharlie with USP adapters. The examples show common Linux log paths. The same adapter configurations work on each supported platform (FreeBSD, macOS, and others). Change the file paths for your OS. ## Collection Methods ### File Adapter (Recommended for Log Files) -The file adapter monitors log files for changes and streams new entries to LimaCharlie. It supports glob patterns for monitoring multiple files and handles log rotation automatically. +The file adapter monitors log files for changes. It sends new entries to LimaCharlie. It supports glob patterns to monitor many files, and it handles log rotation automatically. #### Key Features - Glob pattern support (/var/log/*.log) -- Automatic log rotation handling (with inode-based detection) -- Polling mode for reliable collection on BSD, network filesystems, and across log rotations -- Backfill support for historical data +- Automatic handling of log rotation, with detection based on the inode +- Polling mode for reliable collection on BSD, on network filesystems, and across log rotations +- Backfill of historical data - Multi-line JSON parsing -- Grok pattern parsing for structured log extraction +- Grok pattern parsing to extract structured fields #### Basic Configuration @@ -34,7 +34,7 @@ file: ### Syslog Adapter -The syslog adapter runs as a syslog server, accepting logs via TCP or UDP. This is useful for centralizing logs from multiple systems or integrating with existing syslog infrastructure. +The syslog adapter runs as a syslog server. It accepts logs through TCP or UDP. Use it to centralize logs from many systems, or to connect it to a syslog infrastructure that exists. #### Key Features @@ -60,12 +60,12 @@ syslog: ## Log Parsing Options -LimaCharlie supports two methods for parsing unstructured log data: +LimaCharlie supports two methods to parse unstructured log data: -- **parsing_grok**: Uses Grok patterns (recommended) - pre-built patterns for common log formats, easier to read and maintain -- **parsing_re**: Uses regular expressions - for custom formats or when Grok patterns don't meet specific needs +- **parsing_grok**: Uses Grok patterns (recommended) - pre-built patterns for common log formats, easier to read and to maintain +- **parsing_re**: Uses regular expressions - for custom formats, or when Grok patterns do not meet your needs -Grok patterns are built on regular expressions but provide named patterns for common elements like timestamps, IP addresses, and log formats. Use Grok when possible for better maintainability. +Grok patterns are built on regular expressions, but they give named patterns for common elements such as timestamps, IP addresses, and log formats. Use Grok when possible, because it is easier to maintain. ## Common Log Sources @@ -93,7 +93,7 @@ file: ### Kernel Logs (/var/log/kern.log) -Kernel-specific messages including hardware events, driver messages, and security events. +Kernel messages that include hardware events, driver messages, and security events. ```yaml file: @@ -147,7 +147,7 @@ file: ### Audit Logs (/var/log/audit/audit.log) -Linux audit logs are critical for CIS Controls compliance and security monitoring. +Linux audit logs are critical for compliance with CIS Controls and for security monitoring. ```yaml file: @@ -167,7 +167,7 @@ file: ## Journalctl -Modern logging solution that can output in JSON format for structured parsing. +A modern logging solution that can output JSON format for structured parsing. ### Method 1: Pipe to Stdin Adapter @@ -222,7 +222,7 @@ file: ## Multi-File Collection -For collecting multiple log types simultaneously: +To collect many log types at the same time: ```yaml # /var/log/messages @@ -274,14 +274,14 @@ file: ## Best Practices -- **Use JSON format when possible** - Modern logs often support JSON output, which provides better structure and parsing. -- **Configure appropriate Grok patterns** - Grok provides pre-built patterns for common log formats and is easier to maintain than regex. Use `parsing_grok` over `parsing_re` when possible. -- **Set sensor_seed_key appropriately** - Use descriptive names that identify the log source for easier management. -- **Monitor file permissions** - Ensure the adapter has read access to log files. -- **Use backfill carefully** - Only enable for initial historical data collection to avoid duplicates. -- **Enable polling when needed** - Set `poll: true` if the adapter stops collecting after log rotation, or when running on FreeBSD/BSD systems or network filesystems. See the [File Adapter documentation](adapters/types/file.md#polling-mode) for details. -- **Implement proper field mapping** - Extract hostname, timestamps, and event types for better searchability. -- **Pattern testing** - Test Grok patterns against sample log lines before deployment. Common patterns include %{COMMONAPACHELOG}, %{SYSLOGTIMESTAMP}, and %{NGINXACCESS}. +- **Use JSON format when possible** - Modern logs often support JSON output. JSON gives better structure and parsing. +- **Configure appropriate Grok patterns** - Grok gives pre-built patterns for common log formats, and it is easier to maintain than regex. Use `parsing_grok` instead of `parsing_re` when possible. +- **Set sensor_seed_key appropriately** - Use descriptive names that identify the log source. Descriptive names make management easier. +- **Monitor file permissions** - Make sure that the adapter has read access to the log files. +- **Use backfill carefully** - Enable backfill only for the first collection of historical data. This stops duplicates. +- **Enable polling when needed** - Set `poll: true` if the adapter stops collection after log rotation. Also set it on FreeBSD and BSD systems, and on network filesystems. See the [File Adapter documentation](adapters/types/file.md#polling-mode) for details. +- **Implement proper field mapping** - Extract the hostname, the timestamps, and the event types. These fields make the logs easier to search. +- **Pattern testing** - Test Grok patterns against sample log lines before you deploy them. Common patterns include %{COMMONAPACHELOG}, %{SYSLOGTIMESTAMP}, and %{NGINXACCESS}. ## Troubleshooting @@ -289,6 +289,6 @@ Common issues: - **File permission errors**: Check that the adapter process has read access to log files - **Parse failures**: Validate Grok patterns against actual log formats -- **Missing logs**: Verify file paths and glob patterns -- **Adapter stops collecting after log rotation**: Set `poll: true` in your file adapter configuration. This switches from filesystem event notifications to polling, which reliably detects new data after log rotation tools (e.g. `newsyslog`, `logrotate`) replace the file. This is especially common on FreeBSD and other BSD systems -- **Connection issues**: Check network connectivity and authentication credentials +- **Missing logs**: Check the file paths and the glob patterns +- **Adapter stops collecting after log rotation**: Set `poll: true` in the configuration of your file adapter. The adapter then uses polling instead of filesystem event notifications. Polling reliably detects new data after a log rotation tool (for example `newsyslog` or `logrotate`) replaces the file. This problem is common on FreeBSD and other BSD systems +- **Connection issues**: Check the network connectivity and the authentication credentials diff --git a/docs/2-sensors-deployment/sensor-tags.md b/docs/2-sensors-deployment/sensor-tags.md index 5ec5c5f19..4755de147 100644 --- a/docs/2-sensors-deployment/sensor-tags.md +++ b/docs/2-sensors-deployment/sensor-tags.md @@ -1,60 +1,60 @@ # Sensor Tags -Tags in LimaCharlie are simple strings that can be associated with any number of sensors. A Sensor can also have an arbitrary number of tags associated with it. +Tags in LimaCharlie are strings that you can associate with any number of sensors. A Sensor can also have any number of tags. -Tags appear in every event coming from a sensor under the `routing` component of the event. This greatly simplifies the writing of detection and response rules based on the presence of specific tags, at the cost of including more non-unique data per event. -Tags can be used for a variety of purposes, including: +Tags appear in each event that comes from a sensor, in the `routing` component of the event. This makes it much easier to write detection and response rules that test for specific tags. The cost is more non-unique data in each event. +You can use tags for many purposes: - to classify endpoints - automate detection and response -- create powerful workflows +- create workflows - trigger automations ## Use Cases for Sensor Tags ### Classification -You can use tags to classify an endpoint in a number of different ways based on what is important to you. Some examples of classifications are shown below for inspiration. +You can classify an endpoint with tags in many ways, based on what is important to you. The examples below show some classifications. #### Departments -Create tags to classify endpoints based on what business department they belong to. e.g. sales, finance, operations, development, support, legal, executives. +Create tags that classify endpoints by their business department. For example: sales, finance, operations, development, support, legal, executives. #### Usage Type -You may wish to tag endpoints based on their type of usage. e.g. workstation, server, production, staging. +You can also tag endpoints by their type of usage. For example: workstation, server, production, staging. -By having endpoints tagged in this manner you can easily identify endpoints and decide what actions you may wish to take while considering the tag. For example, if you see an endpoint is tagged with `workstation` and `executives`, and you happen to see suspicious activity on the endpoint, it may be worthwhile for you to prioritize response. +Tags of this type help you identify endpoints and decide which actions to take. For example, an endpoint has the tags `workstation` and `executives`. If you see suspicious activity on that endpoint, give the response a higher priority. ### Automating detection and response You can use tags to automate detection and response. -For example, you can create a detection & response rule so that when a specific user logs in on a device, the box is tagged as `VIP-sales` and the sensor starts collecting an extended list of events from that box. +For example, create a detection & response rule for the login of a specific user on a device. The rule tags the device as `VIP-sales`. The sensor then collects an extended list of events from that device. ### Creating workflows -You can use tags to create workflows and automations. For instance, you can configure an output (forwarder) to send all detections containing `VIP-sales` tag to Slack so that you can review them asap, while detections tagged as `sales` can be sent to an email address. +You can use tags to create workflows and automations. For example, configure an output (forwarder) that sends all detections with the `VIP-sales` tag to Slack for immediate review. Send the detections with the `sales` tag to an email address. ### Trigger Automations -Create a Yara scanning rule so that endpoints tagged as 'sales' are continuously scanned against the specific sets of Yara signatures. +Create a Yara scanning rule that scans the endpoints with the 'sales' tag continuously against specific sets of Yara signatures. ## Adding Tags -Tags can be added to a sensor a few different ways: +You can add tags to a sensor in these ways: -1. Enrollment: the installation keys can optionally have a list of Tags that will get applied to sensors that use them. -2. Manually: using the API as described below, either manually by a human or through some other integration. -3. Detection & Response: automated detection and response rules can programatically add a tag (and check for tags). +1. Enrollment: an installation key can have an optional list of Tags. The cloud applies these tags to the sensors that use the key. +2. Manually: use the API as described below, either by a person or through another integration. +3. Detection & Response: automated detection and response rules can add a tag programmatically, and can check for tags. ### Manual API -Issue a `POST` to `/{sid}/tags` REST endpoint +Issue a `POST` to the `/{sid}/tags` REST endpoint ### Detection & Response -In detection and response rules. To achieve this, in the response part of the detection & response rule, specify the add tag action. For example, to tag a device as DESKTOP, you would say: +In detection and response rules. In the response part of the detection & response rule, specify the add tag action. For example, to tag a device as DESKTOP, write: ```yaml - action: add tag @@ -65,7 +65,7 @@ tag: DESKTOP ### Manual API -Issue a `DELETE` to `/{sid}/tags` REST endpoint +Issue a `DELETE` to the `/{sid}/tags` REST endpoint ### Detection & Response @@ -73,13 +73,13 @@ In detection and response rules ### Manual in the web app -In the web app, click on the sensor in question to expand it. You will see the list of tags you can add/edit/remove. +In the web app, click the sensor to expand it. The web app shows the list of tags that you can add, edit, or remove. ## Checking Tags ### Manual API -Issue a `GET` to `/{sid}/tags` REST endpoint +Issue a `GET` to the `/{sid}/tags` REST endpoint ### Detection & Response @@ -87,44 +87,44 @@ In detection and response rules ## System Tags -We provide system level functionality with a few system tags. Those tags are listed below for reference: +LimaCharlie gives system level functionality with some system tags. The list below is for reference: ### lc:latest -When you tag a sensor with `lc:latest`, the sensor version currently assigned to the Organization will be ignored for that specific sensor, and the latest version of the sensor will be used instead. This means you can tag a representative set of computers in the Organization with the `lc:latest` tag in order to test-deploy the latest version and confirm no negative effects. +When you tag a sensor with `lc:latest`, that sensor ignores the sensor version that is assigned to the Organization. It uses the latest version of the sensor instead. Tag a representative set of computers in the Organization with the `lc:latest` tag. You can then test-deploy the latest version and confirm that it has no negative effects. ### lc:stable -When you tag a sensor with `lc:stable`, the sensor version currently assigned to the Organization will be ignored for that specific sensor, and the *stable* version of the sensor will be used instead. This means you can upgrade an organization as a whole, but leave a few specific sensors behind by assigning the lc:stable tag to them. +When you tag a sensor with `lc:stable`, that sensor ignores the sensor version that is assigned to the Organization. It uses the *stable* version of the sensor instead. You can upgrade an organization as a whole, but keep a few specific sensors behind with the lc:stable tag. ### lc:experimental -When you tag a sensor with `lc:experimental`, the sensor version currently assigned to the Organization will be ignored for that specific sensor. An experimental version of the sensor will be used instead. This tag is typically used when working with the LimaCharlie team to troubleshoot sensor-specific issues. +When you tag a sensor with `lc:experimental`, that sensor ignores the sensor version that is assigned to the Organization. It uses an experimental version of the sensor instead. Use this tag when you work with the LimaCharlie team to troubleshoot a problem in a sensor. ### lc:no_kernel -When you tag a sensor with `lc:no_kernel`, the kernel component will not be loaded on the host. +When you tag a sensor with `lc:no_kernel`, the sensor does not load the kernel component on the host. ### lc:debug -When you tag a sensor with `lc:debug`, the debug version of the sensor currently assigned to the Organization will be used. +When you tag a sensor with `lc:debug`, that sensor uses the debug version of the sensor version that is assigned to the Organization. ### lc:limit-update -When you tag a sensor with lc:limit-update, the sensor will not update the version it's running at run-time. The version will only be loaded when the sensor starts from scratch like after a reboot. +When you tag a sensor with lc:limit-update, the sensor does not update its version at run-time. The sensor loads the version only when it starts from scratch, for example after a reboot. ### lc:sleeper -When you tag a sensor with *lc:sleeper*, the sensor will keep its connection to the LimaCharlie Cloud, but will disable all other functionality to avoid any impact on the system. To wake up sensors from sleeper mode, set your organization's Quota to accommodate the number of sensors you want to activate, then remove the `lc:sleeper` tag from those sensors. For more details, see [Sleeper Deployments](endpoint-agent/sleeper.md). +When you tag a sensor with *lc:sleeper*, the sensor keeps its connection to the LimaCharlie Cloud. It disables all other functionality so that it has no impact on the system. To wake sensors from sleeper mode, set the Quota of your organization for the number of sensors that you want to activate. Then remove the `lc:sleeper` tag from those sensors. For more details, see [Sleeper Deployments](endpoint-agent/sleeper.md). -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Similar to agents, Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives you complete control of security operations. This structure supports flexible, multi-tenant setups for managed security providers, and for enterprises that manage many departments or clients. ## Programmatic Management !!! info "Prerequisites" - All programmatic examples require an API key with `sensor.tag` permissions. See [API Keys](../7-administration/access/api-keys.md) for setup instructions. + All programmatic examples need an API key with `sensor.tag` permissions. See [API Keys](../7-administration/access/api-keys.md) for setup instructions. ### List All Organization Tags @@ -386,4 +386,4 @@ In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Wo - [Sensor Selectors](../8-reference/sensor-selector-expressions.md) - [Python SDK](../6-developer-guide/sdks/python-sdk.md) - [Go SDK](../6-developer-guide/sdks/go-sdk.md) -- [Compliance Frameworks](../9-ai-sessions/compliance/frameworks.md) -- Scope-tag conventions per framework (`cde` for PCI, `ephi-host` for HIPAA, `cui` for CMMC, `fisma-scope` for NIST 800-53, etc.). The compliance reviewer agents key their in-scope check off these tags. +- [Compliance Frameworks](../9-ai-sessions/compliance/frameworks.md) -- Scope-tag conventions for each framework (`cde` for PCI, `ephi-host` for HIPAA, `cui` for CMMC, `fisma-scope` for NIST 800-53, and others). The compliance reviewer agents use these tags for their in-scope check. diff --git a/docs/2-sensors-deployment/troubleshooting/non-responding-sensors.md b/docs/2-sensors-deployment/troubleshooting/non-responding-sensors.md index b65f5a525..5b23b32a8 100644 --- a/docs/2-sensors-deployment/troubleshooting/non-responding-sensors.md +++ b/docs/2-sensors-deployment/troubleshooting/non-responding-sensors.md @@ -2,7 +2,7 @@ ## Overview -A common request is to alert an administrator if a Sensor that normally forwards data, stops or fails to send data. This LimaCharlie Playbook is meant to be triggered on a schedule by rule. It checks for data sent, via the LimaCharlie Python SDK, within a given time window. If no data is sent during the time period, then an alert is generated, one per sensor. +A common request is to alert an administrator when a Sensor that normally forwards data stops or does not send data. A rule triggers this LimaCharlie Playbook on a schedule. The playbook uses the LimaCharlie Python SDK to check for data that arrived in a given time window. If no data arrives in that time window, the playbook generates one alert for each sensor. ## Example Playbook Code diff --git a/docs/2-sensors-deployment/tutorials/defender-logs.md b/docs/2-sensors-deployment/tutorials/defender-logs.md index 4eb1dfacc..2620d8d72 100644 --- a/docs/2-sensors-deployment/tutorials/defender-logs.md +++ b/docs/2-sensors-deployment/tutorials/defender-logs.md @@ -1,12 +1,12 @@ # Ingesting Defender Event Logs -The Windows Sensor can listen, alert, and automate based on various Defender events. +The Windows Sensor can listen for many Defender events. It can alert on these events and automate actions. -This is done by ingesting [artifacts from the Defender Event Log Source](../../5-integrations/extensions/limacharlie/artifact.md) and using [Detection & Response rules](../../3-detection-response/index.md) to take the appropriate action. +To do this, ingest [artifacts from the Defender Event Log Source](../../5-integrations/extensions/limacharlie/artifact.md). Then use [Detection & Response rules](../../3-detection-response/index.md) to take the correct action. -A [config template alerting on common Defender events of interest](https://github.com/refractionPOINT/templates/blob/master/anti-virus/windows-defender.yaml) is available. The template can be used in conjunction with [Infrastructure Extension](../../5-integrations/extensions/limacharlie/infrastructure.md) or its user interface in the [web app](https://app.limacharlie.io). +A [config template for common Defender events](https://github.com/refractionPOINT/templates/blob/master/anti-virus/windows-defender.yaml) is available. Use the template with the [Infrastructure Extension](../../5-integrations/extensions/limacharlie/infrastructure.md), or with the user interface of that extension in the [web app](https://app.limacharlie.io). -Specifically, the template alerts on the following Defender events: +The template alerts on these Defender events: - windows-defender-malware-detected (`event ID 1006`) - windows-defender-history-deleted (`event ID 1013`) diff --git a/docs/2-sensors-deployment/tutorials/linux-audit-logs.md b/docs/2-sensors-deployment/tutorials/linux-audit-logs.md index 4f976f87b..e1ec188bd 100644 --- a/docs/2-sensors-deployment/tutorials/linux-audit-logs.md +++ b/docs/2-sensors-deployment/tutorials/linux-audit-logs.md @@ -1,52 +1,52 @@ # Ingesting Linux Audit Logs -One data source of common interest on Linux systems is the `audit.log` file. By default, this file stores entries from the Audit system, which contains information about logins, privilege escalations, and other account-related events. See [Audit Log file documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/sec-understanding_audit_log_files). +A common data source on Linux systems is the `audit.log` file. By default, this file stores entries from the Audit system. These entries contain information about logins, privilege escalations, and other events that relate to accounts. See [Audit Log file documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/sec-understanding_audit_log_files). -There are a few techniques to ingest Linux Audit logs into LimaCharlie: +You can ingest Linux Audit logs into LimaCharlie with these techniques: -1. Pull the raw logs using Artifacts and/or the File System navigator *(EDR sensors only)* -2. Collect the files using **Artifact Collection.** -3. Stream the raw audit log via a `file` adapter. +1. Pull the raw logs with Artifacts or with the File System navigator *(EDR sensors only)* +2. Collect the files with **Artifact Collection.** +3. Stream the raw audit log through a `file` adapter. -We will explore these techniques in this tutorial. Adapters can also be configured as syslog listeners; that will be covered in another tutorial. +This tutorial explains these techniques. You can also configure adapters as syslog listeners. Another tutorial explains that configuration. ## File System Browser -Our Windows, Linux, and macOS EDR sensors offer file system navigation capabilities. If you need a single, ad-hoc collection of the `auth.log`, you can use the File System capability to navigate to `/var/log`, and download `auth.log`. +The Windows, Linux, and macOS EDR sensors can navigate the file system. For a single, ad-hoc collection of the `auth.log`, use the File System capability. Navigate to `/var/log` and download `auth.log`. ![audit 1](../../assets/images/audit-1.png) ## Artifact Collection -If you don't need to stream Linux Audit log(s), but instead want to maintain a copy of them for posterity, Artifact collection would be your best method. This is an automated collection technique, but won't stream the events to your **Timeline**. +Artifact collection is the best method if you do not need to stream the Linux Audit logs, but want to keep a copy of them. This technique collects the files automatically, but it does not stream the events to your **Timeline**. -**Step 1:** Within the Navigation Pane, select `Artifact Collection`. +**Step 1:** In the Navigation Pane, select `Artifact Collection`. ![audit 2](../../assets/images/audit-2.png) -**Step 2:** Create a simple artifact collection rule for `/var/log/auth.log`. In this example, we chose a retention period of 30 days; however, you should choose the correct retention period for your use case. +**Step 2:** Create an artifact collection rule for `/var/log/auth.log`. This example uses a retention period of 30 days. Choose the correct retention period for your use case. ![audit 3](../../assets/images/audit-3.png) -click **Save** +Click **Save**. ![audit 4](../../assets/images/audit-4.png) -**Step 3:** Saving the artifact rule will then populate to the appropriate sensor(s), and you should see the `auth.log` in the Artifacts menu, once it is collected by the Sensor. +**Step 3:** Save the artifact rule. The cloud sends the rule to the applicable sensors. After the Sensor collects the `auth.log`, the file is shown in the Artifacts menu. ![audit 5](../../assets/images/audit-5(1).png) -Want more logs? +More logs -Want more than just the most recent `auth.log`? Specify a regular expression to capture all archived copies of the log files. However, be careful on retention and make sure you're not unnecessarily duplicating data! +To collect more than the most recent `auth.log`, specify a regular expression. The expression captures all archived copies of the log files. Be careful with the retention period, and make sure that you do not duplicate data. ## File Adapter Ingestion -It is also possible to deploy a LimaCharlie [Adapter](../adapters/index.md) pointed to `auth.log` to collect and stream the events in directly. Note that Adapters will create a separate telemetry "stream" - thus, it is recommended to combine file types where possible. +You can also deploy a LimaCharlie [Adapter](../adapters/index.md) that points to `auth.log`. The adapter collects the events and streams them directly. Each Adapter creates a separate telemetry "stream", so combine file types where possible. -**Step 1:** Create an Installation Key for your adapter and download the appropriate binary. +**Step 1:** Create an Installation Key for your adapter. Download the applicable binary. -**Step 2:** On the system(s) to collect logs from, deploy the adapter. We recommend utilizing a configuration file for adapter testing, to allow for tracking of changes. The following is a sample file that will ingest `auth.log` events as basic text. +**Step 2:** Deploy the adapter on each system that collects logs. Use a configuration file when you test the adapter, so that you can track changes. The sample file below ingests `auth.log` events as basic text. ```yaml file: @@ -62,16 +62,16 @@ file: See [adapter configuration and usage](../adapters/usage.md) for more detail. -**Step 3:** Run the adapter, providing the `file` option and the appropriate config file. +**Step 3:** Run the adapter. Give the `file` option and the applicable config file. `$ ./lc_adapter file /tmp/config.yml` -The adapter should load the config and display options to the terminal. +The adapter loads the config and shows the options in the terminal. ### Note: This is not a persistent install; utilize your operating system's init/systemctl capabilities to create a persistent adapter -**Step 4:** Returning to the LimaCharlie web UI, you should start to see events flowing in almost instantaneously. +**Step 4:** Return to the LimaCharlie web UI. The events start to arrive almost immediately. ![image.png](../../assets/images/image(115).png) -Note that a `text` platform will ingest data as basic text, however you could use formatting options to parse the fields respective to your `auth.log` format. +A `text` platform ingests data as basic text. You can use formatting options to parse the fields of your `auth.log` format. diff --git a/docs/2-sensors-deployment/tutorials/macos-unified-logs.md b/docs/2-sensors-deployment/tutorials/macos-unified-logs.md index 29d2a6444..fbb607eed 100644 --- a/docs/2-sensors-deployment/tutorials/macos-unified-logs.md +++ b/docs/2-sensors-deployment/tutorials/macos-unified-logs.md @@ -1,30 +1,30 @@ # Ingesting MacOS Unified Logs -You can enable real-time MacOS Unified Logs (MUL) ingestion using the LimaCharlie EDR Sensor. +You can ingest MacOS Unified Logs (MUL) in real time with the LimaCharlie EDR Sensor. -First, navigate to the Exfil Control section of LimaCharlie and ensure that `MUL` events are enabled for your Mac rules. +First, go to the Exfil Control section of LimaCharlie. Make sure that `MUL` events are enabled for your Mac rules. ![ingest mac 1](../../assets/images/ingest-mac-1.png) -Next, navigate to the `Artifact Collection` section and set up an artifact collection rule for the MacOS Unified Log(s) of interest. +Next, go to the `Artifact Collection` section. Create an artifact collection rule for the MacOS Unified Logs that you want. ![ingest mac 2](../../assets/images/ingest-mac-2.png) -To ingest MUL real-time events in the timeline, use the `mul://[Predicate]` format, where the predicate is a standard [MacOS MUL predicate](https://www.macminivault.com/faq/introduction-to-macos-unified-logs/). For example, to ingest the Safari logs, you'd use the following pattern: +To ingest real-time MUL events in the timeline, use the `mul://[Predicate]` format. The predicate is a standard [MacOS MUL predicate](https://www.macminivault.com/faq/introduction-to-macos-unified-logs/). For example, use this pattern to ingest the Safari logs: `mul://process == "Safari"` ![ingest mac 3](../../assets/images/ingest-mac-3.png) -If you ingest MacOS Unified Logs with a `mul://` pattern, they are streamed in real-time as first-class telemetry alongside the native EDR events, and are included in the flat rate price of the sensor. +If you ingest MacOS Unified Logs with a `mul://` pattern, the sensor streams them in real time with the native EDR events. These logs are included in the flat rate price of the sensor. -After you apply those, you should start seeing your MacOS Unified Logs data coming through for your endpoints within 10 minutes. You can verify this by going into the Timeline view and choosing `MUL` event type. +After you apply these settings, the MacOS Unified Logs data from your endpoints starts to arrive in 10 minutes. To check this, open the Timeline view and select the `MUL` event type. ## Endpoint Detection & Response -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Similar to agents, Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. -In LimaCharlie, Exfil (Event Collection) is a configuration extension that determines which types of events are collected and sent from endpoint agents to the cloud. It controls the data flow, ensuring only specified events are transmitted for monitoring and analysis. To capture specific events, they must be enabled within the Exfil or Event Collection settings. +In LimaCharlie, Exfil (Event Collection) is a configuration extension. It decides which types of events the endpoint agents collect and send to the cloud. It controls the data flow, so that the agents send only the specified events for monitoring and analysis. To capture specific events, enable them in the Exfil or Event Collection settings. ## Related Articles diff --git a/docs/2-sensors-deployment/tutorials/sysmon-logs.md b/docs/2-sensors-deployment/tutorials/sysmon-logs.md index f5a554be4..c4ee61ad5 100644 --- a/docs/2-sensors-deployment/tutorials/sysmon-logs.md +++ b/docs/2-sensors-deployment/tutorials/sysmon-logs.md @@ -1,14 +1,14 @@ # Ingesting Sysmon Event Logs -Sysmon can be a valuable addition to any defender's toolkit, given it's verbosity and generous log data. It's worth noting that LimaCharlie's native EDR capabilities mirror much of the same telemetry. However, Sysmon and LimaCharlie can be combined to provide granular coverage across Windows systems. +Sysmon is a valuable addition to the tools of a defender, because it gives verbose log data. The native EDR capabilities of LimaCharlie collect much of the same telemetry. But you can combine Sysmon and LimaCharlie to get granular coverage of Windows systems. -With Sysmon deployed, you can utilize LimaCharlie's native Windows Event Log (WEL) streaming capabilities to bring logs into the Sensor timeline. +After you deploy Sysmon, use the native Windows Event Log (WEL) streaming capability of LimaCharlie to bring the logs into the Sensor timeline. 1. Install [Sysmon](https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon) on the endpoint. - - This can easily be done via LimaCharlie's Payload functionality, with a rule, or manually. - - Please note that the LimaCharlie agent must be restarted in order for Sysmon data to show up in the timeline. - - Example rule to deploy Sysmon via payloads on Windows systems tagged with `deploy-sysmon`: + - Do this with the Payload functionality of LimaCharlie, with a rule, or manually. + - You must restart the LimaCharlie agent before the Sysmon data is shown in the timeline. + - Example rule that deploys Sysmon with payloads on Windows systems that have the `deploy-sysmon` tag: ```powershell detect: @@ -43,31 +43,31 @@ With Sysmon deployed, you can utilize LimaCharlie's native Windows Event Log (WE command: restart ``` -2. Within the Organization where you wish to collect Sysmon data, go to the `Event Collection > Event Collection Rules` section. +2. In the Organization where you want to collect Sysmon data, go to the `Event Collection > Event Collection Rules` section. -![ingest sysmon 1](../../assets/images/ingest-sysmon-1.png) + ![ingest sysmon 1](../../assets/images/ingest-sysmon-1.png) -1. Ensure that for Windows systems, `WEL` events are collected. +3. Make sure that `WEL` events are collected for Windows systems. -![ingest sysmon 2](../../assets/images/ingest-sysmon-2.png) + ![ingest sysmon 2](../../assets/images/ingest-sysmon-2.png) -1. Go to the `Artifact Collection` section and add a new collection rule with the following path to bring in all Sysmon events: +4. Go to the `Artifact Collection` section. Add a new collection rule with this path to bring in all Sysmon events: -`wel://Microsoft-Windows-Sysmon/Operational:*` + `wel://Microsoft-Windows-Sysmon/Operational:*` -![ingest sysmon 3](../../assets/images/ingest-sysmon-3.png) + ![ingest sysmon 3](../../assets/images/ingest-sysmon-3.png) -**Note:** You can use tagging or other filters to narrow down the systems that logs are collected from. + **Note:** You can use tags or other filters to limit the systems that the logs come from. -Event Filtering + Event Filtering -You can filter events by event ID to import select events. For example: + You can filter events by event ID to import select events. For example: -`wel://Microsoft-Windows-Sysmon/Operational:16` + `wel://Microsoft-Windows-Sysmon/Operational:16` -`wel://Microsoft-Windows-Sysmon/Operational:25` + `wel://Microsoft-Windows-Sysmon/Operational:25` -1. Allow up to 10 minutes for data to come into LimaCharlie after setting up a new Artifact Collection rule. Data will flow in real-time after that point. -2. Navigate to the Timeline view of a Sensor to confirm that Sysmon logs are present. You can search for Event Type `WEL` and Search for `Microsoft-Windows-Sysmon` to validate the telemetry. +5. Wait up to 10 minutes for the data to arrive in LimaCharlie after you set up a new Artifact Collection rule. After that point, the data flows in real time. +6. Go to the Timeline view of a Sensor to confirm that the Sysmon logs are present. Search for the Event Type `WEL` and for `Microsoft-Windows-Sysmon` to validate the telemetry. -![image.png](../../assets/images/image(96).png) + ![image.png](../../assets/images/image(96).png) diff --git a/docs/2-sensors-deployment/tutorials/test-sensor-version.md b/docs/2-sensors-deployment/tutorials/test-sensor-version.md index 9b0a73ee3..9765db417 100644 --- a/docs/2-sensors-deployment/tutorials/test-sensor-version.md +++ b/docs/2-sensors-deployment/tutorials/test-sensor-version.md @@ -1,17 +1,17 @@ # Test a New Sensor Version -Prior to rolling out a new Sensor version, we recommend testing to ensure everything works as intended within your environment. While we test Sensors before releasing them, we cannot predict every niche use case. We also recommend testing on `dev` or `test` systems prior to deployment in production, again, to eliminate any concerns of resource utilization or Sensor operations. +Test a new Sensor version before you roll it out. The test makes sure that the Sensor works correctly in your environment. LimaCharlie tests Sensors before it releases them, but it cannot predict each niche use case. Test on `dev` or `test` systems before you deploy in production. This removes concerns about resource use and about Sensor operations. -Sensor version testing is done via LimaCharlie's tagging functionality. +You test a sensor version with the tagging functionality of LimaCharlie. -When you tag a Sensor with `lc:latest`, the sensor version currently assigned to the Organization will be ignored for that specific sensor, and the latest version of the sensor will be used instead. You can apply this tag to a handful of systems to test-deploy the latest version. +When you tag a Sensor with `lc:latest`, that sensor ignores the sensor version that is assigned to the Organization. It uses the latest version of the sensor instead. Apply this tag to a small number of systems to test-deploy the latest version. -Alternatively, you can tag a sensor with `lc:stable`. Similarly, the sensor version currently assigned to the Organization will be ignored for that specific sensor, and the stable version of the sensor will be used instead. +You can also tag a sensor with `lc:stable`. That sensor then ignores the sensor version that is assigned to the Organization, and uses the stable version of the sensor instead. -You can tag a Sensor by opening the sensors list, selecting a sensor you would like to test, and navigating to the `tags` field on the sensor `Overview`. +To tag a Sensor, open the sensors list. Select the sensor that you want to test. Go to the `tags` field on the sensor `Overview`. ![Alternatively, you can tag a sensor with lc:stable](../../assets/images/image(314).png) -Simply type `lc:stable` and click `Update Tags`. +Type `lc:stable` and click `Update Tags`. Note: It can take up to 10 minutes to update the sensor to the tagged version. diff --git a/docs/2-sensors-deployment/tutorials/update-sensors.md b/docs/2-sensors-deployment/tutorials/update-sensors.md index a041479e1..b2428fb56 100644 --- a/docs/2-sensors-deployment/tutorials/update-sensors.md +++ b/docs/2-sensors-deployment/tutorials/update-sensors.md @@ -1,21 +1,21 @@ # Updating Sensors to the Newest Version -LimaCharlie releases a new version of the Sensor frequently - often every few weeks. However, we give you full control over what sensor version is running in your Organization. Sensors are not updated by default. +LimaCharlie releases a new version of the Sensor frequently - often every few weeks. You control which sensor version runs in your Organization. Sensors do not update by default. -There are two methods for updating sensors in your organization to the latest version. +There are two methods to update the sensors in your organization to the latest version. ## Manual Update -Upgrading sensors is done transparently for you once you click the "Update to Latest" button, located at `Sensors > Deployed Versions`. +Click the "Update to Latest" button at `Sensors > Deployed Versions`. LimaCharlie then upgrades the sensors for you. ![Manual sensor update via the Update to Latest button](../../assets/images/image(316).png) -The new version should be in effect across the organization within about 20 minutes. +The new version is in effect across the organization in about 20 minutes. ## Automated Update -You can also configure sensors in your organization to auto-update to the new version when it's released. To do it, tag applicable (or all) sensors in your fleet with the `lc:stable` tag (`lc:stable` tag means that the package it provides rarely changes). +You can also configure the sensors in your organization to auto-update when LimaCharlie releases a new version. Tag some or all of the sensors in your fleet with the `lc:stable` tag. The `lc:stable` tag means that the package that it supplies rarely changes. ![Automated sensor update settings](../../assets/images/image(315).png) -This will ensure that when a new sensor version is released, it will be in effect across the organization within about 20 minutes. +When LimaCharlie releases a new sensor version, it is in effect across the organization in about 20 minutes. diff --git a/docs/2-sensors-deployment/tutorials/viberails-mssp-deployment.md b/docs/2-sensors-deployment/tutorials/viberails-mssp-deployment.md index 5625fb624..883a599a2 100644 --- a/docs/2-sensors-deployment/tutorials/viberails-mssp-deployment.md +++ b/docs/2-sensors-deployment/tutorials/viberails-mssp-deployment.md @@ -1,17 +1,17 @@ # Deploying Viberails at Scale via Payloads (MSSP Guide) -[Viberails](https://viberails.io) is a control plane for AI coding assistants (Claude Code, Cursor, Gemini CLI, GitHub Copilot CLI, Codex, OpenCode, OpenClaw). It installs lightweight hooks into each tool so every prompt and tool call is audited and authorized through LimaCharlie. +[Viberails](https://viberails.io) is a control plane for AI coding assistants (Claude Code, Cursor, Gemini CLI, GitHub Copilot CLI, Codex, OpenCode, OpenClaw). It installs hooks into each tool. LimaCharlie then audits and authorizes every prompt and tool call. -This guide is for MSSPs, MSPs, and MDR providers who **already run LimaCharlie for their customers**: each customer has their own LC organization with the endpoint agent deployed. The goal here is to add Viberails coverage onto those existing organizations so each customer's AI coding assistant activity lands in their own LC org, alongside the rest of their telemetry. +This guide is for MSSPs, MSPs, and MDR providers that **already run LimaCharlie for their customers**. Each customer has an LC organization with the sensor deployed. The goal is to add Viberails coverage to those organizations. The AI coding assistant activity of each customer then goes to that customer's own LC org, with the rest of their telemetry. -The whole rollout is done through the LimaCharlie tooling you are already using: the [Payloads](../endpoint-agent/payloads.md) feature delivers the Viberails binary, a [D&R rule](../../3-detection-response/index.md) installs it under the developer's user account, and the [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension and/or [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md) fan everything out across your customer fleet. +You do the full rollout with the LimaCharlie tools that you already use. The [Payloads](../endpoint-agent/payloads.md) feature delivers the Viberails binary. A [D&R rule](../../3-detection-response/index.md) installs the binary under the account of the developer. The [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension, [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md), or both distribute everything across your customer fleet. ## Why this works well for MSSPs -- **No new infrastructure.** Anywhere the LimaCharlie agent is already deployed, you can ship and execute a payload — no new MDM, no new VPN, no installer to email developers, no new SaaS console. -- **Customer data stays with the customer.** Viberails events flow into the customer's own LC org via a per-org webhook adapter. The MSSP retains the same access it already had — through Organization Groups and RBAC — and nothing about data ownership changes. -- **Fits IaC.** Payloads, installation rules, and D&R rules can all be templated and pushed to many customer organizations through the [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension or [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md). -- **Targeted, not fleet-wide.** Sensor tags let you scope the rollout to developer machines only, and the [sensor selector](../../1-getting-started/use-cases/investigation-guide.md) syntax keeps that targeting consistent across customers. +- **No new infrastructure.** You can send and run a payload on every host where the LimaCharlie sensor is deployed. You do not need a new MDM, a new VPN, an installer to email to developers, or a new SaaS console. +- **Customer data stays with the customer.** Viberails events go to the customer's own LC org through a webhook adapter for each org. The MSSP keeps the same access through Organization Groups and RBAC. Data ownership does not change. +- **Fits IaC.** You can make templates of payloads, installation rules, and D&R rules. You can push these templates to many customer organizations with the [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension or [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md). +- **Targeted, not fleet-wide.** Sensor tags let you limit the rollout to developer machines. The [sensor selector](../../1-getting-started/use-cases/investigation-guide.md) syntax keeps the same targets for each customer. ## How it works @@ -37,14 +37,14 @@ flowchart LR For each customer LC org: -1. The MSSP provisions a `viberails` webhook adapter once via `viberails init-team --existing-org `. This creates the per-org team URL that Viberails on the endpoint will report to, and also seeds a set of Viberails-specific D&R rules in the customer's `dr-general` hive. -2. The MSSP uploads the Viberails binaries (one per OS/architecture) and a small PowerShell helper as Payloads in the customer org — normally via the Payload Manager so they stay in sync as Viberails releases new versions. -3. A D&R rule in the customer org fires on `CONNECTED` for sensors tagged `viberails-deploy`, `put`s the right binary, and runs `join-team` + `install --providers all` as the interactively signed-in user. -4. Viberails reports every AI tool prompt and tool call back to the same customer LC org through the webhook adapter. There is no separate "Viberails team" or shared MSSP team in the picture. +1. The MSSP provisions a `viberails` webhook adapter one time with `viberails init-team --existing-org `. The command creates the team URL for that org, and Viberails on the endpoint reports to this URL. The command also adds a set of Viberails D&R rules to the customer's `dr-general` hive. +2. The MSSP uploads the Viberails binaries (one for each OS and architecture) and a small PowerShell helper as Payloads in the customer org. The MSSP normally does this with the Payload Manager, which keeps the payloads in sync when Viberails releases new versions. +3. A D&R rule in the customer org fires on `CONNECTED` for sensors that have the `viberails-deploy` tag. The rule `put`s the correct binary, then runs `join-team` and `install --providers all` as the interactively signed-in user. +4. Viberails reports every AI tool prompt and tool call to the same customer LC org through the webhook adapter. There is no separate "Viberails team" and no shared MSSP team. ## Prerequisites -- One LimaCharlie organization **per customer**, with the endpoint agent already deployed on the developer workstations you want to cover. +- One LimaCharlie organization **per customer**, with the sensor already deployed on the developer workstations that you want to cover. - API permissions in each customer org to: - read org metadata: `org.get` - create the webhook adapter: `cloudsensor.get`, `cloudsensor.set` (the adapter lives in the `cloud_sensor` hive) @@ -52,14 +52,14 @@ For each customer LC org: - manage payloads: `payload.ctrl`, `payload.use` - manage rules: `dr.list`, `dr.set`, `dr.del` - manage tags: `sensor.tag` -- The [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension installed in each target org if you want centralized syncing of payloads. -- A LimaCharlie account that can OAuth into each customer org (interactively) for the one-shot `init-team --existing-org` step. The rest of the rollout is fully scriptable through the LimaCharlie CLI / API. +- The [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) extension installed in each target org, if you want to sync payloads centrally. +- A LimaCharlie account that can OAuth interactively into each customer org for the single `init-team --existing-org` step. You can script the rest of the rollout with the LimaCharlie CLI or API. ## Step 1 — Provision Viberails reception in each customer org -Viberails reports its events to a per-org **team URL** of the form `https://.hook.limacharlie.io//viberails/`. The `` segment is the customer's LimaCharlie OID — so a customer's Viberails events land in that customer's org and nowhere else. +Viberails reports its events to a **team URL** for each org. The URL has the form `https://.hook.limacharlie.io//viberails/`. The `` segment is the LimaCharlie OID of the customer, so the Viberails events of a customer go to that customer's org only. -The simplest way to provision this is to install Viberails locally on an MSSP workstation and run `init-team` against each customer's existing org. `--existing-org` skips the "create new team" path: +To provision this URL, install Viberails on an MSSP workstation and run `init-team` against the existing org of each customer. The `--existing-org` flag skips the "create new team" path: ```bash # Once per customer org. This will: @@ -69,24 +69,24 @@ The simplest way to provision this is to install Viberails locally on an MSSP wo viberails init-team --existing-org ``` -The command is interactive (OAuth) but only needs to run once per org. The webhook URL is stable; record it next to the OID in your customer inventory. +The command is interactive (OAuth), but you run it one time for each org. The webhook URL is stable. Record it next to the OID in your customer inventory. -If you prefer a fully scripted setup (no interactive OAuth), you can recreate the same artifacts using a non-interactive LimaCharlie credential against each customer org: +For a fully scripted setup with no interactive OAuth, create the same artifacts with a non-interactive LimaCharlie credential against each customer org: -1. `limacharlie --oid installation-key create --description "viberails webhook adapter" --get` to create the installation key. -2. `limacharlie --oid cloud-adapter set --key viberails --input-file viberails-adapter.json` to create the webhook adapter entry. The adapter JSON references the installation key from step 1, sets `secret` to a freshly generated UUID, and sets the type to `webhook` with `enabled: true`. -3. Fetch the org's hook domain (it varies per datacenter — query the `org urls` endpoint) and assemble the team URL as `https:////viberails/`. +1. Run `limacharlie --oid installation-key create --description "viberails webhook adapter" --get` to create the installation key. +2. Run `limacharlie --oid cloud-adapter set --key viberails --input-file viberails-adapter.json` to create the webhook adapter entry. The adapter JSON refers to the installation key from step 1, sets `secret` to a new UUID, and sets the type to `webhook` with `enabled: true`. +3. Get the hook domain of the org. The domain is different for each datacenter, so query the `org urls` endpoint. Then assemble the team URL as `https:////viberails/`. -Recording the team URL in your customer inventory is still the only output you actually need for the rest of this guide. +The team URL in your customer inventory is still the only output that you need for the rest of this guide. !!! note "Where Viberails D&R rules come from" - `init-team` seeds a set of detection rules covering SSH key access, hook-config tampering, binary-tamper, cloud-cred access, suspicious TLDs, and similar primer detections. These are independent of the deployment rule built in Step 4 — they detect things Viberails-instrumented tools do at runtime. If you maintain Viberails rules centrally in Git-Sync, you can disable or override these per-customer. + `init-team` adds a set of detection rules. The rules cover SSH key access, changes to the hook configuration, binary tampering, access to cloud credentials, suspicious TLDs, and similar primer detections. These rules are independent of the deployment rule that you build in Step 4. They detect what Viberails-instrumented tools do at runtime. If you keep Viberails rules centrally in Git-Sync, you can disable or override these rules for each customer. ## Step 2 — Tag developer workstations -Pick a tag that identifies machines where AI coding assistants are used. We will use `viberails-deploy` throughout this guide. +Pick a tag that identifies the machines that use AI coding assistants. This guide uses `viberails-deploy`. -You can tag manually from the Sensors view, with the CLI, or automatically based on installed software. A common pattern is to add the tag at install time via the [installation key](../installation-keys.md), so any new developer workstation enrolling under that key inherits the tag. +You can add the tag manually from the Sensors view, with the CLI, or automatically from the installed software. A common pattern is to add the tag at install time with the [installation key](../installation-keys.md). Each new developer workstation that enrolls with that key then gets the tag. ```bash # Tag a single sensor @@ -100,7 +100,7 @@ See [Sensor Tags](../sensor-tags.md) for the full mechanics. ## Step 3 — Upload the Viberails binaries as payloads -Viberails publishes signed binaries for every supported OS/architecture at `get.viberails.io`. Download them once on a trusted host and verify checksums against [release.json](https://get.viberails.io/release.json), then upload each one as a [payload](../endpoint-agent/payloads.md). +Viberails publishes signed binaries for each supported OS and architecture at `get.viberails.io`. Download the binaries one time on a trusted host and check the checksums against [release.json](https://get.viberails.io/release.json). Then upload each binary as a [payload](../endpoint-agent/payloads.md). ```bash # Download @@ -122,23 +122,23 @@ limacharlie --oid payload upload --name viberails-install.ps1 --f ``` !!! tip "Naming" - The payload **name** is also the on-disk file name when it lands on the endpoint, and it determines the file extension that the OS uses to decide how to execute it. Keep the `.exe` suffix for Windows so it runs as a native executable. + The payload **name** is also the file name on disk when the payload arrives on the endpoint. The name gives the file extension that the OS uses to run the file. Keep the `.exe` suffix for Windows so the file runs as a native executable. ### Distributing payloads across many customer orgs -For more than a handful of organizations, do not upload payloads one by one. Instead, drive the upload through the [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md): +Do not upload payloads one by one for more than a few organizations. Use the [Payload Manager](../../5-integrations/extensions/limacharlie/payload-manager.md) instead: -- Store the binaries in an object store (GCS, S3, an internal artifact registry) keyed by version. +- Store the binaries in an object store (GCS, S3, an internal artifact registry) with a key for each version. - Configure Payload Manager in each customer org to pull the same set of named payloads from that source. -- Payload Manager re-syncs payloads every 24 hours, so refreshing a Viberails release across the fleet is a single upload at the source. +- Payload Manager re-syncs payloads every 24 hours. One upload at the source therefore updates a Viberails release across the fleet. -When you ship a new Viberails release, replace the artifacts at the source URL and the change propagates everywhere. +When you release a new Viberails version, replace the artifacts at the source URL. The change then propagates everywhere. ## Step 4 — Create the deployment D&R rule -The rule below fires when a tagged sensor connects, drops the right binary onto disk, runs Viberails as the **active console user** (so hooks install in that user's home directory rather than `root`/`SYSTEM`), then removes the tag so the rule only fires once per workstation. +The rule below fires when a tagged sensor connects. The rule writes the correct binary to disk. It then runs Viberails as the **active console user**, so the hooks install in the home directory of that user and not under `root`/`SYSTEM`. The rule then removes the tag, so it fires one time for each workstation. -Replace `` with the URL recorded for **this** customer in Step 1. Each customer gets a different value — when you sync the rule across customers via Git-Sync or templates, parameterize on this URL per org. +Replace `` with the URL that you recorded for **this** customer in Step 1. Each customer has a different value. When you sync the rule to many customers with Git-Sync or templates, make this URL a parameter for each org. ### Windows @@ -179,7 +179,7 @@ respond: tag: viberails-installed ``` -The PowerShell helper (`viberails-install.ps1`) — upload once as a payload alongside the binaries: +Upload the PowerShell helper (`viberails-install.ps1`) one time as a payload with the binaries: ```powershell param([Parameter(Mandatory = $true)][string]$TeamUrl) @@ -203,7 +203,7 @@ schtasks /Create /F /TN VRInstall /SC ONCE /ST 00:00 /Z ` schtasks /Run /TN VRInstall ``` -`/IT` makes the task run only when the named user is signed in, and `/Z` deletes the task definition once it completes. Sign and review this script before deploying it across customer orgs. +`/IT` runs the task only when the named user is signed in. `/Z` deletes the task definition after the task completes. Review and sign this script before you deploy it to customer orgs. ### macOS @@ -241,7 +241,7 @@ respond: tag: viberails-installed ``` -For Intel hardware, swap `viberails-macos-arm64` for `viberails-macos-x64`. If you have a mixed fleet, use two tags (`viberails-deploy-arm`, `viberails-deploy-x64`) applied per host so each rule picks the right payload — there is no `is arch` operator in D&R rules, so architecture must be encoded in the tag (or in the selector at tag-time via `limacharlie tag mass-add --selector 'arch == arm64 and ...'`). +For Intel hardware, replace `viberails-macos-arm64` with `viberails-macos-x64`. For a mixed fleet, use two tags (`viberails-deploy-arm`, `viberails-deploy-x64`) and apply one tag to each host, so that each rule selects the correct payload. D&R rules have no `is arch` operator, so you must put the architecture in the tag, or in the selector when you add the tag with `limacharlie tag mass-add --selector 'arch == arm64 and ...'`. ### Linux @@ -281,36 +281,42 @@ respond: ``` !!! warning "User-context matters" - Viberails stores its configuration in the **developer's** home directory — `~/.config/viberails/` on Linux, `~/Library/Application Support/viberails/` on macOS, `%APPDATA%\viberails\` on Windows — and installs hooks into per-tool config files there (`~/.claude/`, `~/.cursor/`, etc.). The binary lands at `~/.local/bin/viberails` on every platform. The endpoint agent runs payloads as `root`/`SYSTEM`, so the rules above explicitly drop privileges to the interactively signed-in user. Running Viberails as `root`/`SYSTEM` would install hooks for that account and leave the developer untouched. + Viberails stores its configuration in the home directory of the **developer**: `~/.config/viberails/` on Linux, `~/Library/Application Support/viberails/` on macOS, and `%APPDATA%\viberails\` on Windows. It installs hooks into the configuration file of each tool in that directory (`~/.claude/`, `~/.cursor/`, and others). The binary goes to `~/.local/bin/viberails` on every platform. The sensor runs payloads as `root`/`SYSTEM`, so the rules above drop privileges to the interactively signed-in user. Viberails as `root`/`SYSTEM` installs the hooks for that account and leaves the developer without hooks. - If no user is signed in when the rule fires, the install will fail. The simplest workaround is to fire on a different trigger that implies a user is present, or to leave the `viberails-deploy` tag in place until the rule sees a logged-in user and successfully completes. + If no user is signed in when the rule fires, the install fails. Use a different trigger that shows that a user is present. As an alternative, keep the `viberails-deploy` tag until the rule finds a signed-in user and completes. ## Step 5 — Distribute the rule to every customer org -Manage the rule the same way you manage every other MSSP-wide D&R rule. The two common patterns: +Manage the rule in the same way as every other MSSP-wide D&R rule. There are two common patterns: -- **Git-Sync.** Commit the rule (and the payload manifest) to your shared infrastructure repo and let [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md) push it to each customer org. Parameterize `` per-org through the templating mechanism your repo uses. -- **Organization Groups + IaC CLI.** Define the rule once and apply it to every organization in your "developer-coverage" Organization Group via `limacharlie configs push`. +- **Git-Sync.** Commit the rule and the payload manifest to your shared infrastructure repo. [Git-Sync](../../5-integrations/extensions/limacharlie/git-sync.md) then pushes them to each customer org. Make `` a parameter for each org with the template mechanism that your repo uses. +- **Organization Groups + IaC CLI.** Define the rule one time. Apply it to every organization in your "developer-coverage" Organization Group with `limacharlie configs push`. See [Designing Access for MSSPs](../../7-administration/access/designing-access.md) for the recommended Organization Group layout. ## Step 6 — Verify -For each newly tagged endpoint, confirm the install succeeded: +For each newly tagged endpoint, confirm that the install was successful: -1. **Task results in the sensor timeline.** Each `put` task produces a [`RECEIPT`](../../8-reference/edr-events.md#receipt) event; each `run --shell-command` produces an `EXEC_OOB` event (macOS/Linux) and an audit entry on Windows. Confirm there are no errors. Viberails itself prints `Joined team successfully!` and `Hooks installed successfully!` to STDOUT when invoked correctly. -2. **Tag rotation.** The sensor should now carry `viberails-installed` and no longer carry `viberails-deploy`. -3. **Viberails events flowing.** Watch the same customer org's timeline (or the dedicated Viberails view in the app) for the first AI tool events the next time a developer uses one of the hooked tools — they arrive via the `viberails` webhook adapter you created in Step 1. +1. **Task results in the sensor timeline.** Each `put` task produces a [`RECEIPT`](../../8-reference/edr-events.md#receipt) event. Each `run --shell-command` produces an `EXEC_OOB` event on macOS and Linux, and an audit entry on Windows. Confirm that there are no errors. Viberails prints `Joined team successfully!` and `Hooks installed successfully!` to STDOUT when the command is correct. +2. **Tag rotation.** The sensor now has the `viberails-installed` tag and no longer has the `viberails-deploy` tag. +3. **Viberails events flowing.** Watch the timeline of the same customer org, or the Viberails view in the app. The first AI tool events arrive when a developer next uses one of the hooked tools. The events come through the `viberails` webhook adapter that you created in Step 1. -If verification fails, enable Viberails debug logging on the affected machine and inspect the debug directory: `~/.local/share/viberails/debug/` on Linux, `~/Library/Application Support/viberails/debug/` on macOS, `%LOCALAPPDATA%\viberails\debug\` on Windows. See [Viberails Troubleshooting](https://github.com/refractionPOINT/viberails#troubleshooting). +If the check fails, enable Viberails debug logging on the affected machine and examine the debug directory: `~/.local/share/viberails/debug/` on Linux, `~/Library/Application Support/viberails/debug/` on macOS, `%LOCALAPPDATA%\viberails\debug\` on Windows. See [Viberails Troubleshooting](https://github.com/refractionPOINT/viberails#troubleshooting). ## Updating Viberails on the fleet -Viberails auto-upgrades itself by default whenever any hooked tool runs, so a one-shot install is normally enough. If you have disabled `auto_upgrade` per the [Viberails configuration](https://github.com/refractionPOINT/viberails#configuration), or you want to force-roll a version across all customer endpoints, add a second tag (e.g. `viberails-upgrade`) and a companion D&R rule that runs `viberails upgrade` instead of `install`. +By default, Viberails upgrades itself when a hooked tool runs, so one install is normally enough. If you disabled `auto_upgrade` in the [Viberails configuration](https://github.com/refractionPOINT/viberails#configuration), or you want to force a version onto all customer endpoints, add a second tag (for example, `viberails-upgrade`). Also add a companion D&R rule that runs `viberails upgrade` and not `install`. ## Removing Viberails -Use the same pattern in reverse: tag the targets `viberails-uninstall`, drop the binary as a payload, and run `viberails uninstall-all --yes` in the user's context. The `--yes` flag suppresses the interactive confirmation, which is essential under a non-interactive payload `run`. +Use the same pattern in reverse: + +1. Tag the targets `viberails-uninstall`. +2. Send the binary as a payload. +3. Run `viberails uninstall-all --yes` in the context of the user. + +The `--yes` flag removes the interactive confirmation. A non-interactive payload `run` needs this flag. --- diff --git a/docs/2-sensors-deployment/tutorials/windows-event-logs.md b/docs/2-sensors-deployment/tutorials/windows-event-logs.md index ed91b9ef6..e7944a1d4 100644 --- a/docs/2-sensors-deployment/tutorials/windows-event-logs.md +++ b/docs/2-sensors-deployment/tutorials/windows-event-logs.md @@ -1,27 +1,27 @@ # Ingesting Windows Event Logs -You can enable real-time Windows Event Log (WEL) ingestion using the LimaCharlie EDR Sensor. +You can enable real-time ingestion of Windows Event Logs (WEL) with the LimaCharlie EDR Sensor. -First, navigate to the Exfil Control section of LimaCharlie and ensure that `WEL` events are enabled for your Windows rules. +1. Go to the Exfil Control section of LimaCharlie. Make sure that `WEL` events are enabled for your Windows rules. -![ingest wel 1](../../assets/images/ingest-wel-1.png) + ![ingest wel 1](../../assets/images/ingest-wel-1.png) -Next, navigate to the `Artifact Collection` section and set up an artifact collection rule for the Windows Event Log(s) of interest. +2. Go to the `Artifact Collection` section. Add an artifact collection rule for each Windows Event Log that you want. -![ingest wel 2](../../assets/images/ingest-wel-2.png) + ![ingest wel 2](../../assets/images/ingest-wel-2.png) -To ingest WEL real-time events in the timeline, use the `wel://[Log Name]` format. For example, to ingest the System event log, you'd use the following pattern: +3. To ingest WEL real-time events in the timeline, use the `wel://[Log Name]` format. For example, use this pattern for the System event log: -`wel://system:*` + `wel://system:*` -![ingest wel 3](../../assets/images/ingest-wel-3.png) + ![ingest wel 3](../../assets/images/ingest-wel-3.png) Difference between `.evtx` versus `wel://` ingestion -If you specify the file on disk, via the `evtx` file extension (as seen in the image above), LimaCharlie will upload the entire Windows Event Log file from disk. This will be represented as a collected artifact, not as real-time events on the sensor's timeline. This method incurs regular artifact ingestion costs for "Telemetry Sources" as seen on our [pricing](https://limacharlie.io/pricing) page. +If you specify the file on disk with the `evtx` file extension, as in the image above, LimaCharlie uploads the full Windows Event Log file from disk. The file becomes a collected artifact, not real-time events on the timeline of the sensor. This method has the regular artifact ingestion costs for "Telemetry Sources" on the [pricing](https://limacharlie.io/pricing) page. -If you ingest Windows Event Logs with a `wel://` pattern, they are streamed in real-time as first-class telemetry alongside the native EDR events, and are included in the flat rate price of the sensor. +If you ingest Windows Event Logs with a `wel://` pattern, the sensor streams them in real time with the native EDR events. The flat rate price of the sensor includes them. -After you apply those, you should start seeing your Windows Event Log data coming through for your endpoints. You can verify this by going into the Timeline view and choosing `WEL` event type. +After you apply these settings, the Windows Event Log data from your endpoints starts to arrive. To check this, open the Timeline view and select the `WEL` event type. ![ingest wel 4](../../assets/images/ingest-wel-4.png) diff --git a/docs/3-detection-response/alternate-targets.md b/docs/3-detection-response/alternate-targets.md index afde6a80a..e169f4d39 100644 --- a/docs/3-detection-response/alternate-targets.md +++ b/docs/3-detection-response/alternate-targets.md @@ -1,6 +1,6 @@ # Detection on Alternate Targets -Detection & Response rules run against `edr` events by default, however, there are 7 other targets: +Detection & Response rules run against `edr` events by default. There are 7 other targets: - `detection` - `deployment` @@ -10,17 +10,17 @@ Detection & Response rules run against `edr` events by default, however, there a - `audit` - `billing` -This article is to give some ideas of what they're used for, and how they're used. +This page gives examples of what these targets are for and how to use them. ## Target: detection -You can run rules on detections generated by other rules. This allows you to further filter existing detections -and change add a response behavior to certain special cases. +You can run rules on the detections that other rules generate. These rules let you filter +existing detections and add a response for special cases. -In the `detection` target, the `event:` or `events:` specified refer to the `name` of the detection specified in the -original detection's `report` action. +In the `detection` target, the `event:` or `events:` field refers to the `name` of the detection +in the `report` action of the original detection. -The `detection` target supports all of the same operators and actions as regular `edr` rules. +The `detection` target supports the same operators and actions as regular `edr` rules. ### Example @@ -49,15 +49,16 @@ rules: class: '{{ "dr-rules" }}' ``` -This rule takes a pre-existing detection report named `virus-total-hit` and sends it to PagerDuty if it occurs on a specific hostname. +This rule takes an existing detection report with the name `virus-total-hit`. If the detection +occurs on a specific hostname, the rule sends it to PagerDuty. ## Target: deployment -Deployment events relate to sensors connecting to the cloud: `enrollment`, `sensor_clone`, `sensor_over_quota`, `deleted_sensor`. +Deployment events are about sensors that connect to the cloud: `enrollment`, `sensor_clone`, `sensor_over_quota`, `deleted_sensor`. -Take the `sensor_clone` event as an example. This event can happen when a Sensor is installed in a VM image, leading to duplicate sensor IDs connecting to the cloud. When this is detected we can use this event to automate behavior to de-duplicate the sensor. +The `sensor_clone` event is an example. This event can occur when a sensor is installed in a VM image. Duplicate sensor IDs then connect to the cloud. When the cloud detects this, you can use the event to de-duplicate the sensor automatically. -The `deployment` target supports all of the same operators and actions as regular `edr` rules. +The `deployment` target supports the same operators and actions as regular `edr` rules. ### Example @@ -78,17 +79,17 @@ op: is windows command: restart ``` -This rule de-duplicates sensors on Windows by deleting `.dat` files specific to the Windows installation and then issuing a `restart` sensor command. +This rule de-duplicates sensors on Windows. It deletes the `.dat` files of the Windows installation, then it sends a `restart` command to the sensor. > For samples of each `deployment` event type, see [Reference: Platform Events](../8-reference/platform-events.md). ## Target: artifact -Parsed artifacts can be run through the rule engine as if they were regular `edr` events, but there are some key differences. Namely, they support a subset of operators and actions, while adding some special parameters. +The rule engine can process parsed artifacts as if they are regular `edr` events, but there are differences. Artifacts support only a subset of the operators and actions, and they add special parameters. ### Example -This rule will target parsed `/var/log/auth.log` entries to see if there are are auth failures. +This rule targets parsed `/var/log/auth.log` entries and finds authentication failures. ```yaml # Detection @@ -121,11 +122,11 @@ case sensitive: false ### Supported Resources -`lookup` and `external` resources are supported within rules just like the `edr` target. +Rules support the `lookup` and `external` resources, the same as the `edr` target. ### Supported Actions -The only response action supported for the `artifact` target is the `report` action. +The `artifact` target supports only the `report` response action. ### Special Parameters @@ -133,11 +134,11 @@ The only response action supported for the `artifact` target is the `report` act - `artifact type`: matches the artifact's `type` string, e.g. `pcap`, `zeek`, `auth`, `wel` - `artifact source`: matches the artifact's `source` string, e.g. `hostname-123` -> Note: for duplicate Windows Event Log ingestions, the rule engine will use the log's `EventRecordID` to ensure a rule will not run more than once over the same record. +> Note: for duplicate ingestions of Windows Event Logs, the rule engine uses the `EventRecordID` of the log. This makes sure that a rule does not run more than one time on the same record. ## Target: artifact\_event -For unparsed logs, it can be useful to use the `ingest` and `export_complete` lifecycle events from the `artifact_event` target to automate behaviors in response to artifacts. +For unparsed logs, use the `ingest` and `export_complete` lifecycle events of the `artifact_event` target. These events let you automate a response to artifacts. > For samples of `ingest` and `export_complete`, see [Reference: Platform Events](../8-reference/platform-events.md). @@ -159,14 +160,14 @@ case sensitive: false ## Target: schedule -Schedule events are triggered automatically at various intervals per Organization or per Sensor, observable in rules via the `schedule` target. +Schedule events occur automatically at different intervals for each organization or for each sensor. Rules see these events through the `schedule` target. For more information, see [Reference: Schedule Events](../8-reference/schedule-events.md) ## Target: audit -Audit events are generated by the LimaCharlie platform and track changes and events from within the platform such as tasking, replays, hive changes, etc. These events can be viewed within the "Platform Logs" menu or by viewing events from the `audit-logs` sensor. +The LimaCharlie cloud generates audit events. They track changes and events in the cloud, such as tasking, replays, and hive changes. To see these events, use the "Platform Logs" menu or the events from the `audit-logs` sensor. ## Target: billing -Billing events are generated by the LimaCharlie platform and are related to aspects of the platform such as quotas, thresholds, and other cost-associated events. For an example, see the [Usage Alerts Extension](../5-integrations/extensions/limacharlie/usage-alerts.md) documentation +The LimaCharlie cloud generates billing events. They are about quotas, thresholds, and other events related to cost. For an example, see the [Usage Alerts Extension](../5-integrations/extensions/limacharlie/usage-alerts.md) documentation diff --git a/docs/3-detection-response/behavioral-detection.md b/docs/3-detection-response/behavioral-detection.md index d24fdcc52..e64fd57f8 100644 --- a/docs/3-detection-response/behavioral-detection.md +++ b/docs/3-detection-response/behavioral-detection.md @@ -2,12 +2,12 @@ ## Overview -LimaCharlie supports behavioral detection patterns using D&R rules and the suppression system. These patterns detect anomalous behavior — like a user logging in from a new country or a host resolving an unusual domain — without requiring external analytics infrastructure. +LimaCharlie supports behavioral detection patterns with D&R rules and the suppression system. These patterns detect unusual behavior, for example a user that logs in from a new country, or a host that resolves an unusual domain. They do not need external analytics infrastructure. This page covers: -- **First-Seen Detection** — alert the first time a specific combination of entity + behavior is observed -- **Cardinality Detection** — alert when an entity exceeds a threshold of unique values (e.g., unique domains, unique hosts) +- **First-Seen Detection** — alert the first time that a specific combination of entity and behavior occurs +- **Cardinality Detection** — alert when an entity goes above a threshold of unique values (e.g., unique domains, unique hosts) - **Volume Detection** — alert when a cumulative metric (e.g., bytes transferred) crosses a threshold - **Multi-Signal Aggregation** — combine multiple detection signals into a composite risk indicator @@ -15,11 +15,11 @@ All patterns use the existing D&R rules engine and [suppression](../8-reference/ ## First-Seen Detection -Suppression with `max_count: 1` fires an action exactly once per unique key combination per time window. This makes it a first-seen detector: the first time a `(entity, value)` pair is observed, the action fires. For the rest of the window, it is suppressed. +Suppression with `max_count: 1` fires an action one time only for each unique key combination in each time window. This makes it a first-seen detector. The action fires the first time that an `(entity, value)` pair occurs. For the rest of the window, suppression stops the action. ### First-Seen with Event Fields -When the value you want to track is directly in the event, a single rule is sufficient. +When the value that you track is in the event, one rule is enough. **First time a host resolves a domain (within 30 days):** @@ -41,7 +41,7 @@ respond: - '{{ .event.DOMAIN_NAME }}' ``` -The suppression key combines a constant label with the domain name, scoped per-sensor (`is_global: false`). The first DNS request for a given domain on a given sensor fires the report. Subsequent requests for the same domain on the same sensor are suppressed for 30 days. +The suppression key combines a constant label with the domain name. The scope is one sensor (`is_global: false`). The first DNS request for a domain on a sensor fires the report. Suppression stops the later requests for the same domain on the same sensor for 30 days. **First time a process hash runs on a host:** @@ -84,13 +84,13 @@ respond: - '{{ .event.SOURCE_IP }}' ``` -Using `is_global: true` means the suppression is org-wide — the counter is shared across all sensors. This is important for user-scoped detections where the user may log in from different sensors. +`is_global: true` makes the suppression org-wide. All sensors share the counter. This is important for detections that are scoped to a user, because the user can log in from different sensors. ### First-Seen with Lookup Metadata -When the value you want to track is derived from a lookup (e.g., a GeoIP country from an IP address), the lookup metadata can be referenced in suppression key templates using the `.mtd` namespace. +When a lookup supplies the value that you track (e.g., a GeoIP country from an IP address), you can use the lookup metadata in the suppression key templates. Use the `.mtd` namespace. -The `.mtd` namespace contains the metadata returned by the detection's lookup operator. The key name is the resource name with special characters replaced by underscores. For the [IP Geolocation](../5-integrations/api-integrations/ip-geolocation.md) lookup (`lcr://api/ip-geo`), the metadata is available under `.mtd.lcr___api_ip_geo`. +The `.mtd` namespace contains the metadata that the lookup operator of the detection returns. The key name is the resource name, with underscores in place of the special characters. For the [IP Geolocation](../5-integrations/api-integrations/ip-geolocation.md) lookup (`lcr://api/ip-geo`), the metadata is under `.mtd.lcr___api_ip_geo`. **First time a user logs in from a new country:** @@ -117,9 +117,9 @@ respond: This rule: 1. Matches every `USER_LOGIN` event -2. Looks up the `SOURCE_IP` via the GeoIP API -3. Generates a suppression key from the user name and the resolved country ISO code -4. Reports once per unique `(user, country)` combination per 30 days +2. Looks up the `SOURCE_IP` with the GeoIP API +3. Generates a suppression key from the user name and the country ISO code +4. Reports one time for each unique `(user, country)` combination in 30 days **First time a user logs in from a new ASN:** @@ -167,7 +167,7 @@ respond: > **Metadata Key Naming** > -> The `.mtd` key name is derived from the lookup resource name with `/` and `:` replaced by `_`. For example: +> The `.mtd` key name comes from the lookup resource name, with `_` in place of `/` and `:`. For example: > > - `lcr://api/ip-geo` becomes `.mtd.lcr___api_ip_geo` > - `lcr://api/ip-asn` becomes `.mtd.lcr___api_ip_asn` @@ -175,7 +175,7 @@ respond: ### Combining First-Seen with Other Operators -First-seen detection composes naturally with all D&R operators using `and`/`or`: +First-seen detection combines with all D&R operators through `and`/`or`: **First time a rare domain is resolved on a VIP host:** @@ -205,14 +205,14 @@ respond: ## Cardinality Detection -To detect when an entity accumulates too many unique values (e.g., a host resolving an unusual number of unique domains), use a **two-rule chaining pattern**: +Some entities accumulate too many unique values. An example is a host that resolves an unusual number of unique domains. To detect this, use a **two-rule chaining pattern**: -1. **Rule 1 (dedup):** Reports once per unique value using `max_count: 1` -2. **Rule 2 (count):** Targets the detection from Rule 1 and counts using `min_count: N` +1. **Rule 1 (dedup):** Reports one time for each unique value with `max_count: 1` +2. **Rule 2 (count):** Targets the detection from Rule 1 and counts with `min_count: N` ### Example: DGA / C2 Beaconing Detection -Detect a host resolving more than 100 unique domains in 1 hour: +Detect a host that resolves more than 100 unique domains in 1 hour: ```yaml # Rule 1: Deduplicate — report once per unique domain per sensor per hour @@ -253,11 +253,11 @@ respond: - 'dns-diversity-count' ``` -Rule 1 fires once per unique domain per sensor per hour (deduplication). Rule 2 chains on the `detection` target, counting how many unique domains triggered Rule 1. When the count reaches 100, Rule 2 fires exactly once. +Rule 1 fires one time for each unique domain, for each sensor, in each hour (deduplication). Rule 2 chains on the `detection` target and counts the unique domains that triggered Rule 1. When the count reaches 100, Rule 2 fires one time only. ### Example: Lateral Movement Detection -Detect a user accessing more than 5 unique hosts in 6 hours: +Detect a user that accesses more than 5 unique hosts in 6 hours: ```yaml # Rule 1: Deduplicate per (user, host) @@ -302,7 +302,7 @@ respond: ### Example: Excessive External Connections -Detect a host connecting to more than 50 unique external IPs in 1 hour: +Detect a host that connects to more than 50 unique external IPs in 1 hour: ```yaml # Rule 1: Deduplicate unique external destination IPs per sensor @@ -345,7 +345,7 @@ respond: ## Volume Detection -The `count_path` suppression parameter increments the counter by a value extracted from the event instead of by 1. This enables threshold detection on cumulative metrics like bytes transferred. +The `count_path` suppression parameter increments the counter by a value from the event, and not by 1. This lets you detect a threshold on cumulative metrics such as the bytes transferred. ### Example: Data Exfiltration Threshold @@ -370,15 +370,15 @@ respond: - 'egress-volume' ``` -The counter increments by the value at `event/bytes_out` for each matching event. When the cumulative bytes reach 1 GB (1,073,741,824 bytes), the report fires exactly once. +The counter increments by the value at `event/bytes_out` for each matching event. When the cumulative bytes reach 1 GB (1,073,741,824 bytes), the report fires one time only. ## Multi-Signal Aggregation -Multiple detection rules can feed into a shared suppression counter to create a composite risk indicator. When independent detections all report with a shared key, the counter accumulates across them. +Many detection rules can feed one shared suppression counter to make a composite risk indicator. When independent detections report with a shared key, the counter accumulates across them. ### Example: Risk Score Aggregation -Individual indicator rules each generate a detection: +Each indicator rule generates a detection: ```yaml # Rule A: Suspicious DNS resolution @@ -405,7 +405,7 @@ respond: name: indicator-hit ``` -Aggregation rule — fires when 5 indicators accumulate on a single host in 1 hour: +The aggregation rule fires when 5 indicators accumulate on one host in 1 hour: ```yaml detect: @@ -427,18 +427,18 @@ respond: - 'risk-aggregation' ``` -Since both Rule A and Rule B report the same detection name (`indicator-hit`), the aggregation rule counts them together. Different types of suspicious activity on the same host contribute to the same counter. +Because Rule A and Rule B report the same detection name (`indicator-hit`), the aggregation rule counts them together. Different types of suspicious activity on the same host add to the same counter. ## Suppression Parameter Reference | Parameter | Type | Description | |-----------|------|-------------| -| `max_count` | integer | Maximum action executions per period per key. Use `1` for first-seen. | -| `min_count` | integer | Minimum activations before the action fires. Must be used with `max_count`. | +| `max_count` | integer | Maximum number of times that the action runs in each period for each key. Use `1` for first-seen. | +| `min_count` | integer | Minimum number of activations before the action fires. You must use it with `max_count`. | | `period` | string | Time window. Formats: `s`, `m`, `h`. Range: 1s to 720h (30 days). | | `is_global` | boolean | `true` = org-wide counter. `false` (default) = per-sensor counter. | | `keys` | list | Template strings that form the uniqueness key. Supports `{{ .event.* }}`, `{{ .routing.* }}`, and `{{ .mtd.* }}`. | -| `count_path` | string | Path to an integer in the event to use as the increment value instead of 1. | +| `count_path` | string | Path to an integer in the event. The counter uses this value as the increment, and not 1. | ### Template Namespaces in Keys @@ -450,11 +450,11 @@ Since both Rule A and Rule B report the same detection name (`indicator-hit`), t ## Limitations -- **Static thresholds only.** The thresholds (count values, periods) are user-defined constants. There is no adaptive baseline that learns "normal" from historical data. -- **Fixed time windows.** The suppression period is a fixed window that resets on expiry, not a rolling/sliding window. +- **Static thresholds only.** The thresholds (count values, periods) are constants that you set. There is no adaptive baseline that learns "normal" from historical data. +- **Fixed time windows.** The suppression period is a fixed window that resets when it expires. It is not a rolling or sliding window. - **Maximum period: 30 days.** Suppression counters reset after the period expires. "First seen within 30 days" is the longest tracking window. -- **No statistical comparison.** These patterns detect "above N" or "first occurrence" — they cannot detect "unusual compared to historical baseline." -- **Cardinality detection requires two rules.** The dedup+count pattern needs rule chaining via the `detection` target. +- **No statistical comparison.** These patterns detect "above N" or "first occurrence". They cannot detect "unusual compared to historical baseline." +- **Cardinality detection needs two rules.** The dedup+count pattern needs rule chaining through the `detection` target. --- diff --git a/docs/3-detection-response/examples.md b/docs/3-detection-response/examples.md index a9d4fa369..be851510c 100644 --- a/docs/3-detection-response/examples.md +++ b/docs/3-detection-response/examples.md @@ -1,18 +1,18 @@ # Detection and Response Examples -The following are sample detection and response rules can help you get started in crafting efficient rules utilizing LimaCharlie's telemetry. In addition to these rules, we also recommend checking out [Sigma Rules](managed-rulesets/sigma-converter.md) for more rules. +These sample detection and response rules help you write efficient rules with LimaCharlie telemetry. For more rules, see [Sigma Rules](managed-rulesets/sigma-converter.md). ## Translating Existing Rules -Before listing examples, it's worth mentioning [uncoder.io](https://uncoder.io/) by [SOC Prime](https://socprime.com/) is a great resource for learning by analogy. If you're already familiar with another platform for rules or search queries (Sigma, Splunk, Kibana, etc.) you can use uncoder to translate to LimaCharlie's D&R rules. +[uncoder.io](https://uncoder.io/) by [SOC Prime](https://socprime.com/) helps you learn by analogy. If you know another platform for rules or search queries (Sigma, Splunk, Kibana, etc.), you can use uncoder to translate to LimaCharlie D&R rules. -Looking for more? +More resources are available. -Check out this video that shows you the power of leveraging community resources with LimaCharlie +This video shows how to use community resources with LimaCharlie. ## Examples -Note that through limacharlie.io, in order to provide an easier to edit format, the same rule configuration is used but is in YAML format instead. For example: +In limacharlie.io, the same rule configuration is in YAML format. This format is easier to edit. For example: ```yaml # Detection @@ -54,7 +54,7 @@ case sensitive: false ### Classify Users -Tag any Sensor where the CEO logs in with "vip". +Add the "vip" tag to any Sensor where the CEO logs in. ```yaml # Detection @@ -71,7 +71,7 @@ case sensitive: false ### SSH from External IP Address -The following example looks for connections to/from `sshd` involving a non-RFC1918 IP Address. Be mindful that this is only looking for network connections, not actual logons, so this could be noisy on an internet-facing system but still indicative of an exposed service. +This example looks for connections to or from `sshd` with a non-RFC1918 IP address. The rule looks only for network connections, not for logons. On an internet-facing system the rule can be noisy, but it still shows an exposed service. ```yaml # Detection @@ -94,7 +94,7 @@ The `report` uses [Go Templates](../4-data-queries/template-strings.md) to inclu ### RDP from External IP Address -Similar to the above SSH example, this example looks for RDP connections from an external IP address. Be mindful that this is only looking for network connections, not actual logons, so this could be noisy on an internet-facing system but still indicative of an exposed service. +This example is similar to the SSH example above. It looks for RDP connections from an external IP address. The rule looks only for network connections, not for logons. On an internet-facing system the rule can be noisy, but it still shows an exposed service. ```yaml # Detection @@ -138,7 +138,7 @@ re: .*((\\.txt)|(\\.doc.?)|(\\.ppt.?)|(\\.xls.?)|(\\.zip)|(\\.rar)|(\\.rtf)|(\\. ### Disable an Event at the Source -Turn off the sending of a specific event to the cloud. Useful to limit some verbose data sources when not needed. +Stop the sensor from sending a specific event to the cloud. Use this rule to limit verbose data sources that you do not need. ```yaml # Detection @@ -153,7 +153,7 @@ name: windows ### Windows Event Logs -A simple example of looking for a specific Event ID in WEL events. +This example looks for a specific Event ID in WEL events. ```yaml # Detection @@ -174,7 +174,7 @@ rules: ### Nested Logic -An example demonstrating nested boolean logic. This detection looks specifically for the following conditions: +This example shows nested boolean logic. The detection looks for these conditions: ((`4697` OR `7045`) in the `System` log) OR (`4698` in the `Security` log) ```yaml @@ -209,7 +209,7 @@ rules: #### Monitoring Sensitive Directories -Make sure the File Integrity Monitoring of some directories is enabled whenever Windows sensors connect. +Enable File Integrity Monitoring of some directories each time that a Windows sensor connects. ```yaml # Detection @@ -237,7 +237,7 @@ name: linux #### FIM Hit Detection -Adding a FIM pattern with `fim_add` by itself will only cause `FIM_HIT` events to be generated on the affected system's timeline. To know that we have positive hits on a FIM rule, we want to capture the relevant event and generate a proper Detection. +A FIM pattern that you add with `fim_add` only puts `FIM_HIT` events on the timeline of the affected system. To see the hits on a FIM rule, capture the event and generate a Detection. ```yaml # Detection @@ -254,13 +254,13 @@ path: event/FILE_PATH Resource Utilization -Performing CPU intensive actions such as YARA scanning can impact endpoint performance if not optimized. Be sure to always test rules that carry out sensor commands (like the examples below) before deploying at scale in production. Use [suppression](../8-reference/response-actions.md#suppression) to prevent runaway conditions. +CPU intensive actions such as a YARA scan can decrease endpoint performance. Always test rules that run sensor commands, such as the examples below, before you deploy them at scale in production. Use [suppression](../8-reference/response-actions.md#suppression) to stop runaway conditions. -Here are a few examples of using D&R rules to initiate automatic YARA scans on an endpoint. Note that the defined YARA rule must exist in your org before using it in a D&R rule. +These examples use D&R rules to start automatic YARA scans on an endpoint. The YARA rule must exist in your organization before you use it in a D&R rule. #### YARA Scan Processes -This example looks for `NEW_PROCESS` events that meet certain criteria, then initiates a YARA scan against the offending process ID in memory. Note, this or a similar D&R rule will also depend on a companion [YARA Detection](#yara-detections) rule. +This example looks for `NEW_PROCESS` events that obey some criteria. It then starts a YARA scan of the process ID in memory. This rule, or a similar rule, also needs a companion [YARA Detection](#yara-detections) rule. ```yaml # Detection @@ -291,11 +291,11 @@ rules: period: 1m ``` -Notice the use of `suppression` to prevent the same `PROCESS_ID` from being scanned more than once per minute to prevent a resource runaway situation. +The `suppression` block stops a scan of the same `PROCESS_ID` more than one time each minute. This stops a resource runaway situation. #### YARA Scan Files -This example looks for `NEW_DOCUMENT` events that meet certain criteria, then initiates a YARA scan against the offending file path. Note, this or a similar D&R rule will also depend on a companion [YARA Detection](#yara-detections) rule. +This example looks for `NEW_DOCUMENT` events that obey some criteria. It then starts a YARA scan of the file path. This rule, or a similar rule, also needs a companion [YARA Detection](#yara-detections) rule. ```yaml # Detection @@ -328,11 +328,11 @@ rules: period: 1m ``` -Notice the use of `suppression` to prevent the same `FILE_PATH` from being scanned more than once per minute to prevent a resource runaway situation. +The `suppression` block stops a scan of the same `FILE_PATH` more than one time each minute. This stops a resource runaway situation. ### YARA Detections -Running a YARA scan by itself only sends a `YARA_DETECTION` event to the affected system's timeline. To know that we have positive hits on a YARA scan, we want to capture the relevant event and generate a proper Detection. The following two examples split out a YARA detection on-disk, versus in-memory. Notice we simply check for the presence of `event/PROCESS/*` fields to determine if it's a file or process detection, which may have different severities to security teams (dormant malware versus running malware). +A YARA scan only sends a `YARA_DETECTION` event to the timeline of the affected system. To see the hits from a YARA scan, capture the event and generate a Detection. The two examples below separate a YARA detection on disk from a YARA detection in memory. The rules check for `event/PROCESS/*` fields to find if the detection is a file or a process. Security teams can give a different severity to each one (dormant malware or running malware). #### YARA Detection On-Disk (file) @@ -375,7 +375,7 @@ rules: ttl: 80000 ``` -Both rules will generate a Detection report and add a tag to the system which the detection occurred on. +Both rules generate a Detection report and add a tag to the system where the detection occurred. ### Mention of an Internal Resource @@ -395,9 +395,9 @@ value: /corp/private/info ### De-duplicate Cloned Sensors -Sometimes users install a sensor on a VM image by mistake. This means every time a new instance of the image gets started the same sensor ID (SID) is used for multiple boxes with different names. When detected, LimaCharlie produces a `sensor_clone` event. +Sometimes users install a sensor on a VM image by mistake. Each new instance of the image then uses the same sensor ID (SID) on different machines with different names. When LimaCharlie detects this, it produces a `sensor_clone` event. -We can use these events to deduplicate. This example targets Windows clones. +You can use these events to deduplicate. This example targets Windows clones. ```yaml # Detection @@ -410,7 +410,7 @@ name: windows - action: re-enroll ``` -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Sensors send telemetry to the LimaCharlie cloud as EDR telemetry or as forwarded logs. Sensors are a scalable, serverless solution that connects the endpoints of an organization to the cloud securely. --- diff --git a/docs/3-detection-response/false-positives.md b/docs/3-detection-response/false-positives.md index dd00f53f9..06e8e9ac9 100644 --- a/docs/3-detection-response/false-positives.md +++ b/docs/3-detection-response/false-positives.md @@ -1,61 +1,61 @@ # False Positive Rules -To reduce the number of false positives, you may want to create false positive (FP) rules. FP rules filter out detections generated by the `report` action of detection & response (D&R) rules. These rules apply globally across all rule namespaces and targets. +To reduce the number of false positives, create false positive (FP) rules. FP rules filter out the detections that the `report` action of detection & response (D&R) rules generates. These rules apply globally to all rule namespaces and targets. -There are multiple ways to create a false positive rule in LimaCharlie web app. +You can create a false positive rule in the LimaCharlie web app in more than one way. -Have multiple organizations? +Consider the case of more than one organization. -Similar to detection & response rules, false positive rules are created on a per tenant level. This means that if you have more than one organization you want to apply the rule to, you will want to: +LimaCharlie creates false positive rules for each organization, the same as D&R rules. To apply the same rule to more than one organization, do one of these: -- re-create the same rule in multiple organizations, or -- using our infrastructure as code functionality, push your FP rules to multiple tenants within seconds. +- create the same rule again in each organization, or +- push your FP rules to many organizations with the infrastructure as code functionality. ## Use Cases -The typical use case for FP rules is to add exceptions from some detections that are cross-cutting (for example ignore all detections from a specific host), organization-specific exceptions (like ignoring alerts relating to a custom piece of software used in an organization), or suppressing errors from managed rules you don't have direct access to. +FP rules add exceptions for detections. Use them for cross-cutting exceptions, for example to ignore all detections from one host. Use them for exceptions that are specific to an organization, for example to ignore alerts about custom software. Use them also to suppress errors from managed rules that you cannot access directly. ## Structure -False positive rules are structured roughly the same as the detection part of a D&R rule. The main difference is that instead of a direct event, the rule applies to the content of a detection, as can be seen in the **Detections** section of the web app. +A false positive rule has about the same structure as the detection part of a D&R rule. The difference is that the rule applies to the content of a detection, not to an event. The **Detections** section of the web app shows this content. -The originating event for the detection can still be accessed at the `detect` path. This means that if ignoring something based on the event content, we only need to add `detect/` to the front of the `path` (see [example](#ignore-detections-for-specific-file-name)). +The `detect` path still gives access to the event that caused the detection. To ignore something because of the event content, add `detect/` to the front of the `path`. For an example, see [ignore detections for a specific file name](#ignore-detections-for-specific-file-name). ## Create a False Positive Rule From Detections -This is the quickest and the most common way to create a FP rule. On every detection, you can click the `Mark False Positive` button. +This is the fastest and the most common way to create an FP rule. On every detection, click the `Mark False Positive` button. ![fp rules 1](../assets/images/fp-rules-1.png) -Clicking the button will pre-populate the details of the event and automatically generate a draft false positive rule which you can edit before saving. +The button fills in the details of the event and generates a draft false positive rule. You can edit the draft before you save it. -After the rule is saved, it will appear in the **False Positives Rules** section and can be edited/deleted there. +After you save the rule, it appears in the **False Positives Rules** section. You can edit or delete it there. ## Create a False Positive rule from scratch -While creating FP rule from detections is a common and easy way to reduce the number of false positives, you do not need to wait for the detection to happen before creating a FP rule. The `False Positive Rules` section under `Automation` allows you to create a false positive rule from scratch. +You do not need to wait for a detection before you create an FP rule. The `False Positive Rules` section under `Automation` lets you create a false positive rule from scratch. To create a new false positive rule, click the `New Rule` button. ![fp rules 2](../assets/images/fp-rules-2.png) -This will open a rule editor allowing you to create a new rule. +The rule editor opens, where you create the new rule. ![fp rules 3](../assets/images/fp-rules-3.png) -An FP rule is structured with the same format at the detection component of a D&R rule. The main difference is that the rule applies to the content of a detection, as can be seen in the Detections section of the web app. +An FP rule uses the same format as the detection component of a D&R rule. The difference is that the rule applies to the content of a detection. The Detections section of the web app shows this content. -You have the ability to set a rule name as well as an **Expiry Date** (optional). Setting an expiry date allows you to create a rule that will expire at a certain time. +You can set a rule name and an optional **Expiry Date**. An expiry date makes the rule expire at a set time. -Please note that expiry times must be set in the user's preferred time (not in UTC). +Set expiry times in the preferred time of the user, not in UTC. ## Examples -Clicking the button will pre-populate the details of the event and automatically generate a draft false positive rule which you can edit before saving. The details about the structure of the false positive rules can be found in our technical documentation. +The button fills in the details of the event and generates a draft false positive rule. You can edit the draft before you save it. The technical documentation gives the details about the structure of false positive rules. ### Suppress a Specific Detection -Prevent a specific detection: +Stop a specific detection: ```yaml op: is @@ -75,7 +75,7 @@ value: this_is_fine.exe ### Ignore Detections on a Specific Host -Any detection originating from a specific host will be ignored. +This rule ignores every detection that comes from a specific host. ```yaml op: is @@ -280,7 +280,7 @@ value: web-server-2 ``` !!! warning - The API **replaces** `usr_mtd` entirely. Sending only `{"enabled":false}` will reset tags, expiry, and comment to their defaults. Always read the current metadata first and resend all fields. + The API **replaces** all of `usr_mtd`. If you send only `{"enabled":false}`, the API resets tags, expiry, and comment to their defaults. Always read the current metadata first, then send all fields again. === "Python" diff --git a/docs/3-detection-response/index.md b/docs/3-detection-response/index.md index 6361f7daa..6245757fc 100644 --- a/docs/3-detection-response/index.md +++ b/docs/3-detection-response/index.md @@ -6,12 +6,12 @@ Build custom detection logic with automated response actions. - [Detection and Response Examples](examples.md) - Sample detection rules - [Detection on Alternate Targets](alternate-targets.md) - Detections beyond endpoint events -- [False Positive Rules](false-positives.md) - Managing false positives +- [False Positive Rules](false-positives.md) - How to manage false positives - [Writing and Testing Rules](tutorials/writing-testing-rules.md) - Rule development guide - [Stateful Rules](stateful-rules.md) - Rules with state tracking - [Sensor Variables](sensor-variables.md) - Share state across rules with per-sensor variables -- [Unit Tests](unit-tests.md) - Testing detection rules -- [Replay](../5-integrations/services/replay.md) - Replaying events for testing +- [Unit Tests](unit-tests.md) - Tests for detection rules +- [Replay](../5-integrations/services/replay.md) - Replay of events for tests ## Programmatic Management @@ -213,7 +213,7 @@ Build custom detection logic with automated response actions. ``` !!! warning - The API **replaces** `usr_mtd` entirely. Sending only `{"enabled":false}` will reset tags, expiry, and comment to their defaults. Always read the current metadata first and resend all fields. + The API **replaces** all of `usr_mtd`. If you send only `{"enabled":false}`, the API resets tags, expiry, and comment to their defaults. Always read the current metadata first, then send all fields again. === "Python" diff --git a/docs/3-detection-response/managed-rulesets/community-rules.md b/docs/3-detection-response/managed-rulesets/community-rules.md index 7078371da..6675082d7 100644 --- a/docs/3-detection-response/managed-rulesets/community-rules.md +++ b/docs/3-detection-response/managed-rulesets/community-rules.md @@ -1,6 +1,6 @@ # Community Rules -Our Community Rules feature leverages the power of AI to quickly transform a plethora of third-party rules into LimaCharlie syntax so you can make them your own. The process is fast and efficient: Browse thousands of community rules, select one as a starting point, convert it to LimaCharlie syntax with one click, and customize it to your liking. +The Community Rules feature uses AI to convert third-party rules into LimaCharlie syntax. Browse thousands of community rules and select one as a start. Convert it to LimaCharlie syntax with one click, then change it for your needs. ## Accessing the Community Rules @@ -15,26 +15,26 @@ To access the Community Rules: 7. Look in the upper right corner of the rule creation page for the Community Library button 8. Click the Community Library button -This takes you to the Community Rules search page, and gives you access to thousands of third-party detection rules. The library currently contains detection rules written by [Anvilogic](https://github.com/anvilogic-forge/armory/blob/main/detections/cloud/aws/aws_disableawsserviceaccess/aws_disableawsserviceaccess-splunk-awscloudtrail.yml), [Sigma](https://github.com/SigmaHQ/sigma/blob/master/rules/network/zeek/zeek_http_susp_file_ext_from_susp_tld.yml), [Panther](https://github.com/panther-labs/panther-analysis/blob/develop/rules/gsuite_activityevent_rules/google_workspace_many_docs_downloaded.yml), and [Okta](https://github.com/okta/customer-detections). +The Community Rules search page opens and gives access to thousands of third-party detection rules. The library currently contains detection rules written by [Anvilogic](https://github.com/anvilogic-forge/armory/blob/main/detections/cloud/aws/aws_disableawsserviceaccess/aws_disableawsserviceaccess-splunk-awscloudtrail.yml), [Sigma](https://github.com/SigmaHQ/sigma/blob/master/rules/network/zeek/zeek_http_susp_file_ext_from_susp_tld.yml), [Panther](https://github.com/panther-labs/panther-analysis/blob/develop/rules/gsuite_activityevent_rules/google_workspace_many_docs_downloaded.yml), and [Okta](https://github.com/okta/customer-detections). -> Rules are searchable by CVE number, keyword, or pre-defined descriptors (Tags). Searchable tags include attack techniques, MITRE ATT&CK id codes and other key rule identificators. +> You can search for rules by CVE number, keyword, or pre-defined descriptors (Tags). Searchable tags include attack techniques, MITRE ATT&CK id codes, and other key rule identifiers. ![Community Rules Search Interface](../../assets/images/image(337).png) ## Loading a Community Rule -Once you find the rule you want to use, import it to the organization by clicking "Load Rule", and our AI engine will create it using verified LimaCharlie syntax. +When you find the rule that you want to use, click "Load Rule" to import it into the organization. The AI engine creates the rule with verified LimaCharlie syntax. -> This process may take a few seconds so please be patient. +> This process can take a few seconds. -Once the rule is ready, it will return you to the Add Rule page in LimaCharlie. The Detect and Response sections of the rule will be filled out with LimaCharlie logic that includes explanatory comments. From here you can manage this rule just as you would any other D&R rule. +When the rule is ready, LimaCharlie returns you to the Add Rule page. The Detect and Response sections of the rule contain LimaCharlie logic with explanatory comments. You can then manage this rule as you manage any other D&R rule. ## Digging Deeper -As these rules are the property of third parties you may be interested in knowing more about their licensing or source code. This information is accessible through the Community Rules search page. To see these details click on a rule. +These rules are the property of third parties. The Community Rules search page gives more information about their licensing and source code. To see these details, click a rule. -The example below shows what appears when you click Anvilogic's Potential CVE-2021-44228 - Log4Shell rule +The example below shows the result when you click the Anvilogic Potential CVE-2021-44228 - Log4Shell rule. -Under the rule name you will see the options to load the rule, check its source code, and read additional licensing information. There is also a reference section at the bottom left corner of the window providing links related to the rule. +Below the rule name are the options to load the rule, check its source code, and read more licensing information. A reference section in the bottom left corner of the window gives links that relate to the rule. ![Rule Details Example](https://lh7-rt.googleusercontent.com/docsz/AD_4nXf3SZQZu4j4kEp2Y0wpnoeHA0t_XaR5VqaoB9SupPHl0t91e-12QhMj0epDi742peW0gpu8e44HhJ4lDN1esspiMRUfpFr3W2aNiQcIeff2HhNCxmgp1h3oLqphpqJ8AohoDDxFdA?key=7BgiNipN3DxRQXGQyEk06w) diff --git a/docs/3-detection-response/managed-rulesets/sigma-converter.md b/docs/3-detection-response/managed-rulesets/sigma-converter.md index ab76c4ebb..171a28fa4 100644 --- a/docs/3-detection-response/managed-rulesets/sigma-converter.md +++ b/docs/3-detection-response/managed-rulesets/sigma-converter.md @@ -1,14 +1,14 @@ # Sigma Converter -LimaCharlie is happy to contribute to the [Sigma Project](https://github.com/SigmaHQ/sigma) by maintaining the LimaCharlie Backend for Sigma, enabling most Sigma rules to be converted to the [Detection & Response rule](../examples.md) format. +LimaCharlie contributes to the [Sigma Project](https://github.com/SigmaHQ/sigma) and maintains the LimaCharlie Backend for Sigma. The backend converts most Sigma rules to the [Detection & Response rule](../examples.md) format. -A LimaCharlie Service is available to apply [many of those converted rules](https://github.com/refractionPOINT/sigma-limacharlie/tree/rules) with a single click to an Organization. +A LimaCharlie Service applies [many of those converted rules](https://github.com/refractionPOINT/sigma-limacharlie/tree/rules) to an Organization with one click. -For cases where you either have your own Sigma rules, or you would like to convert/apply specific rules yourself, the Sigma Converter service described below can help streamline the process. +If you have your own Sigma rules, or if you want to convert and apply specific rules yourself, use the Sigma Converter service that is described below. ## Converter Service -The Converter service converts one or many Sigma rules into the LimaCharlie rule format. It can accomplish this via the following HTTPS endpoints available at : +The Converter service converts one or more Sigma rules into the LimaCharlie rule format. It uses the HTTPS endpoints below, which are available at : ### Single Rule @@ -16,7 +16,7 @@ Endpoint: `https://sigma.limacharlie.io/convert/rule` Verb: `POST` Form Parameters: -- `rule`: the content of a literal Sigma rule to be converted. +- `rule`: the content of a literal Sigma rule to convert. - `target`: optional [target](../alternate-targets.md) within LimaCharlie, one of `edr` (default) or `artifact`. Output Example: @@ -38,7 +38,7 @@ Endpoint: `https://sigma.limacharlie.io/convert/repo` Verb: `POST` Form Parameters: -- `repo`: the source where to access the rules to convert, one of: +- `repo`: the source of the rules to convert, one of: - An HTTPS link to a direct resource like: `https://corp.com/my-rules.yaml` - A GitHub link to a file or repo like: diff --git a/docs/3-detection-response/managed-rulesets/soc-prime.md b/docs/3-detection-response/managed-rulesets/soc-prime.md index 8c92a8a5c..77a86a640 100644 --- a/docs/3-detection-response/managed-rulesets/soc-prime.md +++ b/docs/3-detection-response/managed-rulesets/soc-prime.md @@ -1,23 +1,26 @@ # SOC Prime Rules -To use SOC Prime rules in LimaCharlie, start by configuring lists in [SOC Prime](https://socprime.com/). See [SOC Prime's continuous content management guide](https://socprime.com/blog/enable-continuous-content-management-with-the-soc-prime-platform/) for instructions. +To use SOC Prime rules in LimaCharlie, first configure lists in [SOC Prime](https://socprime.com/). For instructions, see [SOC Prime's continuous content management guide](https://socprime.com/blog/enable-continuous-content-management-with-the-soc-prime-platform/). -After the lists have been configured, you can finish the configuration in LimaCharlie. Note that currently the SOC Prime API is not available for free users. It is available only for paid users or if they requested a trial. +After you configure the lists, complete the configuration in LimaCharlie. The SOC Prime API is not available to free users. It is available only to paid users, or to users that requested a trial. -First, enable the `socprime` add-on on the LimaCharlie marketplace. +1. Enable the `socprime` add-on on the LimaCharlie marketplace. -![image.png](../../assets/images/image(55).png) + ![image.png](../../assets/images/image(55).png) -Then, navigate to the Integrations page in your Organization, enter the SOC Prime Key & click `Update`. +2. In your Organization, open the Integrations page. +3. Enter the SOC Prime Key. +4. Click `Update`. -![image.png](../../assets/images/image(56).png) + ![image.png](../../assets/images/image(56).png) -When the Key is saved, you will get the ability to select the SOC Prime content lists you want to have populated in LimaCharlie as detection & response rules. After selecting the lists & clicking `Update`, you are all set to start receiving detections based on the SOC Prime lists. +5. Select the SOC Prime content lists that you want in LimaCharlie as D&R rules. +6. Click `Update`. LimaCharlie starts to send detections that are based on the SOC Prime lists. -![image.png](../../assets/images/image(57).png) + ![image.png](../../assets/images/image(57).png) -A detection that comes from the SOC Prime Lists, will have `socprime` listed as a detection author. +A detection that comes from the SOC Prime lists shows `socprime` as the detection author. ![image.png](../../assets/images/image(58).png) -Note that adding a new rule to a SOC Prime content list that is enabled in LC will see the new rule be applied during next sync (LimaCharlie syncs the SOC Prime rules every 3 hours). +If you add a new rule to a SOC Prime content list that is enabled in LC, LimaCharlie applies the new rule at the next sync. LimaCharlie syncs the SOC Prime rules every 3 hours. diff --git a/docs/3-detection-response/managed-rulesets/soteria/aws.md b/docs/3-detection-response/managed-rulesets/soteria/aws.md index 04113213c..d401deda6 100644 --- a/docs/3-detection-response/managed-rulesets/soteria/aws.md +++ b/docs/3-detection-response/managed-rulesets/soteria/aws.md @@ -1,33 +1,33 @@ # Soteria AWS Rules -Soteria's AWS ruleset provides coverage across multiple AWS telemetry streams, including: +The Soteria AWS ruleset covers many AWS telemetry streams. These include: - [AWS CloudTrail](https://aws.amazon.com/cloudtrail/) - [AWS GuardDuty](https://aws.amazon.com/guardduty/) ## Data Access -Please note that Soteria won't get access to your data, and you won't be able to see or edit their rules - LimaCharlie acts as a broker between the two parties. +Soteria does not get access to your data, and you cannot see or edit the Soteria rules. LimaCharlie is the broker between the two parties. -To leverage detection logic provided by the ruleset: +To use the detection logic of the ruleset: -1. Subscribe your tenant to the Soteria AWS [ruleset extension](https://app.limacharlie.io/add-ons/extension-detail/soteria-rules-aws). -2. Subscribe your tenant to [tor](../../../5-integrations/extensions/limacharlie/lookup-manager.md) lookup (provided at no cost). -3. Configure [AWS CloudTrail](../../../2-sensors-deployment/adapters/types/aws-cloudtrail.md) and [AWS GuardDuty](../../../2-sensors-deployment/adapters/types/aws-guardduty.md) adapters to start collecting AWS audit logs. +1. Subscribe your organization to the Soteria AWS [ruleset extension](https://app.limacharlie.io/add-ons/extension-detail/soteria-rules-aws). +2. Subscribe your organization to the [tor](../../../5-integrations/extensions/limacharlie/lookup-manager.md) lookup, which has no cost. +3. Configure the [AWS CloudTrail](../../../2-sensors-deployment/adapters/types/aws-cloudtrail.md) and [AWS GuardDuty](../../../2-sensors-deployment/adapters/types/aws-guardduty.md) adapters to collect AWS audit logs. ## Enabling Soteria's AWS Rules -Soteria's AWS rules can be activated via two means. +You can activate the Soteria AWS rules in two ways. ### Activating via the Web UI -To enable Soteria's AWS ruleset, navigate to the **Extensions** section of the **Add-On Marketplace** and search for Soteria. You can also directly select `soteria-rules-aws`. +To enable the Soteria AWS ruleset, open the **Extensions** section of the **Add-On Marketplace**. Search for Soteria. You can also select `soteria-rules-aws` directly. ![soteria aws 1](../../../assets/images/soteria-aws-1.png) #### Please note: Pricing may reflect when the screenshot was taken, not the actual pricing -Under the Organization dropdown, select a tenant (organization) you want to subscribe to **soteria-rules-aws** and click **Subscribe**. +Under the Organization dropdown, select the organization that you want to subscribe to **soteria-rules-aws**. Click **Subscribe**. ![soteria aws 2](../../../assets/images/soteria-aws-2.png) @@ -37,6 +37,6 @@ You can also manage add-ons from the **Subscriptions** menu under **Billing**. ### Infrastructure as Code -Alternatively, to manage tenants and LimaCharlie functionality at scale, you can leverage our Infrastructure as Code functionality. +To manage organizations and LimaCharlie functions at scale, you can also use the Infrastructure as Code functionality. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, which gives you full control of security operations. This structure supports multi-tenant setups for managed security providers, or for enterprises that manage many departments or clients. diff --git a/docs/3-detection-response/managed-rulesets/soteria/edr.md b/docs/3-detection-response/managed-rulesets/soteria/edr.md index 2b61980ff..d95f36d5b 100644 --- a/docs/3-detection-response/managed-rulesets/soteria/edr.md +++ b/docs/3-detection-response/managed-rulesets/soteria/edr.md @@ -1,6 +1,6 @@ # Soteria EDR Rules -Soteria's EDR ruleset provides coverage across Windows, Linux, and macOS. You can check the dynamic MITRE ATT&CK mapping here: +The Soteria EDR ruleset covers Windows, Linux, and macOS. The dynamic MITRE ATT&CK mapping is available at these links: - [All rules](https://mitre-attack.github.io/attack-navigator/#layerURL=https%3A%2F%2Fstorage.googleapis.com%2Fsoteria-detector-mapping%2F%2Fall.json) - [Windows](https://mitre-attack.github.io/attack-navigator/#layerURL=https://storage.googleapis.com/soteria-detector-mapping//windows.json) @@ -9,9 +9,9 @@ Soteria's EDR ruleset provides coverage across Windows, Linux, and macOS. You ca ## Data access -Please note that Soteria won't get access to your data, and you won't be able to see or edit their rules - LimaCharlie acts as a broker between the two parties. +Soteria does not get access to your data, and you cannot see or edit the Soteria rules. LimaCharlie is the broker between the two parties. -The following events are utilized by Soteria rules. Please ensure that they are configured within your Organization: +The Soteria rules use the events below. Make sure that these events are configured in your Organization: - `CODE_IDENTITY` - `DNS_REQUEST` @@ -28,21 +28,21 @@ The following events are utilized by Soteria rules. Please ensure that they are - `SENSITIVE_PROCESS_ACCESS` - `THREAD_INJECTION` -This can also be done in the Add-ons Marketplace. +You can also do this in the Add-ons Marketplace. ## Enabling Soteria's EDR Rules -Soteria's EDR rules can be activated via two means. +You can activate the Soteria EDR rules in two ways. ### Activating via the Web UI -To enable Soteria's EDR ruleset, navigate to the **Extensions** section of the Add-On Marketplace and search for Soteria. You can also directly select `soteria-rules-edr`. +To enable the Soteria EDR ruleset, open the **Extensions** section of the Add-On Marketplace. Search for Soteria. You can also select `soteria-rules-edr` directly. ![soteria edr 1](../../../assets/images/soteria-edr-1.png) #### Please note: Pricing may reflect when the screenshot was taken, not the actual pricing -Under the Organization dropdown, select a tenant (organization) you want to subscribe to Soteria rules and click **Subscribe**. +Under the Organization dropdown, select the organization that you want to subscribe to the Soteria rules. Click **Subscribe**. ![soteria edr 2](../../../assets/images/soteria-edr-2.png) @@ -52,4 +52,4 @@ You can also manage add-ons from the **Subscriptions** menu under **Billing**. ### Infrastructure as Code -Alternatively, to manage tenants and LimaCharlie functionality at scale, you can leverage our Infrastructure as Code functionality. +To manage organizations and LimaCharlie functions at scale, you can also use the Infrastructure as Code functionality. diff --git a/docs/3-detection-response/managed-rulesets/soteria/m365.md b/docs/3-detection-response/managed-rulesets/soteria/m365.md index 02ffd3035..7c966c6ff 100644 --- a/docs/3-detection-response/managed-rulesets/soteria/m365.md +++ b/docs/3-detection-response/managed-rulesets/soteria/m365.md @@ -1,6 +1,6 @@ # Soteria M365 Rules -Soteria's O365 ruleset provides coverage across O365 (aka M365) telemetry streams. The ruleset is designed for in-depth analysis of the Office 365 ecosystem which includes: +The Soteria O365 ruleset gives coverage of O365 (also known as M365) telemetry streams. The ruleset analyzes the Office 365 ecosystem in depth. The ecosystem includes: - Teams - Word @@ -12,42 +12,42 @@ Soteria's O365 ruleset provides coverage across O365 (aka M365) telemetry stream Data access -Please note that Soteria won't get access to your data, and you won't be able to see or edit their rules - LimaCharlie acts as a broker between the two parties. +Soteria does not get access to your data, and you cannot see or edit the Soteria rules. LimaCharlie is the broker between the two parties. -To leverage detection logic provided by the ruleset: +To use the detection logic in the ruleset: -1. Subscribe your tenant to the [Soteria Office 365 ruleset extension](https://app.limacharlie.io/add-ons/extension-detail/soteria-rules-o365) -2. Subscribe your tenant to [tor](https://app.limacharlie.io/add-ons/detail/tor-ips) lookup (provided at no cost). -3. Configure Office 365 Sensor to start collecting [Office 365 audit logs](../../../2-sensors-deployment/adapters/types/microsoft-365.md). +1. Subscribe your organization to the [Soteria Office 365 ruleset extension](https://app.limacharlie.io/add-ons/extension-detail/soteria-rules-o365). +2. Subscribe your organization to the [tor](https://app.limacharlie.io/add-ons/detail/tor-ips) lookup. This lookup has no cost. +3. Configure the Office 365 Sensor to collect [Office 365 audit logs](../../../2-sensors-deployment/adapters/types/microsoft-365.md). ## Enabling Soteria's O365 Rules -Soteria's O365 rules can be activated via two means. +You can enable the Soteria O365 rules in two ways. ### Activating via the Web UI -To enable Soteria's O365 ruleset, navigate to the Extensions section of the Add-On Marketplace and search for Soteria. You can also directly select `soteria-rules-o365`. +To enable the Soteria O365 ruleset, go to the Extensions section of the Add-On Marketplace and search for Soteria. You can also select `soteria-rules-o365` directly. ![soteria o365 1](../../../assets/images/soteria-o365-1.png) #### Please note: Pricing may reflect when the screenshot was taken, not the actual pricing -Under the Organization dropdown, select a tenant (organization) you want to subscribe to Soteria O365 rules and click **Subscribe**. +In the Organization dropdown, select the organization that you want to subscribe to the Soteria O365 rules. Click **Subscribe**. ![soteria o365 2](../../../assets/images/soteria-o365-2.png) -You can also manage add-ons from the **Subscriptions** menu under **Billing**. +You can also manage add-ons in the **Subscriptions** menu under **Billing**. ![soteria o365 3](../../../assets/images/soteria-o365-3.png) ### Infrastructure as Code -Alternatively, to manage tenants and LimaCharlie functionality at scale, you can leverage our Infrastructure as Code functionality. +To manage organizations and LimaCharlie features at scale, you can use the Infrastructure as Code functionality instead. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Sensors send telemetry to the cloud as EDR telemetry or as forwarded logs, in the same way as agents. A sensor is a scalable and serverless way to connect the endpoints of an organization to the cloud securely. -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. An extension can integrate a third-party tool, automate a workflow, or add a new capability. An organization subscribes to an extension, and the extension gets specific permissions to use the infrastructure of that organization. An extension can be private for tailored use, or public to share with the community. This framework supports scale, flexibility, and secure and repeatable deployments. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives you full control of security operations. This structure supports flexible multi-tenant setups for managed security providers, and for enterprises that manage many departments or clients. -Infrastructure as Code (IaC) automates the management and provisioning of IT infrastructure using code, making it easier to scale, maintain, and deploy resources consistently. In LimaCharlie, IaC allows security teams to deploy and manage sensors, rules, and other security infrastructure programmatically, ensuring streamlined, repeatable configurations and faster response times, while maintaining infrastructure-as-code best practices in cybersecurity operations. +Infrastructure as Code (IaC) uses code to automate the management and provisioning of IT infrastructure. Code makes it easier to scale, maintain, and deploy resources consistently. In LimaCharlie, IaC lets security teams deploy and manage sensors, rules, and other security infrastructure programmatically. The result is repeatable configurations and faster response times, with the best practices of infrastructure as code in cybersecurity operations. diff --git a/docs/3-detection-response/sensor-variables.md b/docs/3-detection-response/sensor-variables.md index a78e5a957..7c8103b0a 100644 --- a/docs/3-detection-response/sensor-variables.md +++ b/docs/3-detection-response/sensor-variables.md @@ -2,14 +2,14 @@ ## Overview -Sensor variables are per-sensor key-value stores that allow D&R rules to share state across different rules evaluating events from the same sensor. A response action in one rule can set a variable, and a detection operator in another rule can read it — enabling patterns like conditional suppression, cross-rule coordination, and dynamic thresholds. +Sensor variables are key-value stores for each sensor. They let D&R rules share state between rules that evaluate events from the same sensor. A response action in one rule can set a variable, and a detection operator in another rule can read it. This supports patterns such as conditional suppression, coordination between rules, and dynamic thresholds. Variables are: - **Scoped per sensor** — each sensor (SID) has its own independent set of variables. -- **Stored in memory** during the sensor's connection for fast, synchronous access during rule evaluation. -- **Persisted across reconnections** — when a sensor disconnects, its variables are saved and restored when it reconnects. -- **Optionally time-limited** — variables can have a TTL (time-to-live) in seconds, after which they expire automatically. +- **Stored in memory** while the sensor is connected. This gives fast, synchronous access during rule evaluation. +- **Persisted across reconnections** — when a sensor disconnects, the cloud saves its variables and restores them when the sensor reconnects. +- **Optionally time-limited** — a variable can have a TTL (time-to-live) in seconds. The variable then expires automatically. ## Setting Variables (Response Actions) @@ -27,38 +27,38 @@ Use the `add var` response action to set a variable, and `del var` to remove one | Parameter | Required | Description | |-----------|----------|-------------| | `name` | Yes | Name of the variable to set. | -| `value` | Yes | Value to store. Can be a literal string or a [lookback](#using-lookbacks) like `<>`. | -| `ttl` | No | Time-to-live in seconds. The variable expires after this duration. If omitted, the variable persists indefinitely (until explicitly deleted or the sensor state is flushed). | +| `value` | Yes | Value to store. Can be a literal string or a [lookback](#using-lookbacks) such as `<>`. | +| `ttl` | No | Time-to-live in seconds. The variable expires after this time. If you do not set it, the variable persists indefinitely, until you delete it or the cloud flushes the sensor state. | -A single variable name can hold **multiple values**. Each call to `add var` adds a value to the set. For example, calling `add var` with `name: seen-paths` and `value: <>` across multiple events builds up a set of file paths. +A single variable name can hold **multiple values**. Each call to `add var` adds a value to the set. For example, `add var` with `name: seen-paths` and `value: <>` collects a set of file paths across many events. #### TTL Behavior -The `ttl` is **per value**, not per variable. Each value carries its own absolute expiration time, computed at insert time as `now + ttl`. +The `ttl` applies **to each value**, not to the variable. Each value has its own absolute expiration time. The cloud computes this time at insert as `now + ttl`. -- **Adding new values to the same variable:** each value gets its own independent TTL timer. Values added at different times expire at different times. -- **Re-adding a value that already exists in the set:** the TTL is **reset** (the new expiration overwrites the old one). This is useful for keeping a value "alive" as long as related activity continues — re-issue `add var` with the same value on every relevant event and it will only expire after `ttl` seconds of silence. -- **Mixing TTLs:** within a single variable, some values can be short-lived and others long-lived; they are tracked independently. -- **Omitting `ttl`:** the value persists indefinitely. Combined with the limits below, indefinite values can fill the variable up — prefer a TTL whenever the data is naturally bounded in time. +- **New values in the same variable:** each value gets its own independent TTL timer. Values that you add at different times expire at different times. +- **A value that is already in the set:** the TTL is **reset**, and the new expiration replaces the old one. Use this to keep a value while related activity continues. Send `add var` with the same value on each relevant event. The value then expires only after `ttl` seconds without activity. +- **Different TTLs:** in one variable, some values can be short-lived and others long-lived. The cloud tracks each value independently. +- **No `ttl`:** the value persists indefinitely. With the limits below, indefinite values can fill the variable. Set a TTL when the data is bounded in time. #### Limits and Overrun Behavior A sensor can hold up to **16 variable names**, and each variable name can hold up to **32 values**. -These limits exist to keep per-sensor state bounded. **Exceeding either limit is destructive — it does not evict the oldest entry to make room.** Specifically: +These limits keep the state of each sensor bounded. **If you go above either limit, the effect is destructive. The cloud does not remove the oldest entry to make room.** The effects are: | Limit exceeded | Effect | |----------------|--------| -| The 33rd unique value is added to a single variable | The **entire variable** (all of its values) is cleared, and `add var` returns an error. The new value is also lost. | -| The 17th distinct variable name is added to a sensor | **All variables** for that sensor are cleared, and `add var` returns an error. | +| The 33rd unique value is added to a single variable | The cloud clears the **entire variable** and all of its values, and `add var` returns an error. The new value is also lost. | +| The 17th distinct variable name is added to a sensor | The cloud clears **all variables** for that sensor, and `add var` returns an error. | -Because of this, you should design rule sets so the limits are not approached in normal operation: +Therefore, design your rule sets so that normal operation stays below the limits: -- Always set a `ttl` unless you are certain the value set is naturally bounded. -- If you are using `<>` lookbacks to populate a variable from a high-cardinality field (file paths, command lines, IPs), use a short TTL so the set self-prunes. -- Do not split unrelated state across many small variables on the same sensor; combine related state where possible. +- Always set a `ttl`, unless you are sure that the set of values is bounded. +- Use a short TTL when an `<>` lookback fills a variable from a field with high cardinality. Examples are file paths, command lines, and IP addresses. The set then prunes itself. +- Do not split unrelated state into many small variables on the same sensor. Combine related state when possible. -Re-adding a value that is already present is **not** counted against the value limit (it just refreshes the existing entry's TTL), so refreshing a small fixed set of values with `add var` is safe. +A value that is already present does **not** count against the value limit. It only refreshes the TTL of the existing entry. Therefore, it is safe to refresh a small fixed set of values with `add var`. ### del var @@ -71,11 +71,11 @@ Re-adding a value that is already present is **not** counted against the value l | Parameter | Required | Description | |-----------|----------|-------------| | `name` | Yes | Name of the variable. | -| `value` | Yes | Specific value to remove from the variable's set. Can be a literal or a lookback. An empty string (`value: ""`) removes **all** values for the variable — see below. | +| `value` | Yes | The value to remove from the set of the variable. Can be a literal or a lookback. An empty string (`value: ""`) removes **all** values of the variable, as described in the next section. | #### Removing All Values for a Variable -To clear an entire variable (for example, when you've forgotten what's in it, or want to reset state), set `value` to an empty string: +You can clear an entire variable when you do not know its contents, or when you want to reset the state. To do this, set `value` to an empty string: ```yaml - action: del var @@ -83,13 +83,13 @@ To clear an entire variable (for example, when you've forgotten what's in it, or value: "" ``` -This removes every value associated with `my-variable` for the sensor in a single action. It is the only way to clear a variable without enumerating its current values, since there is no API to list a sensor's variables (see [Visibility](#visibility) below). +This removes every value of `my-variable` for the sensor in one action. There is no API to list the variables of a sensor, as described in [Visibility](#visibility). Therefore, this is the only way to clear a variable without a list of its current values. -Alternatively, use a short `ttl` on `add var` so values expire naturally without explicit deletion. +You can also use a short `ttl` on `add var`. The values then expire without an explicit deletion. ### Using Lookbacks -The `value` parameter supports lookback syntax (`<>`) to extract values from the current event: +The `value` parameter supports the lookback syntax (`<>`) to extract values from the current event: ```yaml - action: add var @@ -98,13 +98,13 @@ The `value` parameter supports lookback syntax (`<>`) to extract values fr ttl: 300 ``` -This stores the actual file path from the event that triggered the rule. +This stores the file path from the event that triggered the rule. ## Reading Variables (Detection Operators) -To reference a sensor variable in a detection rule, use the `[[variable_name]]` syntax in the `value` parameter of an operator. +To use a sensor variable in a detection rule, put the `[[variable_name]]` syntax in the `value` parameter of an operator. -When the engine evaluates the operator, `[[variable_name]]` is replaced with the **set of values** currently stored in that variable for the sensor. The operator then checks if the value at `path` matches **any** of those values. +When the engine evaluates the operator, it replaces `[[variable_name]]` with the **set of values** in that variable for the sensor. The operator then checks if the value at `path` matches **any** of those values. ### Supported Operators @@ -119,7 +119,7 @@ The `[[variable_name]]` syntax works with these operators: ### Basic Example -**Rule 1** — When a process accesses a sensitive file, remember the file path: +**Rule 1** — When a process accesses a sensitive file, store the file path: ```yaml # Detect @@ -153,21 +153,21 @@ value: '[[sensitive-files-accessed]]' name: Network Activity After Sensitive File Access ``` -When Rule 2 evaluates, `[[sensitive-files-accessed]]` resolves to the set of file paths stored by Rule 1. If the current event's `FILE_PATH` matches any of them, the rule fires. +When Rule 2 evaluates, `[[sensitive-files-accessed]]` resolves to the set of file paths that Rule 1 stored. If the `FILE_PATH` of the current event matches one of them, the rule fires. ### Empty Variables -If a variable has no values (it was never set, has expired, or was deleted), the `[[variable_name]]` resolves to an **empty set**. Since no value can match an empty set, the operator returns `false`. +A variable can have no values because you never set it, because it expired, or because you deleted it. In that condition, `[[variable_name]]` resolves to an **empty set**. No value can match an empty set, so the operator returns `false`. -This is useful with `not: true` — if the variable is empty, the operator returns `false`, `not` flips it to `true`, and the rule proceeds. If the variable has a matching value, the operator returns `true`, `not` flips it to `false`, and the rule is suppressed. +This is useful with `not: true`. If the variable is empty, the operator returns `false`, `not` changes it to `true`, and the rule continues. If the variable has a value that matches, the operator returns `true`, `not` changes it to `false`, and the rule is suppressed. ## Common Patterns ### Conditional Suppression: "Detect A Unless B Happened Recently" -This is the most common use case for sensor variables. You want to detect an event, but suppress the detection if a related event occurred recently. +This is the most common use of sensor variables. You detect an event, but you suppress the detection if a related event occurred recently. -**Example:** Detect Windows Defender real-time protection being disabled (EID 5001), but not if a managed policy change (EID 5007) occurred recently — which indicates an expected, managed change. +**Example:** Detect that Windows Defender real-time protection is disabled (EID 5001). Do not report the detection if a managed policy change (EID 5007) occurred recently, because that change is expected and managed. **Rule 1 — Flag the managed change:** @@ -232,14 +232,14 @@ rules: | No recent 5007 | empty set | no match → false | true | Detection fires | | After TTL expires | empty set | no match → false | true | Detection fires | -The key is storing the **value you expect to find at `path`** (the EventID `"5001"`) as the variable value, so the `is` comparison is meaningful. +Store the **value that you expect to find at `path`** (the EventID `"5001"`) as the value of the variable. The `is` comparison is then meaningful. !!! note "Ordering matters" - This pattern only suppresses when Rule 1's event (the 5007) is processed **before** Rule 2's event (the 5001). If they can arrive in either order, consider setting the TTL long enough and using the variable in both directions. + This pattern suppresses the detection only if the cloud processes the event of Rule 1 (the 5007) **before** the event of Rule 2 (the 5001). If the two events can arrive in either order, set a TTL that is long enough and use the variable in both directions. ### Dynamic Allowlisting -Build up a set of known-good values and suppress detections for them: +Collect a set of known-good values and suppress the detections for them: **Rule 1 — Learn approved applications during business hours:** @@ -285,7 +285,7 @@ rules: ### Variables Are Not Tags -Unlike [tags](../8-reference/response-actions.md#add-tag-remove-tag), which are visible in the sensor's metadata and can be used for organizational purposes, sensor variables are internal to the D&R engine and invisible outside of rule evaluation. +[Tags](../8-reference/response-actions.md#add-tag-remove-tag) are visible in the metadata of the sensor, and you can use them to organize sensors. Sensor variables are different. They are internal to the D&R engine, and they are not visible outside rule evaluation. | Feature | Tags | Variables | |---------|------|-----------| @@ -297,24 +297,24 @@ Unlike [tags](../8-reference/response-actions.md#add-tag-remove-tag), which are ### Synchronous Evaluation -Because sensor variables are stored in memory on the analytics node processing the sensor's events, they are read and written **synchronously** during rule evaluation. This means: +The analytics node that processes the events of the sensor keeps the sensor variables in memory. Therefore, the engine reads and writes them **synchronously** during rule evaluation. This means: -- A variable set by one rule's response is immediately visible to subsequent rules evaluating events from the same sensor. -- There is no propagation delay (unlike tags, which are asynchronous). +- A variable that the response of one rule sets is immediately visible to the later rules that evaluate events from the same sensor. +- There is no delay in propagation. Tags are different, because they are asynchronous. ### State Persistence -Variables are persisted when a sensor disconnects and restored when it reconnects. The TTL continues to count down during the disconnection — if a variable's TTL expires while the sensor is offline, it will not be restored. +The cloud saves the variables when a sensor disconnects and restores them when the sensor reconnects. The TTL continues to count down during the disconnection. If the TTL of a variable expires while the sensor is offline, the cloud does not restore that variable. ### Visibility Sensor variables are internal to the D&R engine and **not** exposed through any read API: -- They do not appear in sensor info, the sensor's metadata, or audit events. -- There is no way to enumerate the variables currently held for a sensor. -- A specific variable's set can only be observed indirectly — by writing a rule that reads `[[variable_name]]` and reports the matching values. +- They do not appear in sensor info, in the metadata of the sensor, or in audit events. +- There is no way to list the variables that a sensor holds. +- You can see the set of one variable only indirectly. Write a rule that reads `[[variable_name]]` and reports the values that match. -Because variables cannot be inspected externally, treat them as ephemeral, rule-internal state. If you need a piece of state that is observable, queryable, or shared with operators, use [tags](../8-reference/response-actions.md#add-tag-remove-tag) instead — they are slower (asynchronous) but visible in the sensor's metadata. Combined with the destructive overrun behavior described above, this also means: always set a `ttl`, and keep variable contents bounded. +You cannot inspect variables from outside the engine, so treat them as temporary state inside the rules. Use [tags](../8-reference/response-actions.md#add-tag-remove-tag) instead if you need state that you can see, query, or share with operators. Tags are slower because they are asynchronous, but they are visible in the metadata of the sensor. Because of the destructive behavior above when you go above a limit, always set a `ttl` and keep the contents of each variable bounded. --- diff --git a/docs/3-detection-response/stateful-rules.md b/docs/3-detection-response/stateful-rules.md index 0d24af12d..7525448f9 100644 --- a/docs/3-detection-response/stateful-rules.md +++ b/docs/3-detection-response/stateful-rules.md @@ -2,24 +2,24 @@ ## Overview -> It's recommended to first read [Detection & Response rules](tutorials/writing-testing-rules.md) before diving into stateful rules. +> Read [Detection & Response rules](tutorials/writing-testing-rules.md) before you continue with stateful rules. -In LimaCharlie, a Stateful Rule tracks and remembers the state of past events to make decisions based on historical context. Unlike stateless rules, which evaluate events in isolation, stateful rules can detect patterns over time, such as multiple failed logins within an hour. This enables more complex and accurate detection, allowing users to trigger actions only when specific conditions are met across multiple events or timeframes. +In LimaCharlie, a Stateful Rule keeps the state of past events and makes decisions from that history. A stateless rule evaluates each event alone. A stateful rule detects patterns over time, such as many failed logins in one hour. This gives more complex and more accurate detection. Users can trigger actions only when specific conditions occur across many events or timeframes. -Events in LimaCharlie have well-defined relationships to one another using `routing/this`, `routing/parent`, `routing/target`, and can even be implicitly related by occurring in a similar timeframe. The relation context can be useful for writing more complex rules. +Events in LimaCharlie have defined relationships to each other through `routing/this`, `routing/parent`, and `routing/target`. Two events can also have an implicit relation when they occur in a similar timeframe. This relation context helps you write more complex rules. These are called "stateful" rules. ## Detecting Children / Descendants -To detect events in a tree you can use the following parameters: +To detect events in a tree, use these parameters: - `with child`: matches children of the initial event - `with descendant`: matches descendants (children, grandchildren, etc.) of the initial event -Aside from how deep they match, the `with child` and `with descendant` parameters operate identically: they declare a nested stateful rule. +The `with child` and `with descendant` parameters are the same, except for the depth that they match. Both declare a nested stateful rule. -For example, let's detect a `cmd.exe` process spawning a `calc.exe` process: +For example, this rule detects a `cmd.exe` process that spawns a `calc.exe` process: ```yaml # Detect initial event @@ -36,27 +36,27 @@ with child: # Wait for child matching this nested rule case sensitive: false ``` -Simply put, this will detect: +This detects: ```batch cmd.exe --> calc.exe ``` -Because it uses `with child` it will not detect: +Because it uses `with child`, it does not detect: ```batch cmd.exe --> firefox.exe --> calc.exe ``` -To do that, we could use `with descendant` instead. +To detect that chain, use `with descendant` instead. ## Detecting Proximal Events -To detect repetition of events close together on the same Sensor, we can use `with events`. +To detect repeated events close together on the same Sensor, use `with events`. -The `with events` parameter functions very similarly to `with child` and `with descendant`: it declares a nested stateful rule. +The `with events` parameter works like `with child` and `with descendant`. It declares a nested stateful rule. -For example, let's detect a scenario where `5` bad login attempts occur within `60` seconds. +For example, this rule detects `5` bad login attempts in `60` seconds. ```yaml event: WEL @@ -70,13 +70,13 @@ with events: within: 60 ``` -The top-level rule filters down meaningful events to `WEL` ones sent from Windows sensors using the `is windows` operator, and then it declares a stateful rule inside `with events`. It uses `count` and `within` to declare a suitable timespan to evaluate matching events. +The top-level rule uses the `is windows` operator to keep only the `WEL` events from Windows sensors. It then declares a stateful rule inside `with events`. The stateful rule uses `count` and `within` to set the timespan for the events that match. ## Stateful Rules -Stateful rules — the rules declared within `with child`, `with descendant` or `with events` — have full range. They can do anything a normal rule might do, including declaring nested stateful rules or using `and`/`or` operators to write more complex rules. +Stateful rules are the rules that you declare in `with child`, `with descendant`, or `with events`. They have full range and can do everything that a normal rule does. They can declare nested stateful rules, and they can use the `and` and `or` operators for more complex rules. -Here's a stateful rule that uses `and` to detect a specific combination of child events: +This stateful rule uses `and` to detect a specific combination of child events: ```yaml event: NEW_PROCESS @@ -99,7 +99,7 @@ with child: case sensitive: false ``` -The above example is looking for an `outlook.exe` process that spawns a `chrome.exe` process and drops a `.ps1` (powershell) file to disk. Like this: +The example above looks for an `outlook.exe` process that spawns a `chrome.exe` process and writes a `.ps1` (powershell) file to disk. Like this: ```text outlook.exe @@ -109,9 +109,9 @@ outlook.exe ### Counting Events -Rules declared using `with child` or `with descendant` also have the ability to use `count` and `within` to help scope the events it will statefully match. +Rules that you declare with `with child` or `with descendant` can also use `count` and `within`. These parameters set the scope of the events that the rule matches statefully. -For example, a rule that matches on Outlook writing 5 new `.ps1` documents within 60 seconds: +For example, this rule matches when Outlook writes 5 new `.ps1` documents in 60 seconds: ```yaml event: NEW_PROCESS @@ -131,9 +131,9 @@ with child: ### Choosing Event to Report -A reported detection will include a copy of the event that was detected. When writing detections that match multiple events, the default behavior will be to include a copy of the initial parent event. +A reported detection includes a copy of the event that the rule detected. When a detection matches many events, the default is a copy of the initial parent event. -In many cases it's more desirable to get the latest event in the chain instead. For this, there's a `report latest event: true` flag that can be set. Piggy-backing on the earlier example: +In many cases, the latest event in the chain is more useful. To get it, set the `report latest event: true` flag. This example extends the earlier one: ```yaml # Detection @@ -162,11 +162,11 @@ with child: name: Outlook Spawning Chrome & Powershell ``` -The event returned in the detection will be either the `chrome.exe` `NEW_PROCESS` event or the `.ps1` `NEW_DOCUMENT` event, whichever was last. Without `report latest event: true` being set, it would default to including the `outlook.exe` `NEW PROCESS` event. +The detection returns the `chrome.exe` `NEW_PROCESS` event or the `.ps1` `NEW_DOCUMENT` event, whichever came last. Without `report latest event: true`, the default is the `outlook.exe` `NEW PROCESS` event. ### Flipping back to stateless -Since all operators under the `with child` and `with descentant` are operating in stateful mode (meaning all the nodes don't have to match a single event, but can match over multiple events), sometimes you want a operator and the operators underneath to flip back to stateless mode where they must match a single event. You can achieve this by setting `is stateless: true` in the operator like: +All operators under `with child` and `with descentant` operate in stateful mode. In this mode, the nodes do not have to match one single event, but can match across many events. Sometimes you want an operator and the operators below it to return to stateless mode, where they must match a single event. To do this, set `is stateless: true` in the operator: ```yaml # Detection @@ -196,15 +196,15 @@ with child: ### Testing Stateful Rules -Stateful rules are forward-looking only and changing a rule will reset its state. +Stateful rules look forward only, and a change to a rule resets its state. -Practically speaking, this means that if you change a rule that detects `excel.exe -> cmd.exe`, `excel.exe` will need to be relaunched while the updated rule is running for it to then begin watching for `cmd.exe`. +For example, you change a rule that detects `excel.exe -> cmd.exe`. You must start `excel.exe` again while the new rule runs. The rule then starts to watch for `cmd.exe`. ### Using Events in Actions -Using `report` to report a detection works according to the [Choosing Event to Report](#choosing-event-to-report) section earlier. Other actions have a subtle difference: they will *always* observe the latest event in the chain. +The `report` action obeys the rules in [Choosing Event to Report](#choosing-event-to-report) above. Other actions are different: they *always* see the latest event in the chain. -Consider the `excel.exe -> cmd.exe` example. The `cmd.exe` event will be referenced inside the response action if using lookbacks (i.e. `<>`). If we wanted to end the `excel.exe` process (and its descendants), we would write a `task` that references the parent of the current event (`cmd.exe`): +Look at the `excel.exe -> cmd.exe` example again. A lookback in the response action (`<>`) refers to the `cmd.exe` event. To stop the `excel.exe` process and its descendants, write a `task` that refers to the parent of the current event (`cmd.exe`): ```yaml - action: task diff --git a/docs/3-detection-response/tutorials/dr-rule-building-guidebook.md b/docs/3-detection-response/tutorials/dr-rule-building-guidebook.md index aff87c69e..ea1480bb5 100644 --- a/docs/3-detection-response/tutorials/dr-rule-building-guidebook.md +++ b/docs/3-detection-response/tutorials/dr-rule-building-guidebook.md @@ -19,9 +19,9 @@ ## Introduction -LimaCharlie's Detection & Response (D&R) engine is a powerful, flexible system that enables real-time threat detection and automated response across multiple data sources. This guidebook provides comprehensive coverage of all D&R rule components, configuration options, and practical cybersecurity examples. +The LimaCharlie Detection & Response (D&R) engine finds threats in real time. It also runs automated responses across many data sources. This guidebook describes each D&R rule component, the configuration options, and cybersecurity examples. -The D&R engine processes rules against various target types, supports complex stateful detection patterns, and can trigger sophisticated response actions. Understanding each component and how they interact is crucial for building effective security automation. +The D&R engine runs rules against different target types. It supports stateful detection patterns, and it can start response actions. To build effective security automation, you must know each component and how the components interact. --- @@ -29,7 +29,7 @@ The D&R engine processes rules against various target types, supports complex st ### Basic Structure -Every D&R rule consists of a `detect` section and an optional `respond` section: +Every D&R rule has a `detect` section and an optional `respond` section: ```yaml detect: @@ -44,16 +44,16 @@ respond: ### Core Concepts -- **Path**: Slash-separated selectors to extract data from events (e.g., `event/FILE_PATH`, `routing/hostname`) +- **Path**: Slash-separated selectors that extract data from events (e.g., `event/FILE_PATH`, `routing/hostname`) - **Operators**: Logic operations for detection (`is`, `contains`, `matches`, etc.) - **Values**: Comparison targets (static values, lookbacks, or sensor variables) -- **Targets**: Data sources the rule processes (`edr`, `detection`, `artifact`, etc.) +- **Targets**: Data sources that the rule processes (`edr`, `detection`, `artifact`, etc.) --- ## Target Types -D&R rules can process eight different target types, each with unique characteristics and use cases. +D&R rules can process eight different target types. Each target type has its own characteristics and use cases. ### 1. EDR Target (Default) @@ -70,11 +70,11 @@ value: cmd.exe ### 2. Detection Target -**Purpose**: Process detections generated by other D&R rules (enables rule chaining). +**Purpose**: Process detections that other D&R rules generate. This lets you chain rules. **Data Source**: Detection objects from previous rules. **Use Cases**: Alert escalation, correlation, suppression. -In the `detection` target, the `event:` parameter refers to the `name` of the detection specified in the original rule's `report` action. +In the `detection` target, the `event:` parameter refers to the `name` of the detection. The original rule sets this name in its `report` action. ```yaml target: detection @@ -98,11 +98,11 @@ op: is windows ### 4. Artifact Target -**Purpose**: Process parsed artifacts collected via REST API or sensor commands. +**Purpose**: Process parsed artifacts that you collect with the REST API or with sensor commands. **Data Source**: Parsed log files, pcap data, and other collected artifacts. **Use Cases**: Log analysis, forensic investigation, compliance checking. -The artifact target supports a subset of operators and **only** supports the `report` response action. +The artifact target supports a subset of operators. It supports **only** the `report` response action. ```yaml target: artifact @@ -122,7 +122,7 @@ case sensitive: false ### 5. Artifact Event Target -**Purpose**: Process lifecycle events around artifacts. +**Purpose**: Process lifecycle events for artifacts. **Data Source**: Artifact ingestion and export completion events. **Event Types**: `ingest`, `export_complete` @@ -137,7 +137,7 @@ case sensitive: false ### 6. Schedule Target -**Purpose**: Process time-based triggered events at various intervals. +**Purpose**: Process events that a timer triggers at set intervals. **Frequencies**: Both `_per_org` and `_per_sensor` variants are available for each interval: `30m`, `1h`, `3h`, `6h`, `12h`, `24h`, `168h` (7 days). For example: `1h_per_org`, `1h_per_sensor`, `24h_per_org`, `24h_per_sensor`, etc. ```yaml @@ -150,7 +150,7 @@ path: event ### 7. Audit Target **Purpose**: Process platform audit logs. -**Data Source**: Tracks platform changes, tasking, replays, hive modifications, and other administrative actions. +**Data Source**: Tracks platform changes, tasking, replays, hive changes, and other administrative actions. ```yaml target: audit @@ -176,13 +176,13 @@ value: ext-strelka:bytes_scanned ## Detection Operators -The D&R engine supports a comprehensive set of detection operators organized into categories. +The D&R engine supports many detection operators. This section groups the operators into categories. ### String Operations #### `is` - Exact Matching -Performs exact value comparison for strings, integers, and booleans. +Compares strings, integers, and booleans for an exact match. ```yaml op: is @@ -191,11 +191,11 @@ value: "C:\\Windows\\System32\\calc.exe" case sensitive: false ``` -Supports the `file name` and `sub domain` transforms, lookbacks, and sensor variables. +This operator supports the `file name` and `sub domain` transforms, lookbacks, and sensor variables. #### `contains` - Substring Matching -Checks if a string contains a substring, with optional occurrence counting. +Checks if a string contains a substring. You can also set a minimum number of occurrences. ```yaml op: contains @@ -210,7 +210,7 @@ count: 2 - `case sensitive`: Boolean (default: true) - `count`: Minimum occurrences (default: 1) -Supports the `file name` and `sub domain` transforms. +This operator supports the `file name` and `sub domain` transforms. #### `starts with` / `ends with` - Prefix/Suffix Matching @@ -223,11 +223,11 @@ value: "C:\\Users\\" case sensitive: false ``` -Supports the `file name` and `sub domain` transforms. +This operator supports the `file name` and `sub domain` transforms. #### `matches` - Regular Expression -Pattern matching using regular expressions (Golang `regexp` syntax). +Matches a pattern with a regular expression (Golang `regexp` syntax). ```yaml op: matches @@ -236,11 +236,11 @@ re: .*\\system32\\.*\.scr case sensitive: false ``` -**Important**: The regex pattern is specified using the `re:` parameter, not `value:`. +**Important**: Give the regex pattern in the `re:` parameter, not in `value:`. -**Note**: The `matches` operator defaults to **case-insensitive** matching unless `case sensitive: true` is explicitly set. This is the opposite of other operators like `is` and `contains`, which default to case-sensitive. +**Note**: The `matches` operator is **case-insensitive** by default. To make it case-sensitive, set `case sensitive: true`. Other operators such as `is` and `contains` are case-sensitive by default. -Supports the `file name` and `sub domain` transforms. +This operator supports the `file name` and `sub domain` transforms. ### Logical Operations @@ -278,7 +278,7 @@ rules: #### `not` - Negation -Applied as a parameter on any operator to invert its result. +Use `not` as a parameter on any operator to invert the result of the operator. ```yaml op: is @@ -288,13 +288,13 @@ file name: true not: true ``` -When applied to `and`/`or`, it inverts the combined result. For example, `op: or` with `not: true` means "none of these conditions are true." +On `and` or `or`, `not` inverts the combined result. For example, `op: or` with `not: true` means "none of these conditions are true." ### Existence & Structure #### `exists` - Path Existence -Checks if a path exists in the event data. Optionally validates non-empty values with `truthy`. +Checks if a path exists in the event data. To also check that the value is not empty, use `truthy`. ```yaml op: exists @@ -302,11 +302,11 @@ path: event/PARENT truthy: true ``` -When `truthy: true` is set, `null` and empty string values are treated as non-existent. +If you set `truthy: true`, the operator treats `null` and empty string values as non-existent. #### `scope` - Scoped Evaluation -Resets the root of `event/` in paths to be a sub-path, allowing evaluation of individual elements in lists or dicts. +Resets the root of `event/` in paths to a sub-path. This lets the rule evaluate each element in a list or a dict. ```yaml op: scope @@ -328,7 +328,7 @@ rule: #### `is greater than` / `is lower than` - Numeric Comparison -Compares numeric values. Supports `length of` to compare string lengths instead. +Compares numeric values. To compare the length of a string instead, use `length of`. ```yaml op: is greater than @@ -339,7 +339,7 @@ length of: true #### `string distance` - Levenshtein Distance -Measures string similarity using edit distance. The `value` parameter can be a single string or a list of strings. +Measures how similar two strings are with an edit distance. The `value` parameter accepts one string or a list of strings. ```yaml op: string distance @@ -350,13 +350,13 @@ value: max: 2 ``` -Supports the `file name` and `sub domain` transforms. +This operator supports the `file name` and `sub domain` transforms. ### Platform Detection #### `is platform` - Platform Matching -Checks if the event originates from a sensor of the given platform. +Checks if the event comes from a sensor of the given platform. ```yaml op: is platform @@ -392,11 +392,11 @@ path: event/NETWORK_ACTIVITY/SOURCE/IP_ADDRESS cidr: 10.16.1.0/24 ``` -**Important**: The CIDR range is specified using the `cidr:` parameter, not `value:`. +**Important**: Give the CIDR range in the `cidr:` parameter, not in `value:`. #### `is public address` / `is private address` - IP Classification -Classifies IP addresses as public or private. Supports both IPv4 and IPv6. Specialized variants are also available: `is public ipv4 address`, `is public ipv6 address`, `is private ipv4 address`, `is private ipv6 address`. +Classifies IP addresses as public or private. Both IPv4 and IPv6 are supported. These more specific variants are also available: `is public ipv4 address`, `is public ipv6 address`, `is private ipv4 address`, `is private ipv6 address`. ```yaml op: is public address @@ -425,9 +425,9 @@ resource: hive://lookup/malwaredomains case sensitive: false ``` -Resources are of the form `hive://lookup/RESOURCE_NAME`. The organization must be subscribed to the lookup to use it. +Resources have the form `hive://lookup/RESOURCE_NAME`. The organization must subscribe to the lookup before a rule can use it. -Supports the `file name` and `sub domain` transforms. +This operator supports the `file name` and `sub domain` transforms. ### Transforms @@ -446,7 +446,7 @@ A path of `c:\windows\system32\svchost.exe` becomes `svchost.exe`. #### `sub domain` - Domain Component Extraction -Extracts specific components from a domain name using slice notation. +Extracts components from a domain name with slice notation. ```yaml op: is @@ -464,7 +464,7 @@ Slice notation examples: #### `is older than` - Age Comparison -Tests if a timestamp value is older than a specified number of seconds. +Tests if a timestamp value is older than a given number of seconds. ```yaml op: is older than @@ -472,7 +472,7 @@ path: routing/event_time seconds: 3600 ``` -**Important**: The age is specified in the `seconds:` parameter as an integer, not as a duration string. +**Important**: Give the age as an integer in the `seconds:` parameter, not as a duration string. --- @@ -482,7 +482,7 @@ seconds: 3600 #### `event` / `events` - Event Type Filter -Restricts the rule to specific event types for performance. Always specify event types when possible to reduce processing overhead. +Restricts the rule to specific event types, which improves performance. Always specify event types when possible to reduce processing overhead. ```yaml # Single event type @@ -496,7 +496,7 @@ events: ### Stateful Detection Parameters -Enable complex multi-event correlation: +These parameters correlate multiple events: #### `with child` - Immediate Children @@ -559,7 +559,7 @@ with events: #### Stateful Parameters -- `count`: Required number of matches (default: 1) +- `count`: Number of matches that the rule needs (default: 1) - `within`: Time window in seconds - `report latest event: true`: Report the final event in the chain instead of the initial event @@ -567,7 +567,7 @@ with events: #### `times` - Time Restrictions -Restricts rule execution to specific time periods. Uses numeric day-of-week (1-7, where 1 = Sunday and 7 = Saturday) and 24-hour time (0-2359). +Restricts the rule to specific time periods. Give the day of the week as a number (1-7, where 1 = Sunday and 7 = Saturday) and the time in 24-hour form (0-2359). ```yaml event: NEW_PROCESS @@ -588,11 +588,11 @@ times: tz: America/Los_Angeles ``` -The `tz` value should be a [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). +Set the `tz` value to a [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). #### `is stateless` - Disable Stateful Tracking -Within a stateful rule (`with child`, `with descendant`), forces an operator and its children to match a single event rather than across multiple events. +In a stateful rule (`with child`, `with descendant`), this parameter forces an operator and its children to match one event, not multiple events. ```yaml with child: @@ -651,17 +651,17 @@ path: event/FILE_PATH value: '[[known-good-processes]]' ``` -Variables are set using the `add var` response action and can hold multiple values. The operator checks if the value at `path` matches **any** value in the variable. +The `add var` response action sets a variable, and a variable can hold multiple values. The operator checks if the value at `path` matches **any** value in the variable. --- ## Response Actions -Response actions define what happens when a rule detects a match. Multiple actions can be chained together. +Response actions define what happens when a rule matches. You can chain multiple actions together. ### `report` - Generate Detection -Creates a detection (alert) that is sent to the detection output stream, the Detections page, and the D&R rule engine for chaining. +Creates a detection (alert). The cloud sends the detection to the detection output stream, the Detections page, and the D&R rule engine for chaining. ```yaml - action: report @@ -674,17 +674,17 @@ Creates a detection (alert) that is sent to the detection output stream, the Det **Parameters:** -- `name`: Detection name (supports template strings). Prefix with `__` to hide from Outputs but remain visible to chained rules. +- `name`: Detection name (supports template strings). Prefix the name with `__` to hide it from Outputs but keep it visible to chained rules. - `publish`: Boolean (default: true) - `priority`: Integer priority level - `metadata`: Free-form key-value data (appears as `detect_mtd` in the detection) -- `detect_data`: Free-form field for extracting specific elements into a known format +- `detect_data`: Free-form field that extracts specific elements into a known format -The `name`, `metadata`, and `detect_data` parameters support [template strings](../../4-data-queries/template-transforms.md). Note that the template context is the detection itself, so use `.detect.event.USER_NAME` not `.event.USER_NAME`. +The `name`, `metadata`, and `detect_data` parameters support [template strings](../../4-data-queries/template-transforms.md). The template context is the detection itself, so use `.detect.event.USER_NAME`, not `.event.USER_NAME`. ### `output` - Data Routing -Forwards the matched event to a specific Output in the `tailored` stream. +Sends the matched event to a specific Output in the `tailored` stream. ```yaml - action: output @@ -703,14 +703,14 @@ Sends a command to the sensor that generated the event. **Parameters:** -- `command`: The sensor command to execute (supports template strings, e.g., `artifact_get {{ .event.FILE_PATH }}`) -- `investigation`: Optional unique identifier for the task and resulting events +- `command`: The sensor command to run (supports template strings, e.g., `artifact_get {{ .event.FILE_PATH }}`) +- `investigation`: Optional unique identifier for the task and for the events that it produces See [Endpoint Commands](../../8-reference/endpoint-commands.md) for all available commands. ### `add tag` / `remove tag` - Sensor Tagging -Manages sensor tags for organization and targeting. +Adds or removes sensor tags. Use tags to group sensors and to target them. ```yaml - action: add tag @@ -723,11 +723,11 @@ Manages sensor tags for organization and targeting. - `tag`: Tag name - `ttl`: Optional, seconds until the tag expires -- `entire_device`: Optional boolean; when `true`, applies the tag to all sensors sharing the same Device ID +- `entire_device`: Optional boolean; when `true`, applies the tag to all sensors that share the same Device ID ### `add var` / `del var` - Sensor Variables -Manages sensor-specific variables for cross-rule state tracking. +Manages variables for each sensor. These variables track state across rules. ```yaml - action: add var @@ -742,11 +742,11 @@ Manages sensor-specific variables for cross-rule state tracking. - `value`: Value to store (supports lookback `<>` syntax) - `ttl`: Optional, seconds until the variable expires -Variables set here can be referenced in detection rules using `[[variable_name]]` syntax. See [Sensor Variables](../sensor-variables.md) for detailed usage. +Detection rules can reference these variables with the `[[variable_name]]` syntax. See [Sensor Variables](../sensor-variables.md) for more usage information. ### `isolate network` / `rejoin network` - Network Control -Controls sensor network connectivity for containment. Isolation is persistent (survives reboots). +Controls the network connectivity of the sensor for containment. Isolation is persistent and stays active after a reboot. ```yaml - action: isolate network @@ -758,7 +758,7 @@ Controls sensor network connectivity for containment. Isolation is persistent (s ### `seal` / `unseal` - Tamper Resistance -Controls sensor tamper resistance. Sealing is persistent (survives reboots). +Controls the tamper resistance of the sensor. The seal is persistent and stays active after a reboot. ```yaml - action: seal @@ -770,7 +770,7 @@ Controls sensor tamper resistance. Sealing is persistent (survives reboots). ### `undelete sensor` - Sensor Recovery -Restores a previously deleted sensor. Often used with the `deleted_sensor` deployment event. +Restores a deleted sensor. This action is often used with the `deleted_sensor` deployment event. ```yaml - action: undelete sensor @@ -794,11 +794,11 @@ Calls external extensions and integrations asynchronously. - `extension name`: Name of the extension - `extension action`: Action to trigger - `extension request`: Request parameters (varies by extension, supports template transforms) -- `based on report`: Optional boolean; when `true`, the transform is based on the latest `report` action's output instead of the original event (requires a preceding `report` action) +- `based on report`: Optional boolean; when `true`, the transform uses the output of the latest `report` action instead of the original event (needs a `report` action before it) ### `wait` - Introduce Delays -Adds a delay (up to 1 minute) before the next response action. Blocks sensor event processing for the specified duration. +Adds a delay (up to 1 minute) before the next response action. During this delay, the sensor stops event processing. ```yaml - action: wait @@ -807,7 +807,7 @@ Adds a delay (up to 1 minute) before the next response action. Blocks sensor eve **Parameters:** -- `duration`: A duration string (e.g., `5s`, `10ms`) or an integer representing seconds +- `duration`: A duration string (e.g., `5s`, `10ms`) or an integer that gives the number of seconds ### `add hive tag` / `remove hive tag` - Hive Record Tagging @@ -822,7 +822,7 @@ Manages tags on Hive records (e.g., D&R rules). ### `start ai agent` - AI-Driven Response -Spawns a Claude AI session for automated investigation and response. Supports two modes: +Starts a Claude AI session for automated investigation and response. There are two modes: **Inline Mode:** @@ -860,9 +860,9 @@ All response actions support `suppression` to manage repetitive or noisy alerts. **Parameters:** -- `max_count`: Maximum action executions per period -- `min_count`: Minimum threshold before executing (requires both `min_count` and `max_count`) -- `period`: Time window using duration format (`ns`, `us`, `ms`, `s`, `m`, `h`) +- `max_count`: Maximum number of times the action runs in each period +- `min_count`: Minimum threshold before the action runs (needs both `min_count` and `max_count`) +- `period`: Time window in duration format (`ns`, `us`, `ms`, `s`, `m`, `h`) - `is_global`: `true` for organization-wide suppression, `false` for per-sensor - `keys`: List of strings that form the uniqueness key (supports templates) - `count_path`: Path to an integer in the event for variable-count increments @@ -879,7 +879,7 @@ Key templates support three namespaces: ### Stateful Detection -The D&R engine supports sophisticated stateful detection patterns that track relationships and correlations across multiple events. +The D&R engine supports stateful detection patterns. These patterns track relationships and correlations across multiple events. #### Process Tree Tracking @@ -974,7 +974,7 @@ respond: #### Threshold Activation -Alert only after a certain number of occurrences using `min_count`: +Alert only after a set number of occurrences with `min_count`: ```yaml - action: report @@ -987,7 +987,7 @@ Alert only after a certain number of occurrences using `min_count`: ### Template System -Templates enable dynamic content generation in response actions using Go template syntax: +Templates build dynamic content in response actions with Go template syntax: ```yaml - action: report @@ -1013,7 +1013,7 @@ See [Template Strings](../../4-data-queries/template-transforms.md) for the full #### Lookup Resources -Integrate external threat intelligence and reference data: +Add external threat intelligence and reference data to a rule: ```yaml op: lookup @@ -1038,7 +1038,7 @@ detect: ## Cybersecurity Examples by Target Type -This section provides real-world cybersecurity examples for each target type. +This section gives cybersecurity examples for each target type. ### EDR Target Examples @@ -1355,7 +1355,7 @@ tests: ### Detection Target Examples -Detection rules process alerts generated by other D&R rules, enabling alert correlation, escalation, and suppression. +Detection rules process alerts that other D&R rules generate. This lets you correlate, escalate, and suppress alerts. #### Example 5: VIP Endpoint Escalation @@ -1510,7 +1510,7 @@ respond: ### Example 12: Office Macro to Persistence Chain -This rule detects an Office application spawning a shell that then establishes persistence: +This rule detects an Office application that starts a shell. The shell then sets up persistence. ```yaml detect: @@ -1577,7 +1577,7 @@ respond: ### Example 13: Ransomware Behavior Detection -Detects ransomware-like behavior: a process deleting shadow copies (common pre-encryption step). +Detects behavior like ransomware: a process that deletes shadow copies. This is a common step before encryption. ```yaml detect: @@ -1639,7 +1639,7 @@ respond: ### Example 14: Brute Force Detection with AI Triage -Detects brute force login attempts and spawns an AI agent for investigation. +Detects brute force login attempts and starts an AI agent for investigation. ```yaml detect: @@ -1714,13 +1714,13 @@ path: event/NETWORK_ACTIVITY/?/SIGNATURES/?/ISSUER #### Stateless Where Possible -Use `is stateless: true` within stateful rules when correlation isn't needed for a specific sub-rule. +In a stateful rule, use `is stateless: true` when a sub-rule does not need correlation. ### Suppression Best Practices #### Effective Suppression Keys -Use specific, meaningful suppression keys: +Use specific suppression keys with a clear meaning: ```yaml suppression: @@ -1734,7 +1734,7 @@ suppression: #### Time-Based Suppression -Adjust suppression periods based on detection criticality: +Adjust the suppression period to the criticality of the detection: ```yaml # Frequent, low-priority events — longer suppression @@ -1754,26 +1754,26 @@ suppression: ### Rule Design Principles -1. **Start simple**: Begin with basic detection logic and add complexity incrementally. +1. **Start simple**: Start with basic detection logic. Add complexity in steps. 2. **Specify event types**: Always use the `event:` parameter to limit which events trigger the rule. -3. **Test thoroughly**: Use the `tests` parameter with `match` and `non_match` cases to validate rule logic. -4. **Document with metadata**: Use the `metadata` field on `report` actions to include MITRE technique IDs, descriptions, and context. -5. **Handle alert fatigue**: Implement appropriate `suppression` on `report` actions. -6. **Use `case sensitive: false`**: For file paths and command lines, case-insensitive matching avoids missed detections. +3. **Test thoroughly**: Use the `tests` parameter with `match` and `non_match` cases to check the rule logic. +4. **Document with metadata**: Use the `metadata` field on `report` actions to add MITRE technique IDs, descriptions, and context. +5. **Handle alert fatigue**: Add `suppression` to `report` actions. +6. **Use `case sensitive: false`**: For file paths and command lines, case-insensitive matching keeps the rule from missing detections. ### Response Action Guidelines 1. **Proportional response**: Reserve aggressive actions (`isolate network`, `deny_tree`) for high-confidence detections. 2. **Chain actions carefully**: Use `wait` between dependent actions (e.g., after a `task` that needs to complete before the next step). -3. **Use suppression on expensive actions**: Avoid repeated network isolation or extension requests with proper suppression. -4. **Template safely**: Use conditional logic for fields that may not exist in all event types. +3. **Use suppression on expensive actions**: Use suppression to stop repeated network isolation or repeated extension requests. +4. **Template safely**: Use conditional logic for fields that can be absent in some event types. ### Operational Guidelines -1. **Test before deploying**: Unit tests run automatically when creating or updating rules — leverage them. -2. **Use FP rules**: Create false positive rules in the `fp` Hive to suppress known-good activity without modifying the detection. -3. **Monitor rule performance**: Use tags and suppression counters to track rule effectiveness. -4. **Iterate**: Refine rules based on real-world false positive and true positive rates. +1. **Test before deploying**: Unit tests run automatically when you create or update a rule. Use them. +2. **Use FP rules**: Create false positive rules in the `fp` Hive to suppress known-good activity without a change to the detection. +3. **Monitor rule performance**: Use tags and suppression counters to track how well a rule works. +4. **Iterate**: Refine rules with the real false positive and true positive rates. --- @@ -1783,28 +1783,28 @@ suppression: #### Rule Not Triggering -- Check that the `event:` filter matches actual event types being generated. -- Verify `path:` selectors point to existing fields in the event data (use the schema API or timeline to inspect events). -- Confirm operator parameters are correct (e.g., `re:` not `value:` for `matches`). -- Ensure the `target:` is correct for the data source. +- Check that the `event:` filter matches the event types that are generated. +- Check that the `path:` selectors point to fields that exist in the event data. Use the schema API or the timeline to inspect events. +- Confirm that the operator parameters are correct (e.g., `re:`, not `value:`, for `matches`). +- Make sure that the `target:` is correct for the data source. #### False Positives - Add contextual filters (`is tagged`, `times`, platform operators). -- Use FP rules in the `fp` Hive rather than making the detection more complex. -- Add `suppression` to manage volume. -- Refine detection specificity (e.g., `is` with `file name: true` instead of `contains`). +- Use FP rules in the `fp` Hive instead of a more complex detection. +- Add `suppression` to control the volume. +- Make the detection more specific (e.g., `is` with `file name: true` instead of `contains`). #### Template Errors -- Validate Go template syntax. -- Remember that `report` templates operate on the detection context (`.detect.event.*`), not the raw event (`.event.*`). +- Check the Go template syntax. +- `report` templates use the detection context (`.detect.event.*`), not the raw event (`.event.*`). - Use conditional logic for optional fields: `{{ if .event.FIELD }}{{ .event.FIELD }}{{ end }}`. -- Test secret and variable references are properly configured. +- Test that the secret and variable references are configured correctly. ### Unit Testing -Use the built-in testing framework to validate rule logic. Tests run automatically when rules are created or updated — if tests fail, the rule will not be deployed. +Use the built-in testing framework to check the rule logic. Tests run automatically when you create or update a rule. If a test fails, the rule is not deployed. ```yaml tests: @@ -1830,8 +1830,8 @@ tests: **Key points:** -- `match` contains tests that should trigger the rule. -- `non_match` contains tests that should NOT trigger the rule. +- `match` contains tests that must trigger the rule. +- `non_match` contains tests that must NOT trigger the rule. - Each test is a list of events (to support stateful rules with multiple events). - Events must include both `event` and `routing` objects. - Platform values in `routing/plat` are numeric (e.g., `268435456` for Windows). diff --git a/docs/3-detection-response/tutorials/threat-feed-rule.md b/docs/3-detection-response/tutorials/threat-feed-rule.md index 792693153..4adfde548 100644 --- a/docs/3-detection-response/tutorials/threat-feed-rule.md +++ b/docs/3-detection-response/tutorials/threat-feed-rule.md @@ -1,25 +1,29 @@ # Create a D&R Rule Using a Threat Feed -A common use case for rules is to use them to compare telemetry against known malicious IPs, domain names, or file hashes via threat feeds. With LimaCharlie, it is easy to leverage public threat feeds or create your own. +Rules often compare telemetry against known malicious IP addresses, domain names, or file hashes. A threat feed supplies these values. In LimaCharlie, you can use a public threat feed or create your own. -To configure a threat feed, it must first be enabled within the Add-ons Marketplace. First, select a threat feed from the plethora available for free. In the following example, we will enable `crimeware-ips`. +Before you configure a threat feed, enable it in the Add-ons Marketplace. Select one of the many threat feeds that are free. The example that follows enables `crimeware-ips`. ![crimeware ips](../../assets/images/crimeware-ips(1).png) -Select `Subscribe`, which will make the feed available to the respective Organization. +Select `Subscribe`. The feed then becomes available to the organization. -Once subscribed, you can write a D&R rule to detect whenever there is a match to an IP within the threat feed. Navigate to `D&R Rules` within the web application main page, and select `+ New Rule`. Begin your rule with the following template: +After you subscribe, write a D&R rule that detects a match to an IP address in the threat feed. -```yaml -event: NETWORK_CONNECTIONS -op: lookup -path: event/NETWORK_ACTIVITY/?/IP_ADDRESS -resource: hive://lookup/crimeware-ips -``` +1. On the main page of the web app, go to `D&R Rules`. +2. Select `+ New Rule`. +3. Start the rule with this template: + + ```yaml + event: NETWORK_CONNECTIONS + op: lookup + path: event/NETWORK_ACTIVITY/?/IP_ADDRESS + resource: hive://lookup/crimeware-ips + ``` ## Additional Telemetry Points -Configure a lookup based on file hash: +Configure a lookup that uses a file hash: ```yaml op: lookup @@ -28,7 +32,7 @@ path: event/HASH resource: hive://lookup/my-hash-lookup ``` -Configure a lookup based on domain name(s): +Configure a lookup that uses domain names: ```yaml op: lookup diff --git a/docs/3-detection-response/tutorials/writing-testing-rules.md b/docs/3-detection-response/tutorials/writing-testing-rules.md index 69f108b62..78cf045fc 100644 --- a/docs/3-detection-response/tutorials/writing-testing-rules.md +++ b/docs/3-detection-response/tutorials/writing-testing-rules.md @@ -1,110 +1,110 @@ # Writing and Testing Rules Detection & Response () Rules are similar to Google Cloud Functions or AWS Lambda. -They allow you to push D&R rules to the LimaCharlie cloud where the rules will be applied -in real-time to data coming from the sensors. +You push D&R rules to the LimaCharlie cloud. The cloud applies the rules in real +time to the data that comes from the sensors. -D&R rules can also be applied to [Artifact Collection](../../5-integrations/extensions/limacharlie/artifact.md), but for now we will focus -on the simple case where it is applied to Sensor events. +You can also apply D&R rules to [Artifact Collection](../../5-integrations/extensions/limacharlie/artifact.md). This page describes +the simple case: a rule that applies to sensor events. -For a full list of all rule operators and detailed documentation see the [Detection and Response](../examples.md) section. +For the full list of rule operators and more documentation, see the [Detection and Response](../examples.md) section. ## Life of a Rule -D&R rules are generally applied on a per-event basis. When the rule is applied, the "detection" -component of the rule is processed to determine if it matches. If there is a match, the "response" -component is applied. +The cloud usually applies a D&R rule to one event at a time. First, it evaluates the +"detection" component of the rule to find if the rule matches. If the rule matches, the +cloud applies the "response" component. -The detection is processed one step at a time, starting at the root of the detection. If the -root matches, the rule is considered to be matching. +The cloud evaluates the detection one step at a time. It starts at the root of the +detection. If the root matches, the rule matches. -The detection component is composed of "nodes", where each node has an operator describing the -logical evaluation. Most operators are simple, like `is`, `starts with` etc. These simple nodes -can be combined with Boolean (true/false) logic using the `and` and `or` operators, which -themselves reference a series of nodes. The `and` node matches if all the sub-nodes match, while -the `or` node matches if any one of the sub-nodes matches. +The detection component contains "nodes". Each node has an operator that describes the +logical evaluation. Most operators are simple, such as `is` and `starts with`. You can +combine simple nodes with Boolean (true/false) logic through the `and` and `or` operators, +which reference a series of nodes. An `and` node matches if all of its sub-nodes match. +An `or` node matches if one or more of its sub-nodes match. -When evaluating an `or`, as soon as the first matching sub-node is found, the rest of the sub-nodes -are skipped since they will have no impact on the final matching state of the "or". Similarly, failure of a sub-node in an "and" node will immediately terminate its evaluation. +In an `or` node, the cloud stops at the first sub-node that matches. It skips the other +sub-nodes, because they cannot change the result of the "or". In an "and" node, the first +sub-node that fails stops the evaluation immediately. -If the "detection" component is matched, then the "response" evaluation begins. +If the "detection" component matches, the "response" evaluation starts. -The "response" component is a list of actions that should be taken. When an action refers to a -sensor, that sensor is assumed to be the sensor the event being evaluated is coming from. +The "response" component is a list of actions to do. If an action refers to a sensor, that +sensor is the sensor that sent the event. -The best general strategy for D&R rules is to put the parts of the rule most likely -to eliminate the event at the beginning of the rule, so that LC may move on to the next event -as quickly as possible. +Put the parts of the rule that most probably eliminate the event at the start of the rule. +LC can then move to the next event more quickly. ## Introduction ### Goal -The goal of is code lab will be to create a D&R rule to detect the MITRE ATT&CK framework -[Control Panel Items](https://attack.mitre.org/techniques/T1196/) execution. +This code lab creates a D&R rule that detects execution of +[Control Panel Items](https://attack.mitre.org/techniques/T1196/) in the MITRE ATT&CK framework. ### Services Used -This code lab will use the Replay service to validate and test the rule prior to pushing it to production. +This code lab uses the Replay service to validate and test the rule before you push it to production. ## Setup and Requirements -This code lab assumes you have access to a Linux host (MacOS terminal with `brew`). This -code lab also assumes you have "owner" access to an LC Organization. If you don't have -one already, create one, this code lab is compatible with the free tier that comes with -all organizations. +This code lab assumes that you have access to a Linux host (or a MacOS terminal with +`brew`). It also assumes that you have "owner" access to an LC Organization. If you do not +have one, create one. This code lab works with the free tier that comes with all +organizations. ### Install CLI -Interacting with LC can always be done via the [web app](https://app.limacharlie.io) but -day to day operations and automation can be done via the Command Line Interface (CLI). This -will make following this code lab easier. +You can always interact with LC through the [web app](https://app.limacharlie.io), but you +can do daily operations and automation with the Command Line Interface (CLI). This code lab +uses the CLI. -Install the CLI: `pip install limacharlie --user`. If you don't have `pip` installed, install -it, the exact instructions will depend on your Linux distribution. +Install the CLI: `pip install limacharlie --user`. If `pip` is not installed, install it. +The exact instructions depend on your Linux distribution. ### Create REST API Key -We need to create an API key we can use in the CLI to authenticate with LC. To do so, go -to the REST API section of the web app. +Create an API key that the CLI uses to authenticate with LC. Go to the REST API section of +the web app. 1. In the REST API section, click the "+" button in the top right of the page. 2. Give your key a name. -3. For simplicity, click the "Select All" button to enable all permissions. Obviously this would not be a recommended in a production environment, -4. Click the copy-to-clipboard button for the new key and take note of it (pasting it in a temporary text note for example). -5. Back on the REST API page, copy the "Organization ID" at the top of the page and keep note of it like the API key in the previous step. +3. For simplicity, click the "Select All" button to enable all permissions. This is not recommended in a production environment. +4. Click the copy-to-clipboard button for the new key. Keep a record of the key, for example in a temporary text note. +5. On the REST API page, copy the "Organization ID" at the top of the page. Keep a record of it, as you did for the API key. -The Organization ID (OID) identifies uniquely your organization while the API key grants specific permissions to this organization. +The Organization ID (OID) is the unique identifier of your organization. The API key grants specific permissions to this organization. ### Login to the CLI -Back in your terminal, log in with your credentials: `limacharlie auth login`. +In your terminal, log in with your credentials: `limacharlie auth login`. -1. When asked for the Organization ID, paste your OID from the previous step. -2. When asked for a name for this access, you can leave it blank to set the default credentials. -3. When asked for the secret API key, enter the key you got from the previous step. +1. When the CLI asks for the Organization ID, paste the OID from the previous step. +2. When the CLI asks for a name for this access, leave it blank to set the default credentials. +3. When the CLI asks for the secret API key, enter the key from the previous step. -You're done! If you issue a `limacharlie dr list` you should not get any errors. +The setup is complete. If you run `limacharlie dr list`, the command shows no errors. ## Draft Rule -To draft our rule, open your preferred text editor and save the rule to a file, we'll call it `T1196.rule`. -The format of a rule is [YAML](https://en.wikipedia.org/wiki/YAML), if you are unfamiliar with it, there is benefit to spending a few minutes getting familiar. It won't take long as it is not overly complex. +To draft the rule, open a text editor and save the rule to a file named `T1196.rule`. +A rule uses the [YAML](https://en.wikipedia.org/wiki/YAML) format. If you do not know YAML, spend a few minutes to learn it. YAML is not complex. -For our rules based on the [T1196](https://attack.mitre.org/techniques/T1196/) technique, we need -to apply the following constraints: +The rule is based on the [T1196](https://attack.mitre.org/techniques/T1196/) technique. It +needs these constraints: -1. It only applies to Windows. -2. The event is a module (DLL for example on Windows) loading. -3. The module loading ends with `.cpl` (control panel extension). -4. The module is loading from outside of the `C:\windows\` directory. +1. The rule applies to Windows only. +2. The event is the load of a module (a DLL on Windows). +3. The module that loads ends with `.cpl` (the control panel extension). +4. The module loads from outside the `C:\windows\` directory. -LC supports a lot of different event types, this means that the first thing we should strive to -do to try to make the rule fail as quickly as possible is to filter all events we don't care about. +LC supports many event types. To make the rule fail as quickly as possible, first filter out +all events that do not matter. -In this case, we only care about [CODE_IDENTITY](../../8-reference/edr-events.md#code_identity) events. We also know that -our rule will use more than one criteria, and those criteria will be AND-ed together because we only -want to match when they all match. +This rule uses only [CODE_IDENTITY](../../8-reference/edr-events.md#code_identity) events. The rule also uses more than one +criterion. The rule AND-s the criteria together, because it must match only when all of them +match. ```yaml op: and @@ -113,14 +113,14 @@ rules: - ``` -The above sets up the criteria #2 preceding it, with the AND-ing that will follow. Since the AND is at the -top of our rule, and it has an `event:` clause, it will ensure that any event processed by this rule -but is NOT a `CODE_IDENTITY` event will be skipped over right away. +The block above sets up criterion #2 and the AND operation that follows. The `and` node is at +the top of the rule, and it has an `event:` clause. Therefore, the rule skips any event that +is NOT a `CODE_IDENTITY` event immediately. -Next, we should look at the other criteria, and add them to the `rules:` list, which are all the sub-nodes -that will be AND-ed together. +Next, add the other criteria to the `rules:` list. This list holds all the sub-nodes that the +rule AND-s together. -Criteria #1 was to limit to Windows, that's easy: +Criterion #1 limits the rule to Windows: ```yaml op: and @@ -130,10 +130,10 @@ rules: - ``` -Next up is criteria #3 and #4. Both of those can be determined using the `FILE_PATH` component of the -`CODE_IDENTITY` event. If you are unure what those events look like, the best way to get a positive confirmation -of the structure is simply to open the Historic View, start a new process on that specific host and look for -the relevant event. If we were to do this on a Windows host, we'd get an example like this one: +Criteria #3 and #4 come next. The `FILE_PATH` component of the `CODE_IDENTITY` event gives +both of them. To confirm the structure of these events, open the Historic View. Start a new +process on that host. Then find the relevant event. On a Windows host, the event looks like +this example: ```json { @@ -175,13 +175,13 @@ the relevant event. If we were to do this on a Windows host, we'd get an example } ``` -This means what we want is to apply rules to the `event/FILE_PATH`. First part, #3 is easy, we just want -to test for the `event/FILE_PATH` ends in `.cpl`, we can do this using the `ends with` operator. +The rule therefore applies to `event/FILE_PATH`. For criterion #3, test that +`event/FILE_PATH` ends with `.cpl`. Use the `ends with` operator. -Most operators will use a `path` and a `value`. General convention is the `path` describes -how to get to a value we want to compare within the event. So `event/FILE_PATH` says "starting in the `event` -then get the `FILE_PATH`. The `value` generally represents a value we want to compare to the element found -in the `path`. How it is compared depends on the operator. +Most operators use a `path` and a `value`. The `path` describes how to get to the value that +you want to compare in the event. For example, `event/FILE_PATH` means "start in the `event`, +then get the `FILE_PATH`". The `value` is the value that you compare to the element at the +`path`. The operator controls how the comparison works. ```yaml op: and @@ -193,9 +193,9 @@ rules: value: .cpl ``` -That was easy, but we're missing a critical component! By default, D&R rules operate in a case sensitive mode. -This means that the above node we added will match `.cpl` but will NOT match `.cPl`. To fix this, we just add -the `case sensitive: false` statement. +One critical component is missing. By default, D&R rules are case sensitive. The node above +matches `.cpl` but does NOT match `.cPl`. To correct this, add the `case sensitive: false` +statement. ```yaml op: and @@ -209,9 +209,10 @@ rules: - ``` -Finally, we want to make sure the `event/FILE_PATH` is NOT in the `windows` directory. To do this, we will use -a regular expression with a `matches` operator. But in this case, we want to EXCLUDE the paths that include -the `windows` directory, so we want to "invert" the match. We can do this with the `not: true` statement. +Last, make sure that `event/FILE_PATH` is NOT in the `windows` directory. Use a regular +expression with the `matches` operator. The rule must EXCLUDE the paths that contain the +`windows` directory, so it must invert the match. The `not: true` statement inverts the +match. ```yaml op: and @@ -229,20 +230,20 @@ rules: not: true ``` -Here we go, we're done drafting our first rule. +The draft of the first rule is complete. ## Validate Rule -What we want to do now is validate the rule. If the rule validates, it doesn't mean it's correct, it -just means that the structure is correct, the operators we use are known, etc. It's the first pass at -detecting possible formatting issues or typos. +Now validate the rule. Validation does not show that the rule is correct. It shows that the +structure is correct, that the operators are known, and so on. Validation is the first pass +to find possible format problems or typos. -To validate, we will simply leverage the Replay service. This service can be used to test rules or replay -historical events against a rule. In this case however, we just want to start by validating. +Validation uses the Replay service. This service can test rules or replay historical events +against a rule. This step uses only the validation function. -Up until now we focused on the "detection" part of the rule. But a full rule also contains a "response" -component. So before we proceed, we'll add this structure. For a response, we will use a -simple `action: report`. The `report` creates a "detection" (alert). +The steps above cover only the "detection" part of the rule. A full rule also contains a +"response" component. Add this structure before you continue. The response uses +`action: report`. The `report` action creates a "detection" (alert). ```yaml detect: @@ -264,58 +265,56 @@ respond: name: T1196 ``` -Now validate the rule structure. Save the detect and respond components to separate files (`T1196_detect.yaml` and `T1196_respond.yaml`), then run: +Now validate the structure of the rule. Save the detect and respond components to separate files (`T1196_detect.yaml` and `T1196_respond.yaml`), then run: `limacharlie dr validate --detect T1196_detect.yaml --respond T1196_respond.yaml` -After a few seconds, you should see a response with `success: true` if the rule -validates properly. +After a few seconds, the response shows `success: true` if the rule is valid. ## Test rule ### Test Plan -Now that we know our rule is generally sound, we need to test it against some events. +The rule is now structurally sound. Test it against some events. -Our test plan will take the following approach: +The test plan uses these steps: -1. Test a positive (a `.cpl` loading outside of `windows`). -2. Test a negative for the major criteria: +1. Test a positive match: a `.cpl` that loads outside `windows`. +2. Test a negative match for each major criterion: - 1. Test a non-`.cpl` loading outside of `windows` does not match. - 2. Test a `.cpl` loading within `windows` does not match. + 1. Test that a non-`.cpl` file that loads outside `windows` does not match. + 2. Test that a `.cpl` that loads in `windows` does not match. 3. Test on historical data. -With this plan, #1 and #2 lend themselves well to [unit tests](https://en.wikipedia.org/wiki/Unit_testing) -while #3 can be done more holistically by using Replay to run historical events -through the rule and evaluate if there are any [false positives](https://en.wikipedia.org/wiki/False_positives_and_false_negatives). +Steps #1 and #2 are a good match for [unit tests](https://en.wikipedia.org/wiki/Unit_testing). +Step #3 uses Replay to run historical events through the rule and to find +[false positives](https://en.wikipedia.org/wiki/False_positives_and_false_negatives). -This may be excessive for you, or for certain rules which are very simple, we leave that -evaluation to you. For the sake of this code lab, we will do a light version to demonstrate -how to do tests. +This plan can be more than you need, or more than a simple rule needs. You decide how much to +test. This code lab uses a short version of the tests as a demonstration. ### Testing a Single Event -To test #1 and #2, let's just create some synthetic events. It's always better to use -real-world samples, but we'll leave that up to you. +For tests #1 and #2, create some synthetic events. Real-world samples are better, but the +choice is yours. -Take the event sample we had in the "Draft Rule" section and copy it to two new files -we will name `positive.json`, `negative-1.json` and `negative-2.json`. +Take the event sample from the "Draft Rule" section and copy it to two new files that you +name `positive.json`, `negative-1.json` and `negative-2.json`. -Modify the `positive.json` file by renaming the `FILE_PATH` at the bottom from -`"C:\\Windows\\System32\\setupcln.dll"` to `"C:\\temp\\System32\\setupcln.cpl"` so that -the event now describes a `.cpl` loading in the `temp` directory, which we should detect. +In `positive.json`, change the `FILE_PATH` at the bottom from +`"C:\\Windows\\System32\\setupcln.dll"` to `"C:\\temp\\System32\\setupcln.cpl"`. The event +then describes a `.cpl` that loads in the `temp` directory, and the rule must detect it. -Then modify the `negative-1.json` file by changing the same `.dll` to `.cpl`. This should NOT -match because the path is still in the `windows` directory. +In `negative-1.json`, change the same `.dll` to `.cpl`. This event must NOT match, because +the path is still in the `windows` directory. -Then modify the `negative-2.json` file by changing the `windows` directory to `temp`. This -should still NOT match because it's not a `.cpl`. +In `negative-2.json`, change the `windows` directory to `temp`. This event must NOT match, +because the file is not a `.cpl`. -Now we can run our 3 samples against the rule using Replay, +Now run the 3 samples against the rule with Replay. -`limacharlie dr test --input-file T1196.rule --events positive.json` should output a result -indicating the event matched (by actioning the `report`) like: +The command `limacharlie dr test --input-file T1196.rule --events positive.json` shows that +the event matched. The result contains the `report` action: ```json { @@ -330,8 +329,8 @@ indicating the event matched (by actioning the `report`) like: ... ``` -`limacharlie dr test --input-file T1196.rule --events negative-1.json` should output a result -indicating the event did NOT match like: +The command `limacharlie dr test --input-file T1196.rule --events negative-1.json` shows that +the event did NOT match: ```json { @@ -343,17 +342,16 @@ indicating the event did NOT match like: } ``` -`limacharlie dr test --input-file T1196.rule --events negative-2.json` be the same as `negative-1.json`. +The result of `limacharlie dr test --input-file T1196.rule --events negative-2.json` is the same as the result for `negative-1.json`. ### Testing Historical Data -The final test is to run the rule against historical data. If you are not using an -organization on the free tier, note that the Replay API is billed on usage. In the -following step we will run against all historical data from the organization, so if -your organization is not on the free tier and it is large, there may be non-trivial -costs associated. +The last test runs the rule against historical data. The Replay API is billed on usage if +your organization is not on the free tier. The next step runs against all historical data +from the organization. A large organization that is not on the free tier can therefore cause +significant costs. -Running our rule against the last week of data is simple: +To run the rule against the last week of data, use these commands: ```bash START=$(date -d '7 days ago' +%s) @@ -361,7 +359,7 @@ END=$(date +%s) limacharlie replay run --detect-file T1196_detect.yaml --respond-file T1196_respond.yaml --start $START --end $END ``` -No matches should look like that: +A result with no matches looks like this: ```json { @@ -375,13 +373,14 @@ No matches should look like that: ### Moving to Unit Tests -Once your rule is done and you've evaluated various events for matches, you can move these to [D&R Rules Unit Tests](../unit-tests.md) so that the tests are run during rule update. +After the rule is complete and you evaluate events for matches, move these events to +[D&R Rules Unit Tests](../unit-tests.md). LC then runs the tests at each rule update. ## Publish Rule -Now is the time to push the new rule to production, the easy part. +Now push the new rule to production. -Simply run `limacharlie dr set --key T1196 --input-file T1196.rule --enabled` -and confirm it is operational by running `limacharlie dr list`. -The `--enabled` flag creates the rule and enables it in one shot — without -it the rule is stored disabled and would not fire on matching events. +Run `limacharlie dr set --key T1196 --input-file T1196.rule --enabled`. +Then run `limacharlie dr list` to confirm that the rule is operational. +The `--enabled` flag creates the rule and enables it in one step. Without +the flag, the cloud stores the rule as disabled, and the rule does not fire on matching events. diff --git a/docs/3-detection-response/unit-tests.md b/docs/3-detection-response/unit-tests.md index e9f27dcec..6d9e6795e 100644 --- a/docs/3-detection-response/unit-tests.md +++ b/docs/3-detection-response/unit-tests.md @@ -2,11 +2,11 @@ ## Rules Unit Tests -A D&R rule record can optionally contain unit tests. These tests describe events that should match, and events that should not match. When a D&R rule is updated or created, LimaCharlie will simulate the rules and if the tests fail, an error is produced. +A D&R rule record can contain unit tests. These tests describe the events that must match and the events that must not match. When you create or update a D&R rule, LimaCharlie simulates the rules. If the tests fail, LimaCharlie produces an error. ### Structure -A typical D&R rule looks like: +A typical D&R rule looks like this: ```json { @@ -22,9 +22,9 @@ A typical D&R rule looks like: } ``` -The `match` and `non_match` both have the same format: they contain a list of lists of events. Each top list element is a unit test, and the content of a test is a list of events as would be seen by LimaCharlie. The reason for the test to be a list is to accomodate for [Stateful Detections](stateful-rules.md) which operate across multiple events. +The `match` and `non_match` fields have the same format. Each field contains a list of lists of events. Each element of the top list is one unit test. The content of a test is a list of events in the form that LimaCharlie sees. A test is a list because [Stateful Detections](stateful-rules.md) operate across more than one event. -Here's an example: +Here is an example: ```json { diff --git a/docs/4-data-queries/events/sysmon-comparison.md b/docs/4-data-queries/events/sysmon-comparison.md index 0a8e776c3..a25886a55 100644 --- a/docs/4-data-queries/events/sysmon-comparison.md +++ b/docs/4-data-queries/events/sysmon-comparison.md @@ -2,9 +2,9 @@ System Monitor, or "Sysmon", is a Windows server and device driver that monitors and logs operating system activity. It is part of the Sysinternals toolkit. See Microsoft's [Sysmon download and reference page](https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon). -Many organizations deploy Sysmon and structure their detection events around Sysmon-specific event logs, which can offer granular insight into operating system changes. LimaCharlie's EDR telemetry can offer similar events, allowing you to write detections against these events directly. +Many organizations deploy Sysmon and build their detection events around Sysmon event logs. These logs give detailed information about changes to the operating system. The EDR telemetry of LimaCharlie gives similar events, and you can write detections against these events directly. -A comparison of LimaCharlie vs. Sysmon is as follows: +The table below compares Sysmon events to LimaCharlie events: | Sysmon Event | LimaCharlie Event | | --- | --- | @@ -22,10 +22,10 @@ A comparison of LimaCharlie vs. Sysmon is as follows: | Event ID 17 (PipeEvent Created) | NEW\_NAMED\_PIPE | | Event ID 18 (PipeEvent Connected) | OPEN\_NAMED\_PIPE | -Why not both? ¯\*(ツ)*/¯ +You can also use both. -Note, LC's Endpoint Agent is easily able to [consume Sysmon events](../../2-sensors-deployment/tutorials/sysmon-logs.md) as well. +The LimaCharlie sensor can also [consume Sysmon events](../../2-sensors-deployment/tutorials/sysmon-logs.md). ## Executable Tracking -Recent updates to Sysmon also include the ability to capture and store information about binaries identified on a system. You can replicate this functionality in LimaCharlie with the [BinLib extension](../../5-integrations/extensions/limacharlie/binlib.md). +Recent updates to Sysmon can also capture and store information about binaries found on a system. You can do the same in LimaCharlie with the [BinLib extension](../../5-integrations/extensions/limacharlie/binlib.md). diff --git a/docs/4-data-queries/index.md b/docs/4-data-queries/index.md index 566cc4cd7..698a9d32d 100644 --- a/docs/4-data-queries/index.md +++ b/docs/4-data-queries/index.md @@ -1,12 +1,12 @@ # Query Console -Query and analyze your security telemetry using LimaCharlie Query Language (LCQL). +Query and analyze your security telemetry with LimaCharlie Query Language (LCQL). ## Documentation - [LCQL Examples](lcql-examples.md) - Example queries for common use cases -- [Query Console UI](query-console-ui.md) - Using the web-based query interface -- [Query with CLI](query-cli.md) - Running queries from the command line +- [Query Console UI](query-console-ui.md) - How to use the query interface in the web app +- [Query with CLI](query-cli.md) - How to run queries from the command line - [Query Limits & Performance](query-limits-and-performance.md) - Concurrency and timeout limits, and how to write efficient queries --- @@ -14,11 +14,11 @@ Query and analyze your security telemetry using LimaCharlie Query Language (LCQL ## Running Queries Programmatically !!! info "Prerequisites" - All API examples require an API key with the `insight` permission. See [API Keys](../7-administration/access/api-keys.md) for setup. + All API examples need an API key with the `insight` permission. For setup steps, see [API Keys](../7-administration/access/api-keys.md). ### Search API Endpoint -There is no single search hostname. Each organization's search endpoint lives in the datacenter for the region where the organization was created, so you discover it from the API first and then send queries to that host. The Python SDK, Go SDK, and CLI do this automatically. +There is no single search hostname. The search endpoint of an organization is in the datacenter for the region where the organization was created. First, get the endpoint from the API. Then send your queries to that host. The Python SDK, the Go SDK, and the CLI do this automatically. === "REST API" @@ -30,13 +30,13 @@ There is no single search hostname. Each organization's search endpoint lives in === "Python" - The Python SDK resolves the search endpoint automatically from your OID; no manual step is required. + The Python SDK resolves the search endpoint automatically from your OID. There is no manual step. === "CLI" - The CLI resolves the search endpoint automatically from your OID; no manual step is required. + The CLI resolves the search endpoint automatically from your OID. There is no manual step. -The bootstrap API host `https://api.limacharlie.io` is the same for every region and routes to the correct datacenter based on your OID. The REST examples below reuse the `$SEARCH_HOST` variable for the discovered hostname. For reference, the current production search endpoints per region are: +The bootstrap API host `https://api.limacharlie.io` is the same for every region. It routes to the correct datacenter for your OID. The REST examples below reuse the `$SEARCH_HOST` variable for the hostname that you found. The current production search endpoints for each region are: | Region | Search endpoint | |--------|-----------------| @@ -48,7 +48,7 @@ The bootstrap API host `https://api.limacharlie.io` is the same for every region | India | `https://4d897015b0815621.replay-search.limacharlie.io` | !!! tip "Use the bootstrap API, not a direct endpoint" - Discovering your search endpoint through the bootstrap API (`https://api.limacharlie.io/v1/orgs/{oid}/url`, the `url.search` field) is the recommended approach. The direct per-region hostnames above can change over time, whereas the bootstrap API always returns the current endpoint for your organization. Treat the table as a convenience reference only, and do not hardcode a direct endpoint. + Get your search endpoint through the bootstrap API (`https://api.limacharlie.io/v1/orgs/{oid}/url`, the `url.search` field). The direct hostnames for each region above can change with time, but the bootstrap API always returns the current endpoint for your organization. Use the table as a reference only. Do not hardcode a direct endpoint. ### Run an LCQL Query @@ -183,7 +183,7 @@ The bootstrap API host `https://api.limacharlie.io` is the same for every region ``` !!! note - The validate response also includes query-size fields (`batchesInScope`, `eventsInScope`, `bytesInScope`) and a running search returns per-page progress and actual billing. See [Query Progress and Cost Reporting](query-limits-and-performance.md#query-progress-and-cost-reporting) for how to build a progress bar and read the real cost. + The validate response also includes query-size fields (`batchesInScope`, `eventsInScope`, `bytesInScope`). A query that runs returns the progress for each page and the actual billing. To build a progress bar and read the real cost, see [Query Progress and Cost Reporting](query-limits-and-performance.md#query-progress-and-cost-reporting). ### Saved Queries diff --git a/docs/4-data-queries/lcql-examples.md b/docs/4-data-queries/lcql-examples.md index 413aedca9..6d80c71c8 100644 --- a/docs/4-data-queries/lcql-examples.md +++ b/docs/4-data-queries/lcql-examples.md @@ -1,14 +1,14 @@ # LCQL Examples -LimaCharlie Query Language (LCQL) lets you write well-structured queries to search across telemetry within LimaCharlie. The following examples can help you perform targeted searches or hunts across your telemetry, as well as modify them to build your own. Example queries are sorted by *source*, however can be adjusted for your environment. +LimaCharlie Query Language (LCQL) lets you write structured queries against the telemetry in LimaCharlie. The examples below help you do targeted searches or hunts across your telemetry. You can also change them to build your own queries. The examples are sorted by *source*, but you can adjust them for your environment. -Got a Unique Query? +Share your unique queries. -If you've written a unique query or have one you'd like to share with the community, please join us in the [LimaCharlie Community](https://community.limacharlie.com/)! +If you wrote a unique query, or you want to share one with the community, join the [LimaCharlie Community](https://community.limacharlie.com/). ## Time Range -Every LCQL query is scoped to a time range. Where that range comes from depends on the interface you use: +Every LCQL query has a time range. The source of that range depends on the interface that you use: | Interface | How the time range is set | |-----------|---------------------------| @@ -18,13 +18,13 @@ Every LCQL query is scoped to a time range. Where that range comes from depends | CLI (`limacharlie search run`) | The **`--start` and `--end`** flags, in Unix epoch seconds. | !!! note - In the Search API, the CLI, and the Query Console, the explicit range (the picker, `startTime` / `endTime`, or `--start` / `--end`) always wins: any time prefix written into the query string is stripped and replaced. The examples on this page include the leading time component (`-24h |`) because they are written as raw LCQL, where the time range is the first component of the query string. + In the Search API, the CLI, and the Query Console, the explicit range has priority. The explicit range is the picker, `startTime` / `endTime`, or `--start` / `--end`. Any time prefix in the query string is removed and replaced. The examples on this page include the leading time component (`-24h |`) because they are raw LCQL. In raw LCQL, the time range is the first component of the query string. ### Time Formats in the Query String When the time range is part of the query (raw LCQL and the Replay API), the first component accepts relative durations, absolute date/times, or a bounded range. -**Relative durations** count backwards from now using Go [duration syntax](https://pkg.go.dev/time#ParseDuration). The units are `h`, `m`, and `s`; there is no day or week unit, so express longer windows in hours (`-168h` is 7 days). +**Relative durations** count backwards from now with the Go [duration syntax](https://pkg.go.dev/time#ParseDuration). The units are `h`, `m`, and `s`. There is no unit for days or weeks, so give longer windows in hours (`-168h` is 7 days). | Value | Meaning | |-------|---------| @@ -32,9 +32,9 @@ When the time range is part of the query (raw LCQL and the Replay API), the firs | `-90m` | Last 90 minutes | | `-1h30m` | Last 1 hour and 30 minutes | -**Absolute date/times** accept common formats such as `2025-01-16 08:52:54` or `2025-01-16`. When you need precise control, include a timezone offset (for example a trailing `Z` or `+02:00`); a time given without one is interpreted as UTC. +**Absolute date/times** accept common formats such as `2025-01-16 08:52:54` or `2025-01-16`. For precise control, include a timezone offset, for example a trailing `Z` or `+02:00`. A time without an offset is interpreted as UTC. -**Bounded ranges** join two values with `to`. Each side may be relative or absolute, and the two can be mixed. A single value with no `to` means "from that time until now". +**Bounded ranges** join two values with `to`. Each side can be relative or absolute, and you can mix the two. A single value with no `to` means "from that time until now". ```lcql -24h to -12h | plat == windows | NEW_PROCESS | event/FILE_PATH ends with ".exe" @@ -42,16 +42,16 @@ When the time range is part of the query (raw LCQL and the Replay API), the firs ## General Queries -Search *all* event types across *all* Windows systems for a particular string showing up in *any* field. The `event/*` selector is a subtree wildcard: it tests the value against every field in the event. +Search *all* event types on *all* Windows systems for a string in *any* field. The `event/*` selector is a subtree wildcard. It tests the value against every field in the event. ```lcql -24h | plat == windows | * | event/* contains 'psexec' ``` !!! warning "`event/*` is powerful but slow" - A subtree wildcard has to test every field of every event, and pairing it with the `*` event-type selector scans every event type - the most expensive shape of query. Use it for broad, exploratory hunts, then narrow to a specific event type and field (for example `NEW_PROCESS | event/COMMAND_LINE contains 'psexec'`) once you know where the value lives. See [Query Limits & Performance](query-limits-and-performance.md#writing-efficient-and-performant-queries). + A subtree wildcard must test every field of every event. With the `*` event-type selector, the query also scans every event type. This is the most expensive shape of query. Use it for broad hunts. When you know which field holds the value, narrow the query to a specific event type and field, for example `NEW_PROCESS | event/COMMAND_LINE contains 'psexec'`. See [Query Limits & Performance](query-limits-and-performance.md#writing-efficient-and-performant-queries). -You can also scope the wildcard to a specific *subtree* instead of the whole event, which is far cheaper than `event/*`. Windows Event Log records nest many fields under `event/EVENT/EventData`; this matches a username in any of those fields without touching the rest of the event: +You can also apply the wildcard to a specific *subtree* instead of the whole event. A subtree is much cheaper than `event/*`. Windows Event Log records keep many fields under `event/EVENT/EventData`. This query matches a username in any of those fields, and it does not read the rest of the event: ```lcql -24h | plat == windows | WEL | event/EVENT/EventData/* contains "administrator" @@ -59,11 +59,11 @@ You can also scope the wildcard to a specific *subtree* instead of the whole eve ## GitHub Telemetry -GitHub logs can be an excellent source of telemetry to identify potential repository or account abuse or misuse. When ingested properly, GitHub log data can be observed via `plat == github`. +GitHub logs are a good source of telemetry to find abuse or misuse of a repository or an account. When LimaCharlie ingests the logs correctly, you can see the GitHub log data with `plat == github`. ### GitHub Protected Branch Override -Show me all the GitHub branch protection override (force pushing to repo without all approvals) in the past 12h that came from a user outside the United States, with the repo, user and number of infractions. +Show all GitHub branch protection overrides (a force push to a repository without all approvals) in the last 12h that came from a user outside the United States. Show the repository, the user, and the number of infractions. ```lcql -12h | plat == github | protected_branch.policy_override | event/public_repo is false and event/actor_location/country_code is not "us" | event/repo as repo event/actor as actor COUNT(event) as count GROUP BY(repo actor) @@ -79,11 +79,11 @@ which could result in: ## Network Telemetry -Network details recorded on endpoints, such as new connections or DNS requests, allow for combined insight. We can also query this data for aggregate details, and display data in an easily-consumed manner. +Endpoints record network details such as new connections and DNS requests. These details give combined information. You can also query this data for aggregate details and show the results in a readable form. ### Domain Count -Show me all domains resolved by Windows hosts that contain "google" in the last 10 minutes and the number of times each was resolved. +Show all domains that contain "google" and that Windows hosts resolved in the last 10 minutes. Also show how many times each domain was resolved. ```lcql -10m | plat == windows | DNS_REQUEST | event/DOMAIN_NAME contains 'google' | event/DOMAIN_NAME as domain COUNT(event) as count GROUP BY(domain) @@ -98,7 +98,7 @@ which could result in: ### Domain Prevalence -Show me all domains resolved by Windows hosts that contain "google" in the last 10 minutes and the number of unique Sensors that have resolved them. +Show all domains that contain "google" and that Windows hosts resolved in the last 10 minutes. Also show the number of unique Sensors that resolved each domain. ```lcql -10m | plat == windows | DNS_REQUEST | event/DOMAIN_NAME contains 'google' | event/DOMAIN_NAME as domain COUNT_UNIQUE(routing/sid) as count GROUP BY(domain) @@ -135,7 +135,7 @@ Grouped and counted. ## Windows Event Log (WEL) -When ingested with EDR telemetry, or as a separate Adapter, `WEL` type events are easily searchable via LimaCharlie. Sample queries are organized alphabetically, with threat/technique details provided where applicable. +You can query `WEL` type events in LimaCharlie when you ingest them with EDR telemetry or with a separate Adapter. The sample queries are in alphabetical order. Details of the threat or the technique are given where they apply. ### %COMSPEC% in Service Path @@ -179,11 +179,11 @@ When ingested with EDR telemetry, or as a separate Adapter, `WEL` type events ar ## Common Operators and Patterns -The filter (the clause before the projection) is a full detection-style expression. These snippets show the operators and patterns you will use most often; combine them with the projection, aggregation, sorting, and limiting clauses shown elsewhere on this page. For the broad `event/*` subtree wildcard, see [General Queries](#general-queries) above. +The filter (the clause before the projection) is a full detection-style expression. These examples show the most common operators and patterns. Combine them with the projection, aggregation, sorting, and limiting clauses in other sections of this page. For the broad `event/*` subtree wildcard, see [General Queries](#general-queries) above. ### String matching -Double-quoted values are case-insensitive; single-quoted values are case-sensitive. +Double-quoted values are case-insensitive. Single-quoted values are case-sensitive. - Contains (case-insensitive): `event/FILE_PATH contains "temp"` - Contains (case-sensitive): `event/FILE_PATH contains 'Temp'` @@ -191,7 +191,7 @@ Double-quoted values are case-insensitive; single-quoted values are case-sensiti - Regular expression: `event/COMMAND_LINE matches "(?i)invoke-\\w+"` - Negation: `event/FILE_PATH not contains "system32"` -Combined example - executables launched from outside `system32`: +Combined example - executables that start from outside `system32`: ```lcql -1h | plat == windows | NEW_PROCESS | event/FILE_PATH ends with ".exe" and event/FILE_PATH not contains "system32" | event/FILE_PATH as Path event/COMMAND_LINE as CommandLine routing/hostname as Host @@ -218,7 +218,7 @@ Example - outbound connections to public IPs on high ports: ### Field existence -`exists` matches events where a field is present, regardless of value: +`exists` matches events that contain the field, with any value: ```lcql -1h | plat == windows | NEW_PROCESS | event/PARENT/FILE_PATH exists @@ -234,55 +234,55 @@ Combine terms with `and`, `or`, and `not`, and use parentheses to control preced ### Stateful correlation (with child / with descendant / with events) -Stateful operators match an event only when a *related* event also matches a nested filter (given in parentheses after the operator). They scan the whole time range, so scope them tightly (see [Query Types](query-limits-and-performance.md#query-types)). +Stateful operators match an event only when a *related* event also matches a nested filter. You give the nested filter in parentheses after the operator. These operators scan the whole time range, so keep their scope small (see [Query Types](query-limits-and-performance.md#query-types)). -**`with child`** matches when the event has a **direct child** matching the nested filter. For process events, "child" means a directly-spawned process. This query looks for `cmd.exe` directly spawning `calc.exe`: +**`with child`** matches when the event has a **direct child** that matches the nested filter. For process events, "child" means a process that the event spawned directly. This query finds `cmd.exe` that directly spawns `calc.exe`: ```lcql -6h | plat == windows | NEW_PROCESS | event/FILE_PATH ends with "cmd.exe" with child (event/FILE_PATH ends with "calc.exe") ``` -Against the process trees below it matches the first but not the second, because there `calc.exe` is a grandchild, not a direct child: +In the process trees below, the query matches the first tree but not the second. In the second tree, `calc.exe` is a grandchild, not a direct child: ```text cmd.exe --> calc.exe (match) cmd.exe --> firefox.exe --> calc.exe (no match) ``` -**`with descendant`** works exactly like `with child` but matches at **any depth** (child, grandchild, and deeper). Swapping the operator makes both trees above match: +**`with descendant`** works like `with child`, but it matches at **any depth**: child, grandchild, and deeper. If you change the operator, the query matches both trees above: ```lcql -6h | plat == windows | NEW_PROCESS | event/FILE_PATH ends with "cmd.exe" with descendant (event/FILE_PATH ends with "calc.exe") ``` -**`with events`** correlates **proximal events on the same sensor** that need not be in a parent/child relationship - it simply requires that another event matching the nested filter also occurred. This example flags a host that ran a credential-dumping command line and, separately, a lateral-movement tool: +**`with events`** correlates **proximal events on the same sensor**. The events do not need a parent/child relation. Another event that matches the nested filter must also occur. This example finds a host that ran a credential-dumping command line and, separately, a lateral-movement tool: ```lcql -6h | plat == windows | NEW_PROCESS | event/COMMAND_LINE contains "sekurlsa" with events (event/COMMAND_LINE contains "psexec") ``` !!! tip "Repetition thresholds (count / within)" - To match *repeated* events - for example 5 failed logons within 60 seconds - use the `count` and `within` modifiers. Those are available in [D&R stateful rules](../3-detection-response/stateful-rules.md) (YAML), which use the same `with child` / `with descendant` / `with events` model and include additional sample data. + To match *repeated* events, for example 5 failed logons in 60 seconds, use the `count` and `within` modifiers. These modifiers are available in [D&R stateful rules](../3-detection-response/stateful-rules.md) (YAML). Those rules use the same `with child` / `with descendant` / `with events` model, and they give more sample data. ### Target specific sensors -The sensor field accepts `*` (whole org), a [Sensor Selector](../8-reference/sensor-selector-expressions.md) expression, or a space-separated list of sensor IDs: +The sensor field accepts `*` (the whole organization), a [Sensor Selector](../8-reference/sensor-selector-expressions.md) expression, or a space-separated list of sensor IDs: ```lcql -1h | 1a2b3c4d-1111-2222-3333-444455556666 5f6e7d8c-9999-8888-7777-666655554444 | NEW_PROCESS | event/FILE_PATH ends with ".exe" ``` !!! note "Aggregation functions" - LCQL provides two aggregation functions: `COUNT(...)` (number of matching rows) and `COUNT_UNIQUE(...)` (number of distinct values of a field). There is no `SUM`, `AVG`, `MIN`, or `MAX`. + LCQL has two aggregation functions. `COUNT(...)` gives the number of matching rows. `COUNT_UNIQUE(...)` gives the number of distinct values of a field. There is no `SUM`, `AVG`, `MIN`, or `MAX`. - - Do not wrap a field in `COUNT_UNIQUE` that is also a `GROUP BY` key - the result is always 1. - - Avoid `GROUP BY` on high-cardinality fields (for example a full command line, a file hash, or a raw timestamp). It produces a very large number of groups, is inefficient, and rarely yields useful insight - group by a coarser field instead. + - Do not use `COUNT_UNIQUE` on a field that is also a `GROUP BY` key. The result is always 1. + - Do not use `GROUP BY` on high-cardinality fields, for example a full command line, a file hash, or a raw timestamp. Such a field makes a very large number of groups, is inefficient, and rarely gives useful information. Group by a coarser field instead. --- ## Sorting and Limiting Results -The projection clause supports `ORDER BY(...)` for sorting and `LIMIT N` for capping the result set. These are evaluated after aggregation, so they apply to both raw projections and `GROUP BY` summaries. +The projection clause supports `ORDER BY(...)` to sort the results and `LIMIT N` to cap the result set. They are evaluated after aggregation, so they apply to raw projections and to `GROUP BY` summaries. ### ORDER BY Syntax @@ -291,10 +291,10 @@ ORDER BY( [asc|desc]) ORDER BY() # direction omitted; defaults to ascending ``` -The parentheses are mandatory - they delimit the operator's arguments inside the space-delimited projection clause. Direction keywords are case-insensitive but the canonical form is lowercase `asc` / `desc`. Sort keys may reference either raw selectors (e.g. `event/PORT`) or projection aliases (e.g. `Port`). +The parentheses are mandatory. They delimit the arguments of the operator inside the space-delimited projection clause. Direction keywords are case-insensitive, but the canonical form is lowercase `asc` / `desc`. A sort key can be a raw selector (for example `event/PORT`) or a projection alias (for example `Port`). !!! note - `ORDER BY` currently sorts on a single key. Multi-key sort expressions are not supported by the backend at this time. + `ORDER BY` currently sorts on a single key. The backend does not support multi-key sort expressions at this time. ### LIMIT Syntax @@ -302,7 +302,7 @@ The parentheses are mandatory - they delimit the operator's arguments inside the LIMIT ``` -`LIMIT` caps the number of rows returned. It appears at the end of the projection clause, after any `ORDER BY`. +`LIMIT` caps the number of rows that the query returns. Put it at the end of the projection clause, after any `ORDER BY`. ### Top N Noisiest Destination Ports diff --git a/docs/4-data-queries/query-cli.md b/docs/4-data-queries/query-cli.md index d8d45b40f..c41765f0e 100644 --- a/docs/4-data-queries/query-cli.md +++ b/docs/4-data-queries/query-cli.md @@ -1,49 +1,48 @@ # Query with CLI -The command line interface found in the Python CLI/SDK can be invoked like `limacharlie search` once installed (`pip install limacharlie`). +The command line interface is part of the Python CLI/SDK. Install it with `pip install limacharlie`. Then start it with `limacharlie search`. ## Context -To streamline day to day usage, the first 3 components of the query are set seperatly and remain between queries. - These 3 component can be set through the following commands: +You set the first 3 components of the query separately, and they stay the same between queries. Use these commands to set them: -1. `set_time` to set the timeframe of the query, like `set_time -3h` based on the [ParseDuration()](https://pkg.go.dev/time#ParseDuration) strings. -2. `set_sensors` to set the sensors who's data is queried, like `set_sensors plat == windows`, based on the [sensor selector](../8-reference/sensor-selector-expressions.md) grammar. -3. `set_events` to set the events that should be queried, space separated like `NEW_PROCESS DNS_REQUEST`. This command supports tab completion. +1. Use `set_time` to set the time range of the query, for example `set_time -3h`. The value uses the [ParseDuration()](https://pkg.go.dev/time#ParseDuration) strings. +2. Use `set_sensors` to set the sensors that the query reads, for example `set_sensors plat == windows`. The value uses the [sensor selector](../8-reference/sensor-selector-expressions.md) grammar. +3. Use `set_events` to set the events to query, space separated, for example `NEW_PROCESS DNS_REQUEST`. This command supports tab completion. -Once set, you can specify the last component(s): the Filter, and the Projection. +After you set these components, give the last components: the Filter and the Projection. -Several other commands are avaible to make your job easier: +Other commands are also available: -- `set_limit_event` to set a maximum number of events to scan during the query. -- `set_output` to mirror the queries and their results to a file. -- `set_format` to display results either in `json` or `table`. -- `stats` to display the total costs incurred from the queries during this session. +- Use `set_limit_event` to set the maximum number of events to scan in the query. +- Use `set_output` to copy the queries and their results to a file. +- Use `set_format` to show the results in `json` or `table` format. +- Use `stats` to show the total cost of the queries in this session. ## Querying ### Paged Mode -The main method of running a query as described above (in paged mode) is to use the `q` (for "query") command. +To run a query in paged mode, as described above, use the `q` (for "query") command. -Paged mode means that an initial subset of the results will be returned (usually in the 1000s of elements) and if you want to fetch more of the results, you can use the `n` (for "next") command to fetch the next page. +In paged mode, the query returns a first subset of the results, usually some thousands of elements. To get more results, use the `n` (for "next") command to fetch the next page. -Some queries cannot be done in paged mode, like queries that do aggregation or queries that use a stateful filter (like `with child`). In those cases, all results over the entire timeline are computed. +Some queries cannot run in paged mode: queries that do aggregation, and queries that use a stateful filter such as `with child`. For these queries, all results over the entire timeline are computed. For example: `q event/DOMAIN_NAME contains 'google' | event/DOMAIN_NAME as domain COUNT_UNIQUE(routing/sid) as count GROUP BY(domain)` -This command supports tab completion for elements of the query, like `event/DO` + "tab" will suggest `event/DOMAIN_NAME` or other relevant elements that exist as part of the schema. +This command supports tab completion for elements of the query. For example, `event/DO` + "tab" suggests `event/DOMAIN_NAME` or other elements in the schema. ### Non Paged Mode -You can also force a full query over all the data (no paging) by using the "query all" (`qa`) command like: +To force a full query over all the data, with no paging, use the "query all" (`qa`) command: `qa event/DOMAIN_NAME contains 'google' | event/DOMAIN_NAME as domain COUNT_UNIQUE(routing/sid) as count GROUP BY(domain)` ### Dry Run -To simulate running a query, use the `dryrun` command. This will query the LimaCharlie API and return to you an aproximate worst case cost for the query (assuming you fetch all pages over its entire time range). +To simulate a query, use the `dryrun` command. The command queries the LimaCharlie API and returns an approximate worst-case cost for the query. The cost assumes that you fetch all pages over the entire time range. For example: `dryrun event/COMMAND_LINE contains "powershell" and event/FILE_PATH not contains "powershell"` diff --git a/docs/4-data-queries/query-console-ui.md b/docs/4-data-queries/query-console-ui.md index 90e30495f..370c0a793 100644 --- a/docs/4-data-queries/query-console-ui.md +++ b/docs/4-data-queries/query-console-ui.md @@ -1,73 +1,73 @@ -To view and operate the Query Console, the following permissions are required: +You need these permissions to see and use the Query Console: -- `insight.evt.get` for search -- `org.get` for schema service access -- `query.set` for saving queries -- `query.get` for reading a list of queries (if you don't have this set you will see an error saying you need `query.get.mtd`, but this is the permission you need) -- `query.del` for editing or deleting queries (editing is creating a new one and removing the old one) +- `insight.evt.get` to search +- `org.get` to use the schema service +- `query.set` to save queries +- `query.get` to read a list of queries (if you do not have this permission, an error tells you that you need `query.get.mtd`, but `query.get` is the permission that you need) +- `query.del` to edit or delete queries (an edit creates a new query and removes the old one) ### UI Element Overview ![Annotated overview of the Query Console interface with numbered UI elements](../assets/images/query-console-overview.png) -1. **Source:** Select Events (everything that had been injected from endpoints and XDR sources, default), Detections, or Platform Audit events as the data source for the search. +1. **Source:** Select the data source for the search: Events (all data that comes from endpoints and XDR sources, the default), Detections, or Platform Audit events. -2. **Query editor:** Enter a LimaCharlie Query Language (LCQL) query to include: +2. **Query editor:** Enter a LimaCharlie Query Language (LCQL) query. The query includes: - 1. *Sensor Selector -* precisely define the sensors that produced the desired events. - 2. *Event Type* - filter results to only return specific types of events. - 3. Filter - the actual query filter using individual fields and operations on top of them. - 4. Projections (optional) - control output columns, sort results via `ORDER BY` and/or aggregate the data with `GROUP BY` , `COUNT`, `COUNT_UNIQUE` and more. See LCQL reference and Examples for details. + 1. *Sensor Selector -* define the exact sensors that produced the events that you want. + 2. *Event Type* - filter the results to only specific types of events. + 3. Filter - the query filter. It uses individual fields and operations on those fields. + 4. Projections (optional) - control the output columns, sort the results with `ORDER BY`, and aggregate the data with `GROUP BY`, `COUNT`, `COUNT_UNIQUE`, and more. See the LCQL reference and Examples for details. -3. **Time period:** Set the searchable time period using three options: last [time period], around [time frame], and absolute "from start→to finish". +3. **Time period:** Set the time period to search. There are three options: last [time period], around [time frame], and absolute "from start→to finish". ![Event Type - filter results to only return specific types of events](../assets/images/image(340).png) - - Enter a time `16:00`, or day and time `2025-01-16 08:52:54`, using most common time formats. For example: + - Enter a time `16:00`, or a day and time `2025-01-16 08:52:54`. The field accepts most common time formats. For example: - From `33m` to `now` - last 33 minutes - - Around `2025-01-16 08:52:54` +- `15 minutes` - 15 minutes before and after the specified time stamp + - Around `2025-01-16 08:52:54` +- `15 minutes` - 15 minutes before and after the given time stamp - From `10am` to `1:30pm` - **Note:** All times are shown according to the timezone selected by the user in User Settings. + **Note:** All times use the timezone that you select in User Settings. 4. **Available Fields:** Managed data exploration - 1. Schema fields - a list of all the fields associated with ingested events. - 2. Event types - event types present in the returned portion of the query. As more data is churned to complete the specified time frame more event types may appear. - 3. Query fields - event fields present in the *portion of the result already fetched by the query*, with a count of total occurrences. Clicking on the event field opens a details panel. From here you can add a term to the query. + 1. Schema fields - a list of all the fields in ingested events. + 2. Event types - the event types in the part of the results that the query returned. More event types can appear as the query churns more data to complete the selected time frame. + 3. Query fields - the event fields in the *part of the result that the query fetched*, with a count of total occurrences. Click an event field to open a details panel. In this panel, you can add a term to the query. ![Schema fields - a list of all the fields associated with ingested events](../assets/images/image(341).png) - 4. Table columns: control the columns displayed in Table View. + 4. Table columns: control the columns that Table View shows. - Note: While the schema fields are always available, the event types and query fields are only shown for portion of the time frame *searched so far*. As more data is churned in the background (to complete your selected time frame), more event types and fields may appear. + Note: The schema fields are always available. But the event types and query fields show only the part of the time frame *searched so far*. As the query churns more data in the background (to complete your selected time frame), more event types and fields can appear. -5. **Query status:** Shows the state of your query in real time, highlighting any existing syntax errors or providing a cost estimate if the query is properly formed. +5. **Query status:** Shows the state of your query in real time. It shows syntax errors, or a cost estimate if the query is correct. - As the query runs the status displays progress, query status, and a running total of the cost accrued. + When the query runs, the status shows the progress, the query status, and a running total of the cost. - *Query cost estimation:* Queries are charged by the amount of data churned, measured and billed per 200,000 events evaluated. This estimation shows the "at most" cost of a query for the selected time range. Only retrieved data is chargeable. + *Query cost estimation:* The charge for a query depends on the amount of data churned. LimaCharlie measures and bills this for each 200,000 events evaluated. The estimate shows the maximum cost of a query for the selected time range. Only retrieved data is chargeable. - *Performance tuning:* The better tuned the query, the faster the search and lower the cost. Using Sensor Selector and Event Type to precisely target the desired telemetry will increase search speeds and lower costs. + *Performance tuning:* A better tuned query is faster and costs less. Use the Sensor Selector and the Event Type to target the exact telemetry that you want. This increases the search speed and lowers the cost. 6. **Histogram:** - When a search is run, a histogram appears below the query field showing the distribution of events over time. The portion with a vertical bar chart represents results that have been retrieved so far. The non-bar chart portion shows the total number of events in the selected time frame. The histogram shows the progress of the search through the time frame. As you paginate through the search, more events are evaluated, and more bars appear to signify the progress through the time frame. + When you run a search, a histogram appears below the query field. The histogram shows the distribution of events over time. The part with the vertical bars shows the results that the search retrieved so far. The part without bars shows the total number of events in the selected time frame. The histogram shows the progress of the search through the time frame. When you paginate through the search, the query evaluates more events and more bars appear. -7. **Search results:** displays results in two views, **timeline** and **table**. Timeline view shows matching events with the most recent on top. Table view provides a way to sort results into desired columns. Find the desired field in Query Fields and use the `pin` icon to add it as a column. +7. **Search results:** Shows the results in two views, **timeline** and **table**. Timeline view shows the matching events with the most recent at the top. Table view sorts the results into the columns that you want. Find the field in Query Fields, then use the `pin` icon to add it as a column. - 1. A **Tab Columns** section appears in the **Fields** sidebar when table view is selected. Columns can be viewed or removed here. - 2. **Event Details** allows you to click on an event and perform applicable event actions like **Build a D&R Rule**. - 3. **Download** all the events you've retrieved in a [.ndjson format](https://github.com/ndjson/ndjson-spec). The automatic download of the entire time range is coming soon. + 1. A **Tab Columns** section appears in the **Fields** sidebar when you select table view. In this section, you can see or remove the columns. + 2. **Event Details** lets you click an event and do the event actions that apply, such as **Build a D&R Rule**. + 3. **Download** all the events that you retrieved in the [.ndjson format](https://github.com/ndjson/ndjson-spec). The automatic download of the full time range is coming soon. ![A Tab Columns section appears in the Fields sidebar when table view is selected](../assets/images/image(342).png) -8. **Saving Queries and Query Library.** A query can be saved in your private user library or shared via an org library. Use the library to browse queries and load the desired one to the query editor. +8. **Saving Queries and Query Library.** You can save a query in your private user library, or share it through an org library. Use the library to browse queries and load the one that you want into the query editor. -9. **Progress indicator:** The status line shows how much of the query has completed so far (for example, `11% scanned`). For whole-timeline queries such as aggregations, sorting, and other stateful operations, this value climbs as more of the selected time range is processed. See [Query Limits & Performance](query-limits-and-performance.md#query-progress-and-cost-reporting) for details on how progress and cost are reported. +9. **Progress indicator:** The status line shows how much of the query is complete (for example, `11% scanned`). For whole-timeline queries such as aggregations, sorting, and other stateful operations, this value increases as the query processes more of the selected time range. See [Query Limits & Performance](query-limits-and-performance.md#query-progress-and-cost-reporting) for details about how progress and cost are reported. -10. **Search details (info icon):** Hovering the info icon at the end of the status line opens a **Search Details** panel with per-session and per-page timings (wall, server, total work, cost, and pages) and a completion breakdown (progress, batches completed vs. in scope, events, and data). It also shows the query's **Query ID**, which you can copy and share with LimaCharlie support when reporting an issue with a query so troubleshooting is faster. +10. **Search details (info icon):** Hold the pointer on the info icon at the end of the status line to open a **Search Details** panel. The panel shows per-session and per-page timings (wall, server, total work, cost, and pages). It also shows a completion breakdown (progress, batches completed compared to batches in scope, events, and data). The panel also shows the **Query ID** of the query. Copy the Query ID and send it to LimaCharlie support when you report a problem with a query, so that troubleshooting is faster. ![Search Details panel showing per-session and per-page timings, a completion breakdown, and the Query ID](../assets/images/query-console-search-details.png) diff --git a/docs/4-data-queries/query-limits-and-performance.md b/docs/4-data-queries/query-limits-and-performance.md index 9f4e154c3..4a9729ab0 100644 --- a/docs/4-data-queries/query-limits-and-performance.md +++ b/docs/4-data-queries/query-limits-and-performance.md @@ -1,121 +1,121 @@ # Query Limits & Performance -This page describes the operational limits that apply to Query Console and LCQL searches - how many queries you can run at once and how long a query may run - along with guidance on how large an aggregation can reasonably get and how to write efficient queries that stay within those limits and cost less. It also covers the different query types, since how a query executes determines how it behaves against these limits. +This page describes the operational limits for the Query Console and for LCQL searches. The limits control how many queries you can run at the same time and how long a query can run. This page also gives guidance about how large an aggregation can be. It shows how to write efficient queries that stay inside the limits and cost less. It also describes the query types, because the way that a query executes decides how the query behaves against these limits. ## Query Types -How a query executes - and therefore how it behaves against the limits below - depends on what it does. LCQL queries fall into four kinds: +The way that a query executes depends on what the query does. This also decides how the query behaves against the limits below. There are four kinds of LCQL query: | Query type | What it does | Execution | |------------|--------------|-----------| -| **Stateless** | Evaluates each event independently against the filter and returns the matching events. This is the default. | Paged: results come back a page at a time, and you fetch more on demand. | -| **Projection** | Adds a projection clause at the end of the query to return only selected or renamed fields instead of whole events. | Paged, as long as it only selects or renames fields; `GROUP BY`, `ORDER BY`, or an aggregation function make it whole-timeline. | -| **Aggregation** | Uses aggregation functions in the projection (`COUNT`, `COUNT_UNIQUE`, `GROUP BY`, and similar) to summarize matching events. | Whole timeline: the entire selected time range is scanned before any result is returned. | -| **Stateful** | Uses a filter that correlates across events, such as `with child`, so a match depends on more than one event. | Whole timeline: the entire selected time range is scanned before any result is returned. | +| **Stateless** | Evaluates each event on its own against the filter and returns the matching events. This is the default. | Paged: the results come back one page at a time, and you fetch more pages on demand. | +| **Projection** | Adds a projection clause at the end of the query. The query returns only selected or renamed fields, not whole events. | Paged, if it only selects or renames fields. `GROUP BY`, `ORDER BY`, or an aggregation function make it whole-timeline. | +| **Aggregation** | Uses aggregation functions in the projection (`COUNT`, `COUNT_UNIQUE`, `GROUP BY`, and similar) to summarize matching events. | Whole timeline: the query scans the full selected time range before it returns a result. | +| **Stateful** | Uses a filter that correlates across events, such as `with child`, so a match depends on more than one event. | Whole timeline: the query scans the full selected time range before it returns a result. | -**Paged** queries (a stateless filter, or a projection that only selects fields) stream results incrementally and rarely run long. **Whole-timeline** queries (anything that sorts, groups, aggregates, or correlates across events) must scan the full range before returning, so they consume the most resources and are the ones that can reach the [query timeout](#query-timeouts). +**Paged** queries (a stateless filter, or a projection that only selects fields) return the results in increments and seldom run long. **Whole-timeline** queries sort, group, aggregate, or correlate across events. They must scan the full range before they return a result. They use the most resources, and they are the queries that can reach the [query timeout](#query-timeouts). ## Data Sources (Streams) -Every query runs against one data *stream*, chosen with the Source dropdown in the Query Console or the `stream` parameter in the API, CLI, and SDKs. The stream determines which kind of records the query scans: +Every query runs against one data *stream*. Select the stream with the Source dropdown in the Query Console, or with the `stream` parameter in the API, CLI, and SDKs. The stream decides which kind of records the query scans: | Stream | Console label | Contains | |--------|---------------|----------| -| `event` | Events | Raw telemetry collected from endpoints, adapters, and other sensors. This is the default. | -| `detection` | Detections | Detections produced by your D&R rules. | +| `event` | Events | Raw telemetry from endpoints, adapters, and other sensors. This is the default. | +| `detection` | Detections | Detections that your D&R rules produce. | | `audit` | Platform Audit | Platform audit records, such as configuration changes and user actions. | -A query only sees data from the stream it targets - a query on the `event` stream will not match detections, and vice versa. When the `stream` parameter is omitted it defaults to `event`. If a query returns nothing you expected to see, confirm you are searching the intended stream. +A query only sees data from the stream that it targets. A query on the `event` stream does not match detections, and a query on the `detection` stream does not match events. If you do not give the `stream` parameter, the default is `event`. If a query does not return the data that you expect, make sure that you search the correct stream. ## Concurrent Queries -Each organization can run several queries at the same time. Every organization is guaranteed a minimum of **10 concurrent queries**, and the effective limit may be higher depending on your region and plan. +Each organization can run several queries at the same time. Every organization gets a minimum of **10 concurrent queries**. The true limit can be higher, and depends on your region and plan. -Both interactive Query Console searches and searches issued through the API, CLI, or SDKs count toward this limit. A paginated query counts as active for the entire time it is fetching pages, not only at the moment it starts. +Query Console searches and searches from the API, CLI, or SDKs both count against this limit. A paginated query is active for all the time that it fetches pages, not only when it starts. -When the limit is reached, additional queries are rejected with an `HTTP 429` (too many concurrent queries) response until one of the in-flight queries finishes. Retry the rejected query once an earlier one completes. +When you reach the limit, the cloud rejects more queries with an `HTTP 429` (too many concurrent queries) response. This continues until one of the queries in flight finishes. Retry the rejected query after an earlier query completes. !!! tip - If you regularly run automation or dashboards that need more headroom, contact support to request a higher concurrent-query limit for your organization. + Contact support to ask for a higher concurrent-query limit for your organization. Do this if you run automation or dashboards that need more capacity. ## Query Timeouts -A single query has a maximum execution time of roughly **8 to 9 minutes**. If a query exceeds this deadline it returns an error rather than partial results. +A single query has a maximum execution time of about **8 to 9 minutes**. If a query goes past this deadline, it returns an error and not partial results. -**Paged queries (a stateless filter or a field-only projection).** Each page fetches a bounded number of events and returns quickly, so paged queries should effectively never reach the timeout. When you need more results, fetch the next page rather than trying to widen a single request. +**Paged queries (a stateless filter or a field-only projection).** Each page fetches a limited number of events and returns quickly. Because of this, a paged query almost never reaches the timeout. When you need more results, fetch the next page. Do not make one request wider. -**Whole-timeline queries (sorting, aggregation, and stateful).** Sorting (`ORDER BY`), aggregations (`COUNT`, `COUNT_UNIQUE`, `GROUP BY`), and stateful filters (such as `with child`) must scan the entire selected time range before they can return results, because the outcome is only complete once every matching event has been evaluated. Over a very large time range or a high volume of data, the scan can exceed the timeout and the query returns an error. See [Query Types](#query-types) for the distinction. +**Whole-timeline queries (sorting, aggregation, and stateful).** Sorting (`ORDER BY`), aggregations (`COUNT`, `COUNT_UNIQUE`, `GROUP BY`), and stateful filters (such as `with child`) must scan the full selected time range before they return results. The result is complete only after the query evaluates every matching event. On a very large time range, or with a high volume of data, the scan can go past the timeout and the query returns an error. See [Query Types](#query-types) for the difference between the query types. !!! note "Working around whole-timeline timeouts" - If a large aggregation times out, narrow the time range and split the work into several smaller queries that each cover an incremental slice of the range, then combine the results yourself. + If a large aggregation times out, make the time range smaller. Split the work into several smaller queries. Each query covers one slice of the range. Then combine the results yourself. - For example, instead of a single 24-hour aggregation, run the same aggregation over 24 consecutive one-hour windows and add the per-window counts together for the full-range total. Keep the query identical and only change the time range for each run: + For example, do not run one 24-hour aggregation. Run the same aggregation over 24 one-hour windows, then add the counts of the windows together to get the total for the full range. Keep the query the same and change only the time range for each run: ```lcql plat == windows | WEL | event/EVENT/System/EventID == "4625" | COUNT(event) as FailedAttempts ``` - Each one-hour window stays well under the timeout. Set the time range per run using the Console time picker (absolute from/to), the CLI `set_time`, or the API `startTime` / `endTime` parameters. + Each one-hour window stays well below the timeout. Set the time range for each run with the Console time picker (absolute from/to), the CLI `set_time`, or the API `startTime` / `endTime` parameters. - Splitting and summing works for additive aggregations like `COUNT`; a `COUNT_UNIQUE` result cannot simply be added across windows. For stateful queries (`with child`), narrow the scope instead, since splitting can miss correlations that span a window boundary. + You can split and add additive aggregations such as `COUNT`. But you cannot add a `COUNT_UNIQUE` result across windows. For stateful queries (`with child`), make the scope smaller instead, because a split can miss correlations that cross a window boundary. ## Aggregation Limits -Aggregations build in-memory groupings as they scan, so very high-cardinality aggregations become slow and unreliable. Treat the following as recommended guardrails for dependable results: +An aggregation builds groups in memory as it scans. Thus an aggregation with very high cardinality becomes slow and unreliable. Use these values as guardrails for dependable results: - `GROUP BY` distinct groups: keep well under **~1,000,000** distinct groups. - `COUNT_UNIQUE` distinct values per field per group: keep well under **~5,000,000** distinct values. -The usual cause of blowing past these numbers is grouping by a near-unique field (see [Anti-patterns](#anti-patterns) below). Group by a coarser field, or narrow the scope, so the number of groups stays bounded. +The usual cause of a value above these numbers is a query that groups by a near-unique field (see [Anti-patterns](#anti-patterns) below). Group by a coarser field, or make the scope smaller, to keep the number of groups limited. !!! tip - Add `ORDER BY(...) LIMIT N` to bound the output, and project only the fields you need to shrink each row. See [Writing Efficient and Performant Queries](#writing-efficient-and-performant-queries) below. + Add `ORDER BY(...) LIMIT N` to limit the output. Project only the fields that you need, to make each row smaller. See [Writing Efficient and Performant Queries](#writing-efficient-and-performant-queries) below. ## Query Progress and Cost Reporting -Because a query can scan a large amount of data, the API reports both a pre-flight estimate before you run it and the actual progress and cost as results stream back. A query scans stored telemetry in discrete units called *batches*; the batch counts below are what drive a progress bar. +A query can scan a large amount of data. Because of this, the API reports an estimate before you run the query, and the true progress and cost while the results come back. A query scans stored telemetry in separate units that are called *batches*. The batch counts below drive a progress bar. ### Pre-flight estimate (validate) -The [validate endpoint](index.md#validate-query-syntax) returns an estimate of how much work a query represents before you run it: +The [validate endpoint](index.md#validate-query-syntax) returns an estimate of the work of a query before you run it: -- `batchesInScope` - the total number of batches the query will scan. This is the denominator for a progress bar. +- `batchesInScope` - the total number of batches that the query scans. This is the denominator for a progress bar. - `eventsInScope` / `bytesInScope` - the estimated number of events and bytes in scope. -- `estimatedPrice` - the estimated cost, derived from the events in scope. +- `estimatedPrice` - the estimated cost, from the events in scope. ### Progress while paging -Each page of a running search reports how much of the query is complete so far in its `cumulativeStats`: +While a search runs, each page reports how much of the query is complete in its `cumulativeStats`: -- `batchesInScope` - the total batches in scope (denominator); the same value for every page of the search. -- `batchesCompleted` - the batches processed so far across all pages (numerator). +- `batchesInScope` - the total batches in scope (denominator). This value is the same for every page of the search. +- `batchesCompleted` - the batches that the query processed so far across all pages (numerator). -Render progress as `batchesCompleted / batchesInScope`, clamped to 0-100%. This is exactly how the Query Console progress bar is computed. The per-page `batchesProcessed` field reports the batches handled by that single page. Byte- and event-weighted ratios (`bytesScanned / bytesInScope`, `eventsScanned / eventsInScope`) are also available as a smoother signal, but the batch ratio is the reliable one; guard against a zero denominator. +Show the progress as `batchesCompleted / batchesInScope`, clamped to 0-100%. The Query Console computes its progress bar in this way. The per-page `batchesProcessed` field reports the batches of that one page. Byte and event ratios (`bytesScanned / bytesInScope`, `eventsScanned / eventsInScope`) are also available and give a smoother signal. But the batch ratio is the reliable one. Guard against a denominator of zero. ### Actual cost per page -Every page also returns the actual billing for the data it processed, so you do not have to trust the estimate for cost: +Every page also returns the true billing for the data that it processed. Thus you do not have to trust the estimate for the cost: -- `billedEvents` / `freeEvents` - the events on this page that were billed versus covered by a free-tier window (`billedEvents + freeEvents == eventsScanned`). -- `estimatedPrice` - the price for this page, derived from the actual `billedEvents`. The running totals across all pages are carried in `cumulativeStats`. +- `billedEvents` / `freeEvents` - the events on this page that are billed, compared to the events that a free-tier window covers (`billedEvents + freeEvents == eventsScanned`). +- `estimatedPrice` - the price for this page, from the true `billedEvents`. The `cumulativeStats` field carries the running totals across all pages. !!! warning "Estimates are approximate - rely on the per-page billing for cost" - The pre-flight `estimatedPrice`, `eventsInScope`, and related validate estimates are approximations. Their accuracy varies with the query type and with internal optimizations that reduce how much data actually has to be scanned, which are not always reflected in the estimate. Treat the estimate as a planning aid only and never rely on it as the exact cost. The authoritative cost is the actual billing (`billedEvents` and the `estimatedPrice` derived from it) returned with each page and accumulated in `cumulativeStats`. + The pre-flight `estimatedPrice`, `eventsInScope`, and the related validate estimates are approximations. Their accuracy changes with the query type and with internal optimizations that decrease how much data the query must scan. The estimate does not always include these optimizations. Use the estimate only to plan, and never as the exact cost. The authoritative cost is the true billing (`billedEvents` and the `estimatedPrice` from it). Each page returns this billing, and `cumulativeStats` accumulates it. ### Building a Progress Bar -The Query Console renders its progress bar with this formula: +The Query Console draws its progress bar with this formula: ```text progress = clamp(batchesCompleted / batchesInScope, 0, 100%) ``` -Use `batchesInScope` as the denominator - from the [validate response](#pre-flight-estimate-validate) before the search starts, or from each page's `cumulativeStats` once it is running - and the per-page `cumulativeStats.batchesCompleted` as the numerator. Two rules keep the bar well-behaved: +Use `batchesInScope` as the denominator. Get this value from the [validate response](#pre-flight-estimate-validate) before the search starts, or from the `cumulativeStats` of each page after the search starts. Use the per-page `cumulativeStats.batchesCompleted` as the numerator. Two rules keep the bar correct: -- **Guard the denominator.** `batchesInScope` is `0` (or absent) until the scope is known, so treat progress as unavailable rather than dividing by zero. -- **Clamp the ratio.** `batchesCompleted` can briefly exceed `batchesInScope` when a batch is re-opened across page boundaries, so clamp to 100%. A page's `completed` flag is the authoritative "done" signal. +- **Guard the denominator.** `batchesInScope` is `0` (or absent) until the scope is known. Show the progress as unavailable. Do not divide by zero. +- **Clamp the ratio.** `batchesCompleted` can be more than `batchesInScope` for a short time when a batch is re-opened across page boundaries. Clamp the value to 100%. The `completed` flag of a page is the authoritative "done" signal. -The examples below take one Search API page response (a parsed `SearchResponse`) and return a percentage in the range 0-100. +The examples below take one Search API page response (a parsed `SearchResponse`). They return a percentage in the range 0-100. === "Python" @@ -152,29 +152,29 @@ The examples below take one Search API page response (a parsed `SearchResponse`) end' ``` -See [Run an LCQL Query](index.md#run-an-lcql-query) for how to discover `$SEARCH_HOST` and obtain a JWT. +See [Run an LCQL Query](index.md#run-an-lcql-query) to find `$SEARCH_HOST` and get a JWT. ## Writing Efficient and Performant Queries -Query cost is measured by the amount of data churned (billed per 200,000 events evaluated), and speed tracks the same factor: the fewer events a query has to scan and the less data it has to return, the faster and cheaper it is. The patterns below reduce both. +The cost of a query depends on the amount of data churned (billed for each 200,000 events evaluated). The speed depends on the same factor. A query that scans fewer events and returns less data is faster and costs less. The patterns below improve both the speed and the cost. ### Prefer Projections (Select Only the Fields You Need) -By default a query returns whole events. Adding a projection clause (the segment after the final `|`) returns only the fields you name, which reduces the data transferred, speeds up the query, and lowers cost. +By default, a query returns whole events. A projection clause (the segment after the last `|`) returns only the fields that you name. This decreases the data transferred, makes the query faster, and lowers the cost. -Non-aggregation query. Instead of returning every field of each matching event: +Non-aggregation query. This query returns every field of each matching event: ```lcql -1h | * | NETWORK_CONNECTIONS | event/PORT > 1000 ``` -project just the two fields you actually care about: +Project only the two fields that you need: ```lcql -1h | * | NETWORK_CONNECTIONS | event/PORT > 1000 | event/IP_ADDRESS as IP event/PORT as Port ``` -Aggregation query. Projections also define what an aggregation emits. This returns only the source IP and its failed-logon count, sorted and capped: +Aggregation query. A projection also defines what an aggregation returns. This query returns only the source IP and its count of failed logons, sorted and capped: ```lcql -24h | plat == windows | WEL | event/EVENT/System/EventID == "4625" | event/EVENT/EventData/IpAddress as SourceIP COUNT(event) as FailedAttempts GROUP BY(SourceIP) ORDER BY(FailedAttempts desc) LIMIT 50 @@ -182,62 +182,62 @@ Aggregation query. Projections also define what an aggregation emits. This retur ### Narrow the Scope Early -Restrict what the query has to scan before it reaches the filter: +Limit the data that the query scans before it reaches the filter: -- Use the [Sensor Selector](../8-reference/sensor-selector-expressions.md) instead of `*` so only relevant sensors are searched (see below). -- Set the Event Type to the specific events you need rather than searching all event types. -- Use the tightest time range that answers your question. +- Use the [Sensor Selector](../8-reference/sensor-selector-expressions.md) and not `*`, so that the query searches only the applicable sensors (see below). +- Set the Event Type to the specific events that you need. Do not search all event types. +- Use the smallest time range that answers your question. -Each of these lowers the number of events churned, which makes the query both faster and cheaper. +Each of these decreases the number of events churned. This makes the query faster and cheaper. -**Targeting sensors by ID.** When you know exactly which sensors you care about, matching on `sid` is the most efficient selector of all, because it narrows the scan to specific sensors before any events are read: +**Targeting sensors by ID.** A match on `sid` is the most efficient selector. Use it when you know the exact sensors that you want. It limits the scan to specific sensors before the query reads any events: - A single sensor: `sid == ""`. - A specific set of sensors: combine terms with `or`, as in `sid == "" or sid == "" or sid == ""`. -When you do not know the IDs, select by attribute instead - for example `plat == windows`, `"prod" in tags`, or by `hostname`. Sensor IDs are UUIDs, and a selector value that starts with a number must be backtick-quoted; see the [Sensor Selector reference](../8-reference/sensor-selector-expressions.md) for the full operator list and quoting rules. +When you do not know the IDs, select by attribute - for example `plat == windows`, `"prod" in tags`, or `hostname`. Sensor IDs are UUIDs. You must put backticks around a selector value that starts with a number. See the [Sensor Selector reference](../8-reference/sensor-selector-expressions.md) for the full list of operators and the rules for quotes. ### Bound Output with ORDER BY and LIMIT -For "top N" style questions, always add `ORDER BY(...) LIMIT N` so the result set is capped instead of returning every matching row. See [Sorting and Limiting Results](lcql-examples.md#sorting-and-limiting-results) for the full syntax. +For "top N" questions, always add `ORDER BY(...) LIMIT N`. This caps the result set, and the query does not return every matching row. See [Sorting and Limiting Results](lcql-examples.md#sorting-and-limiting-results) for the full syntax. ### Aggregate Instead of Pulling Raw Events -When you only need counts or summaries, use `COUNT`, `COUNT_UNIQUE`, and `GROUP BY` rather than downloading raw events and counting them yourself. Aggregating in the query returns a small summary instead of a large event stream. +When you need only counts or summaries, use `COUNT`, `COUNT_UNIQUE`, and `GROUP BY`. Do not download raw events and count them yourself. An aggregation in the query returns a small summary and not a large stream of events. ### Split Large Aggregations -If an aggregation over a wide time range is slow or times out, break it into smaller incremental time windows and combine the results, as described in [Working around whole-timeline timeouts](#query-timeouts) above. +If an aggregation over a wide time range is slow or times out, divide it into smaller time windows and combine the results. [Working around whole-timeline timeouts](#query-timeouts) above describes this method. ### Anti-patterns !!! warning "Avoid these patterns" - - `*` sensor selector with no Event Type filter over a wide time range - this scans everything and is the slowest, most expensive shape of query. - - Returning whole events when you only need a few fields - add a projection instead. - - Grouping by a near-unique field such as a full command line, a raw timestamp, or a per-event identifier - this produces millions of groups and blows past the aggregation guardrails. Group by a coarser field. - - Unbounded aggregations with no `LIMIT` - cap the output with `ORDER BY(...) LIMIT N`. + - Do not use the `*` sensor selector with no Event Type filter over a wide time range. This query scans everything, and it is the slowest and most expensive query. + - Do not return whole events when you need only a few fields. Add a projection. + - Do not group by a near-unique field such as a full command line, a raw timestamp, or a per-event identifier. This makes millions of groups and goes past the aggregation guardrails. Group by a coarser field. + - Do not run an aggregation with no `LIMIT`. Cap the output with `ORDER BY(...) LIMIT N`. ## Troubleshooting ### The query is rejected before it runs -[Validate the query](index.md#validate-query-syntax) first - the validate endpoint reports syntax errors without scanning any data. Common causes: +[Validate the query](index.md#validate-query-syntax) first. The validate endpoint reports syntax errors and does not scan any data. Common causes: -- **Field paths use `/`, not dots.** Write `event/FILE_PATH`, not `event.FILE_PATH`. Nested fields chain with slashes, as in `event/PARENT/FILE_PATH`. +- **Field paths use `/`, not dots.** Write `event/FILE_PATH`, not `event.FILE_PATH`. Nested fields join with slashes, as in `event/PARENT/FILE_PATH`. - **A selector value that starts with a number must be backtick-quoted**, for example `` plat == `1password` ``. - **Projection and aggregation go in the final clause**, after the last `|`. See [LCQL Examples](lcql-examples.md). ### The query returns no results -- **Wrong stream.** A query only sees the stream it targets. If you expected detections, query the `detection` stream rather than `event`. See [Data Sources (Streams)](#data-sources-streams). -- **Time range.** Confirm the range actually covers the data. In the Query Console, times use the timezone from your User Settings; API, CLI, and SDK times are Unix epoch seconds. -- **Selector too narrow.** An overly specific Sensor Selector or Event Type can exclude the data you want - widen it and re-run. -- **Field name.** A misspelled or non-existent field simply never matches. Use the Available Fields panel or the [event schema](../8-reference/event-schemas.md) to confirm field names. +- **Wrong stream.** A query only sees the stream that it targets. If you want detections, query the `detection` stream and not the `event` stream. See [Data Sources (Streams)](#data-sources-streams). +- **Time range.** Make sure that the range covers the data. In the Query Console, times use the timezone from your User Settings. API, CLI, and SDK times are Unix epoch seconds. +- **Selector too narrow.** A Sensor Selector or Event Type that is too specific can exclude the data that you want. Make it wider and run the query again. +- **Field name.** A field name with a spelling error, or a field that does not exist, never matches. Use the Available Fields panel or the [event schema](../8-reference/event-schemas.md) to check field names. ### The query is rejected as too busy or times out -- **`HTTP 429` (too many concurrent queries).** You have reached the [concurrent-query limit](#concurrent-queries). Wait for an in-flight query to finish, then retry. -- **Timeout.** Long-running aggregations over large ranges can hit the [query timeout](#query-timeouts). Narrow the range or split the query into smaller windows. +- **`HTTP 429` (too many concurrent queries).** You reached the [concurrent-query limit](#concurrent-queries). Wait for a query in flight to finish, then retry. +- **Timeout.** A long aggregation over a large range can reach the [query timeout](#query-timeouts). Make the range smaller, or divide the query into smaller windows. ## See Also diff --git a/docs/4-data-queries/template-strings.md b/docs/4-data-queries/template-strings.md index c4d72cfd5..1106410c5 100644 --- a/docs/4-data-queries/template-strings.md +++ b/docs/4-data-queries/template-strings.md @@ -2,35 +2,35 @@ Many areas of LimaCharlie support template strings and transforms. -A template string allows you to customize the value of a configuration based on the context. For example to adjust the Detection Name a D&R rule to include a value from the detection itself. Transforms can also be used to select, modify, or remove fields upon data ingestion from an Adapter. +A template string lets you set the value of a configuration from the context. For example, you can add a value from the detection to the Detection Name of a D&R rule. You can also use transforms to select, change, or remove fields when an Adapter ingests data. -A transform allows you to change the shape of JSON data in flight to suit better your usage. This can mean moving, renaming, removing and adding fields in JSON. For example, it can allow you to create an Output that works with `DNS_REQUEST` events, but outputs only specific fields from the event. +A transform changes the shape of JSON data while the data passes through LimaCharlie. You can move, rename, remove, and add fields in the JSON. For example, you can create an Output that works with `DNS_REQUEST` events but sends only specific fields from the event. ## Template Strings Template strings in LimaCharlie use the [Go `text/template` format](https://pkg.go.dev/text/template). [Hashicorp's Go template syntax tutorial](https://learn.hashicorp.com/tutorials/nomad/go-template-syntax) is also a useful reference. -The most basic example for a D&R rule customizing the detection name looks like this: +This example shows a D&R rule that sets the detection name: ```yaml - action: report name: Evil executable on {{ .routing.hostname }} ``` -Template strings also support some LimaCharlie-specific functions: +Template strings also support functions that are specific to LimaCharlie: -- `token`: applies an MD5 hashing function on the value provided. -- `anon`: applies an MD5 hashing function on a secret seed value, plus the value provided. -- `json`: marshals the input into a JSON string representation. -- `prettyjson`: same as `json` but with indentation and newlines. -- `parsetime`: parse a time format to another. -- `split`: split a string based on a seperator param. -- `join`: join a list into a string joined by another string. -- `replace`: replace all string into the other. -- `base`: return the file name in a file path. -- `dir`: return the base directory path from a file path. +- `token`: applies an MD5 hash function to the value that you supply. +- `anon`: applies an MD5 hash function to a secret seed value plus the value that you supply. +- `json`: converts the input into a JSON string. +- `prettyjson`: the same as `json`, but with indentation and newlines. +- `parsetime`: converts one time format to another. +- `split`: splits a string on a separator parameter. +- `join`: joins a list into one string with another string between the items. +- `replace`: replaces all instances of one string with another string. +- `base`: returns the file name in a file path. +- `dir`: returns the base directory path from a file path. -The `token` and `anon` functions can be used to partially anonymize data anywhere a template string is supported, for example: +Use the `token` and `anon` functions to partly anonymize data. These functions work anywhere that supports a template string. For example: ```yaml - action: report @@ -45,16 +45,16 @@ Other examples: ### Template Strings and Adapter Transforms -Template strings can also be used with in conjunction the `client_options.mapping.transform` option in [Adapter configuration](../2-sensors-deployment/adapters/usage.md). These allow you to modify data prior to ingestion, having control over *what* fields get ingested and resulting field names. +You can also use template strings with the `client_options.mapping.transform` option in the [Adapter configuration](../2-sensors-deployment/adapters/usage.md). This option lets you change data before ingestion. You control *what* fields LimaCharlie ingests and the names of the fields. -The following options are available in Adapter configurations: +Adapter configurations support these options: - `+` to add a field - `-` to remove a field -Both support template strings, meaning you can add/remove values from the JSON data to replace/supplement other fields. +Both options support template strings. You can add values to the JSON data or remove values from it, to replace or supplement other fields. -For example, if we had the following data: +For example, this is the input data: ```json { "event": @@ -67,7 +67,7 @@ For example, if we had the following data: } ``` -And we wanted to rename the `d` value to `c` on ingestion, remove the d value, and add a field called `hostname`, we could use the following configuration: +This configuration renames the `d` value to `c` on ingestion, removes the d value, and adds a field named `hostname`: ```text ... @@ -79,7 +79,7 @@ And we wanted to rename the `d` value to `c` on ingestion, remove the d value, a +hostname : '{{ "my-computer" }}', ``` -The resulting event to be ingested would be: +LimaCharlie then ingests this event: ```json { "event": @@ -97,15 +97,15 @@ The resulting event to be ingested would be: With Transforms, you specify a JSON object that describes the transformation. -This object is in the shape of the final JSON you would like to transform to. +This object has the shape of the final JSON that you want. Key names are the literal key names in the output. Values support one of 3 types: -1. Template Strings, as described above. In this case, the template string will be generated and placed at the same place as the key in the transform object. -2. A `gjson` selector. See the [gjson syntax reference](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) for the selector syntax. It makes it possible to select subsets of input object and map it within the resulting object as defined by the transform. -3. Other JSON objects which will be present in the output. +1. Template Strings, as described above. LimaCharlie generates the template string and puts it at the same place as the key in the transform object. +2. A `gjson` selector. For the selector syntax, see the [gjson syntax reference](https://github.com/tidwall/gjson/blob/master/SYNTAX.md). A selector selects a subset of the input object and maps that subset into the output object that the transform defines. +3. Other JSON objects. These objects are present in the output. -Let's look at an example, let's say this is the Input to our transform: +This is an example Input to a transform: ```json { @@ -186,7 +186,7 @@ Let's look at an example, let's say this is the Input to our transform: } ``` -And this is our Transform definition: +This is the Transform definition: ```json { @@ -201,7 +201,7 @@ And this is our Transform definition: } ``` -Then the resulting Output would be: +The Output is: ```json { @@ -240,7 +240,7 @@ Then the resulting Output would be: ### Transforming Output Data -When passing events to an output, you have the option to transform the original event in multiple ways. When creating an output, Custom Transforms are applied in the CUSTOM TRANSFORM area of the screenshot below. In this example we are transforming a detection event to pass via a custom webhook to a web application. +When you pass events to an output, you can transform the original event in more than one way. When you create an output, apply Custom Transforms in the CUSTOM TRANSFORM area of the screenshot below. This example transforms a detection event and sends it through a custom webhook to a web application. ![Output data transformation settings](../assets/images/image(310).png) @@ -248,7 +248,7 @@ When passing events to an output, you have the option to transform the original #### Extracting Fields from Telemetry -Let's say you have the following 4625 failed logon and you want to send similar events to an output, but only certain fields. +This is a 4625 failed logon event. You want to send events like it to an output, but only some of the fields. ```json { @@ -291,7 +291,7 @@ Let's say you have the following 4625 failed logon and you want to send similar } ``` -The following Output Transform would extract only the `IpAddress`, `TargetUserName`, `EventID`, and `SystemTime` the event was created. Notice, the newly mapped field names can be whatever you want. +This Output Transform extracts only the `IpAddress`, `TargetUserName`, `EventID`, and the `SystemTime` when the event was created. The new field names can be any names that you want. ```json { @@ -302,7 +302,7 @@ The following Output Transform would extract only the `IpAddress`, `TargetUserNa } ``` -The following example outputs text and specified fields using Template Strings. +This example uses Template Strings to output text and specific fields. ```json { @@ -310,7 +310,7 @@ The following example outputs text and specified fields using Template Strings. } ``` -The above example would generate the following output using the provided sample WEL. +With the sample WEL event, the example generates this output. ```json { @@ -320,9 +320,9 @@ The above example would generate the following output using the provided sample ### Output as String / Passthrough -The `custom_transform` in outputs can also be used to output pure text (non-JSON) from LimaCharlie. This is useful if, for example, you are ingesting syslog data, and want to forward this syslog data as-is to something else. +You can also use the `custom_transform` field in outputs to send pure text (non-JSON) from LimaCharlie. For example, you ingest syslog data and want to forward that syslog data unchanged to another system. -This is accomplished by specifying a Template String in the `custom_transform` field instead of a Transform. In those cases, when LimaCharlie determines the `custom_transform` string is not a valid Transform, it will interpret it as a Template String like: +To do this, put a Template String in the `custom_transform` field instead of a Transform. If LimaCharlie finds that the `custom_transform` string is not a valid Transform, it reads the string as a Template String: ```json { @@ -340,16 +340,15 @@ or ### Custom Modifiers -Beyond the built-in modifiers for `gjson` (as seen in their [playground](https://gjson.dev/), LimaCharlie also implements several new modifiers: +The [gjson playground](https://gjson.dev/) shows the built-in modifiers for `gjson`. LimaCharlie adds these modifiers: -- `parsejson`: this modifier takes no arguments, it takes in as input a string that represents a JSON object and outputs the decoded JSON object. -- `extract`: this modifier takes a single argument, `re` which is a regular expression that uses "named capture groups" (as defined in the [re2 documentation](https://github.com/google/re2/wiki/Syntax)). The group names become the keys of the output JSON object with the matching values. -- `parsetime`: this modifier takes two arguments, `from` and `to`. It converts an input string from a given time format (using the [Go `time` library format constants](https://pkg.go.dev/time#pkg-constants)) and outputs the resulting time in the `to` format. Beyond those time constants, LimaCharlie also supports a `from` format of: - - `epoch_s`: a second based epoch timestamp - - `epoch_ms`: a millisecond based epoch timestamp +- `parsejson`: this modifier takes no arguments. The input is a string that holds a JSON object. The output is the decoded JSON object. +- `extract`: this modifier takes one argument, `re`. This argument is a regular expression that uses "named capture groups", as the [re2 documentation](https://github.com/google/re2/wiki/Syntax) defines them. The group names become the keys of the output JSON object, and the matching values become the values. +- `parsetime`: this modifier takes two arguments, `from` and `to`. It reads an input string in the `from` time format and writes the time in the `to` format. Both formats use the [Go `time` library format constants](https://pkg.go.dev/time#pkg-constants). LimaCharlie also supports these `from` formats: + - `epoch_s`: an epoch timestamp in seconds + - `epoch_ms`: an epoch timestamp in milliseconds -For example: -The transform: +For example, this transform: ```json { @@ -373,7 +372,7 @@ applied to: } ``` -would result in: +results in: ```json { diff --git a/docs/4-data-queries/template-transforms.md b/docs/4-data-queries/template-transforms.md index 83c5e1081..e407f45ab 100644 --- a/docs/4-data-queries/template-transforms.md +++ b/docs/4-data-queries/template-transforms.md @@ -2,35 +2,35 @@ Many areas of LimaCharlie support template strings and transforms. -A template string allows you to customize the value of a configuration based on the context. For example to adjust the Detection Name a D&R rule to include a value from the detection itself. Transforms can also be used to select, modify, or remove fields upon data ingestion from an Adapter. +A template string lets you set the value of a configuration from the context. For example, you can add a value from the detection to the Detection Name of a D&R rule. You can also use transforms to select, change, or remove fields when an Adapter ingests data. -A transform allows you to change the shape of JSON data in flight to suit better your usage. This can mean moving, renaming, removing and adding fields in JSON. For example, it can allow you to create an Output that works with `DNS_REQUEST` events, but outputs only specific fields from the event. +A transform changes the shape of JSON data while the data passes through LimaCharlie. You can move, rename, remove, and add fields in the JSON. For example, you can create an Output that works with `DNS_REQUEST` events but sends only specific fields from the event. ## Template Strings Template strings in LimaCharlie use the [Go `text/template` format](https://pkg.go.dev/text/template). [Hashicorp's Go template syntax tutorial](https://learn.hashicorp.com/tutorials/nomad/go-template-syntax) is also a useful reference. -The most basic example for a D&R rule customizing the detection name looks like this: +This example shows a D&R rule that sets the detection name: ```yaml - action: report name: Evil executable on {{ .routing.hostname }} ``` -Template strings also support some LimaCharlie-specific functions: +Template strings also support functions that are specific to LimaCharlie: -- `token`: applies an MD5 hashing function on the value provided. -- `anon`: applies an MD5 hashing function on a secret seed value, plus the value provided. -- `json`: marshals the input into a JSON string representation. -- `prettyjson`: same as `json` but with indentation and newlines. -- `parsetime`: parse a time format to another. -- `split`: split a string based on a seperator param. -- `join`: join a list into a string joined by another string. -- `replace`: replace all string into the other. -- `base`: return the file name in a file path. -- `dir`: return the base directory path from a file path. +- `token`: applies an MD5 hash function to the value that you supply. +- `anon`: applies an MD5 hash function to a secret seed value plus the value that you supply. +- `json`: converts the input into a JSON string. +- `prettyjson`: the same as `json`, but with indentation and newlines. +- `parsetime`: converts one time format to another. +- `split`: splits a string on a separator parameter. +- `join`: joins a list into one string with another string between the items. +- `replace`: replaces all instances of one string with another string. +- `base`: returns the file name in a file path. +- `dir`: returns the base directory path from a file path. -The `token` and `anon` functions can be used to partially anonymize data anywhere a template string is supported, for example: +Use the `token` and `anon` functions to partly anonymize data. These functions work anywhere that supports a template string. For example: ```yaml - action: report @@ -45,27 +45,27 @@ Other examples: ### Template Strings and Adapter Transforms -Template strings can also be used with in conjunction the `client_options.mapping.transform` option in [Adapter configuration](../2-sensors-deployment/adapters/usage.md). These allow you to modify data prior to ingestion, having control over *what* fields get ingested and resulting field names. +You can also use template strings with the `client_options.mapping.transform` option in the [Adapter configuration](../2-sensors-deployment/adapters/usage.md). This option lets you change data before ingestion. You control *what* fields LimaCharlie ingests and the names of the fields. -The following options are available in Adapter configurations: +Adapter configurations support these options: - `+` to add a field - `-` to remove a field -Both support template strings, meaning you can add/remove values from the JSON data to replace/supplement other fields. +Both options support template strings. You can add values to the JSON data or remove values from it, to replace or supplement other fields. #### Additive vs Replacement Mode A transform operates in one of two modes: -- **Replacement mode** (default): when *no* keys in the transform are prefixed with `+` or `-`, the original event is discarded and the output is built from scratch using only the keys you defined. This is the same behavior described in the [Transforms](#transforms) section further down. -- **Additive mode**: as soon as *any* key in the transform is prefixed with `+` or `-`, the entire transform switches to additive mode. The original event is preserved as the base, and the transform's keys add to, modify, or remove fields from it. +- **Replacement mode** (default): if *no* keys in the transform have a `+` or `-` prefix, LimaCharlie discards the original event. It builds the output only from the keys that you defined. The [Transforms](#transforms) section below describes the same behavior. +- **Additive mode**: if *any* key in the transform has a `+` or `-` prefix, the whole transform changes to additive mode. LimaCharlie keeps the original event as the base. The keys of the transform then add, change, or remove fields in that event. -Mixing prefixed and non-prefixed keys in the same transform is allowed: the presence of even a single `+`/`-` key flips the whole map to additive mode, and the non-prefixed keys still take effect (replacing the values at those paths). This is usually what you want when augmenting an event, but it's important to know if you ever expect a non-prefixed key to mean "rebuild the event from this only". +You can mix prefixed and non-prefixed keys in the same transform. One `+` or `-` key changes the whole map to additive mode, and the non-prefixed keys still apply. Each non-prefixed key replaces the value at its path. This behavior is usually what you want when you add data to an event. Remember this behavior if you expect a non-prefixed key to rebuild the event from that key only. #### Example: Renaming and Adding Fields -If we had the following data: +This is the input data: ```json { "event": @@ -78,7 +78,7 @@ If we had the following data: } ``` -And we wanted to rename the `d` value to `c` on ingestion, remove the d value, and add a field called `hostname`, we could use the following configuration: +This configuration renames the `d` value to `c` on ingestion, removes the d value, and adds a field named `hostname`: ```text ... @@ -90,7 +90,7 @@ And we wanted to rename the `d` value to `c` on ingestion, remove the d value, a +hostname : '{{ "my-computer" }}', ``` -The resulting event to be ingested would be: +LimaCharlie then ingests this event: ```json { "event": @@ -106,9 +106,9 @@ The resulting event to be ingested would be: #### Example: Parsing a Stringified JSON Field in Place -A common case with adapters (especially log sources like Parquet, Teleport, or audit logs) is an event that contains a field whose value is a JSON-encoded string rather than a nested object. Without parsing, that field will arrive in LimaCharlie as an opaque string and will not be queryable as structured data. +Adapters often receive an event with a field that holds a JSON-encoded string instead of a nested object. This is common with log sources such as Parquet, Teleport, or audit logs. If nothing parses that field, it arrives in LimaCharlie as an opaque string. You cannot query it as structured data. -Combining additive mode with the [`@parsejson` modifier](#custom-modifiers) lets you decode that string in place without rewriting the rest of the event. For example, given an event like: +Additive mode with the [`@parsejson` modifier](#custom-modifiers) decodes that string in place. The rest of the event does not change. For example, this is an event: ```json { @@ -118,7 +118,7 @@ Combining additive mode with the [`@parsejson` modifier](#custom-modifiers) lets } ``` -The following adapter configuration replaces `event_data` with the decoded object while leaving every other field untouched: +This adapter configuration replaces `event_data` with the decoded object. Every other field stays the same: ```yaml client_options: @@ -127,7 +127,7 @@ client_options: +event_data: "event_data|@parsejson" ``` -If you want to keep the raw string and add the parsed copy alongside it, use a different output key: +To keep the raw string and add the parsed copy next to it, use a different output key: ```yaml client_options: @@ -136,21 +136,21 @@ client_options: +event_data_parsed: "event_data|@parsejson" ``` -Both forms stay in additive mode (because the key is prefixed with `+`), so all the surrounding fields in the event are preserved. +Both forms stay in additive mode because the key has a `+` prefix. LimaCharlie keeps all the other fields in the event. ## Transforms With Transforms, you specify a JSON object that describes the transformation. -This object is in the shape of the final JSON you would like to transform to. +This object has the shape of the final JSON that you want. Key names are the literal key names in the output. Values support one of 3 types: -1. Template Strings, as described above. In this case, the template string will be generated and placed at the same place as the key in the transform object. -2. A `gjson` selector. See the [gjson syntax reference](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) for the selector syntax. It makes it possible to select subsets of input object and map it within the resulting object as defined by the transform. -3. Other JSON objects which will be present in the output. +1. Template Strings, as described above. LimaCharlie generates the template string and puts it at the same place as the key in the transform object. +2. A `gjson` selector. For the selector syntax, see the [gjson syntax reference](https://github.com/tidwall/gjson/blob/master/SYNTAX.md). A selector selects a subset of the input object and maps that subset into the output object that the transform defines. +3. Other JSON objects. These objects are present in the output. -Let's look at an example, let's say this is the Input to our transform: +This is an example Input to a transform: ```json { @@ -231,7 +231,7 @@ Let's look at an example, let's say this is the Input to our transform: } ``` -And this is our Transform definition: +This is the Transform definition: ```json { @@ -246,7 +246,7 @@ And this is our Transform definition: } ``` -Then the resulting Output would be: +The Output is: ```json { @@ -285,7 +285,7 @@ Then the resulting Output would be: ### Transforming Output Data -When passing events to an output, you have the option to transform the original event in multiple ways. When creating an output, Custom Transforms are applied in the CUSTOM TRANSFORM area of the screenshot below. In this example we are transforming a detection event to pass via a custom webhook to a web application. +When you pass events to an output, you can transform the original event in more than one way. When you create an output, apply Custom Transforms in the CUSTOM TRANSFORM area of the screenshot below. This example transforms a detection event and sends it through a custom webhook to a web application. ![Output data transformation settings](../assets/images/image(310).png) @@ -293,7 +293,7 @@ When passing events to an output, you have the option to transform the original #### Extracting Fields from Telemetry -Let's say you have the following 4625 failed logon and you want to send similar events to an output, but only certain fields. +This is a 4625 failed logon event. You want to send events like it to an output, but only some of the fields. ```json { @@ -336,7 +336,7 @@ Let's say you have the following 4625 failed logon and you want to send similar } ``` -The following Output Transform would extract only the `IpAddress`, `TargetUserName`, `EventID`, and `SystemTime` the event was created. Notice, the newly mapped field names can be whatever you want. +This Output Transform extracts only the `IpAddress`, `TargetUserName`, `EventID`, and the `SystemTime` when the event was created. The new field names can be any names that you want. ```json { @@ -347,7 +347,7 @@ The following Output Transform would extract only the `IpAddress`, `TargetUserNa } ``` -The following example outputs text and specified fields using Template Strings. +This example uses Template Strings to output text and specific fields. ```json { @@ -355,7 +355,7 @@ The following example outputs text and specified fields using Template Strings. } ``` -The above example would generate the following output using the provided sample WEL. +With the sample WEL event, the example generates this output. ```json { @@ -365,9 +365,9 @@ The above example would generate the following output using the provided sample ### Output as String / Passthrough -The `custom_transform` in outputs can also be used to output pure text (non-JSON) from LimaCharlie. This is useful if, for example, you are ingesting syslog data, and want to forward this syslog data as-is to something else. +You can also use the `custom_transform` field in outputs to send pure text (non-JSON) from LimaCharlie. For example, you ingest syslog data and want to forward that syslog data unchanged to another system. -This is accomplished by specifying a Template String in the `custom_transform` field instead of a Transform. In those cases, when LimaCharlie determines the `custom_transform` string is not a valid Transform, it will interpret it as a Template String like: +To do this, put a Template String in the `custom_transform` field instead of a Transform. If LimaCharlie finds that the `custom_transform` string is not a valid Transform, it reads the string as a Template String: ```json { @@ -385,16 +385,15 @@ or ### Custom Modifiers -Beyond the built-in modifiers for `gjson` (as seen in their [playground](https://gjson.dev/), LimaCharlie also implements several new modifiers: +The [gjson playground](https://gjson.dev/) shows the built-in modifiers for `gjson`. LimaCharlie adds these modifiers: -- `parsejson`: this modifier takes no arguments, it takes in as input a string that represents a JSON object and outputs the decoded JSON object. -- `extract`: this modifier takes a single argument, `re` which is a regular expression that uses "named capture groups" (as defined in the [re2 documentation](https://github.com/google/re2/wiki/Syntax)). The group names become the keys of the output JSON object with the matching values. -- `parsetime`: this modifier takes two arguments, `from` and `to`. It converts an input string from a given time format (using the [Go `time` library format constants](https://pkg.go.dev/time#pkg-constants)) and outputs the resulting time in the `to` format. Beyond those time constants, LimaCharlie also supports a `from` format of: - - `epoch_s`: a second based epoch timestamp - - `epoch_ms`: a millisecond based epoch timestamp +- `parsejson`: this modifier takes no arguments. The input is a string that holds a JSON object. The output is the decoded JSON object. +- `extract`: this modifier takes one argument, `re`. This argument is a regular expression that uses "named capture groups", as the [re2 documentation](https://github.com/google/re2/wiki/Syntax) defines them. The group names become the keys of the output JSON object, and the matching values become the values. +- `parsetime`: this modifier takes two arguments, `from` and `to`. It reads an input string in the `from` time format and writes the time in the `to` format. Both formats use the [Go `time` library format constants](https://pkg.go.dev/time#pkg-constants). LimaCharlie also supports these `from` formats: + - `epoch_s`: an epoch timestamp in seconds + - `epoch_ms`: an epoch timestamp in milliseconds -For example: -The transform: +For example, this transform: ```json { @@ -418,7 +417,7 @@ applied to: } ``` -would result in: +results in: ```json { diff --git a/docs/4-data-queries/tutorials/bigquery-looker-studio.md b/docs/4-data-queries/tutorials/bigquery-looker-studio.md index e04e88a05..d38407b95 100644 --- a/docs/4-data-queries/tutorials/bigquery-looker-studio.md +++ b/docs/4-data-queries/tutorials/bigquery-looker-studio.md @@ -1,14 +1,14 @@ # Building Reports with BigQuery + Looker Studio -LimaCharlie does not include reporting by default, however our granular and customizable Output options allow you to push data to any source and use third-party tools for reporting. In this tutorial, we'll push a subset of LimaCharlie EDR telemetry to [BigQuery](https://cloud.google.com/bigquery) and analyze our data using Google's [Looker Studio](https://lookerstudio.google.com/). We'll be doing the work in the web UI, however this could also be done via the API. +LimaCharlie does not include reporting by default. Output options send data to any destination, and you use third-party tools for reporting. This tutorial sends a subset of LimaCharlie EDR telemetry to [BigQuery](https://cloud.google.com/bigquery), then analyzes the data with Google [Looker Studio](https://lookerstudio.google.com/). This tutorial uses the web app, but you can also do the same work with the API. -For this example, we will aggregate and analyze Windows processes making network connections. +This example aggregates and analyzes Windows processes that make network connections. ## Preparing BigQuery -Within your project of choice, begin by creating a new dataset. For the purposes of this tutorial, I'm going to create a dataset named `windows_process_details`. Within this dataset, I'll create a table named `network_connections`. +In your project, create a new dataset. This tutorial uses a dataset named `windows_process_details`. In this dataset, create a table named `network_connections`. -Let's examine this hierarchy for a moment: +This is the hierarchy: ```text ├── limacharlie-bq-testing # project @@ -16,25 +16,29 @@ Let's examine this hierarchy for a moment: │ │ ├── network_connections # table ``` -The nice part about this type of hierarchy is that I can build out multiple tables of process details within the same dataset, and then link/analyze them as needed. We'll focus on the `network_connections` data for now, but we could also look at exporting other process details into the same dataset. +This hierarchy lets you build more than one table of process details in the same dataset. You can then link and analyze those tables. This tutorial uses only the `network_connections` data, but you can export other process details into the same dataset. ![image.png](../../assets/images/image(97).png) -Within the Google Cloud Console, we also want to create a Service Account and gather an API key. See Google Cloud's [service account creation guide](https://cloud.google.com/iam/docs/service-accounts-create) for more detail. +In the Google Cloud Console, create a Service Account and get an API key. For more detail, see the Google Cloud [service account creation guide](https://cloud.google.com/iam/docs/service-accounts-create). -Copy the API key and keep it somewhere safe, we'll need to configure it in the output. +Copy the API key and keep it in a safe place. You configure it in the output. ## Creating the BigQuery Output -Creating an Output within LimaCharlie is straightforward. Navigate to `Outputs` in the web UI, select `Add Output`, and select `Events`. +To create an Output in LimaCharlie: + +1. In the web app, go to `Outputs`. +2. Select `Add Output`. +3. Select `Events`. Note: -We want to export raw events in this case - however, we'll use filters to export only the events of interest to BigQuery. +This output exports raw events. Filters send only the events of interest to BigQuery. -Within the Output Destination menu, select `Google Cloud BigQuery`. You'll be prompted with a configuration menu; expand the `Advanced Options`, as we'll need those too. +In the Output Destination menu, select `Google Cloud BigQuery`. A configuration menu opens. Expand the `Advanced Options`, because this tutorial also uses those options. -The following values must be provided in order for the Output to work: +The Output needs these values: - Name (choose your own name) - Dataset (from the previous section) @@ -44,11 +48,11 @@ The following values must be provided in order for the Output to work: Where to Store the Secret? -The secret key for this output can be inserted directly in the web app helper, however we recommend keeping secrets in the [Secret hive](../../7-administration/config-hive/secrets.md) for centralized management. +You can put the secret key directly in the web app helper. LimaCharlie recommends that you keep secrets in the [Secret hive](../../7-administration/config-hive/secrets.md) for central management. -Within the `Advanced Options`, we'll need to provide the following details: +In the `Advanced Options`, supply these details: -- Custom Transform - we don't want to include *all* the details from the `NETWORK_CONNECTIONS` event. For this output, we are interested in processes making network connections and the users associated with them. Thus, we'll apply the following transform to pare this down: +- Custom Transform - this output does not need *all* the details from the `NETWORK_CONNECTIONS` event. It needs the processes that make network connections and the users of those processes. Apply this transform to reduce the fields: ```json { @@ -58,36 +62,36 @@ Within the `Advanced Options`, we'll need to provide the following details: } ``` -Within the `Specific Event Types` field, we'll specify only `NETWORK_CONNECTIONS`. This is another way to pare down the number of events processed and exported. +In the `Specific Event Types` field, specify only `NETWORK_CONNECTIONS`. This is another way to reduce the number of events that LimaCharlie processes and exports. -Finally, we'll also specify a tag of `windows`, ensuring we only capture Windows systems (per our tagging - your tags may differ). Based on the values provided and discussed, here's a screenshot of the Output configuration (minus the API key): +Also specify a tag of `windows`, to capture only Windows systems. This tag matches the tagging in this example; your tags can be different. This screenshot shows the Output configuration with these values, without the API key: ![image](../../assets/images/output-config.png) -Save the output details, and then check `View Samples` in the Outputs menu to see if you're successfully seeing events. +Save the output details. Then select `View Samples` in the Outputs menu to check that events arrive. ![image](../../assets/images/output-sample.png) ## Analyzing Events in BigQuery + Looker Studio -Navigating back to BigQuery, we can see some initial events flowing in: +Go back to BigQuery. The first events arrive: ![image.png](../../assets/images/image(102).png) -Let's hop over to Looker Studio. Create a Blank Report, and select `BigQuery` in the `Connect to Data` menu. +Go to Looker Studio. Create a Blank Report. Select `BigQuery` in the `Connect to Data` menu. ![image.png](../../assets/images/image(103).png) -Select the Project, Dataset, and Table of interest, and click `Add`. +Select the Project, Dataset, and Table. Click `Add`. ![image.png](../../assets/images/image(104).png) -Looker Studio may prompt you about permissions of connected data. However, once connected, we'll be able to see a starter table with aggregate details from our `network_connections` table. +Looker Studio can ask you about the permissions of connected data. After the connection is complete, a starter table shows aggregate details from the `network_connections` table. ![image.png](../../assets/images/image(105).png) -And that's it! From here, you can manipulate and move around the data as needed. You can also blend with another table, allowing you to combine multiple data points. +You can now change and move the data. You can also blend the data with another table to combine more data points. -Reports can also be styled, additional statistics generated, etc. The following example continues to pull on the basic data we exported to provide some unique insights: +You can also style reports and generate more statistics. This example uses the same exported data to show other insights: ![image.png](../../assets/images/image(106).png) diff --git a/docs/5-integrations/api-integrations/alphamountain.md b/docs/5-integrations/api-integrations/alphamountain.md index dfceb8487..cb5bb7a27 100644 --- a/docs/5-integrations/api-integrations/alphamountain.md +++ b/docs/5-integrations/api-integrations/alphamountain.md @@ -1,22 +1,22 @@ # alphaMountain -There are [three alphaMountain API integrations](https://app.limacharlie.io/add-ons/category/api) that can be subscribed with the appropriate API keys. When enabled and configured, alphaMountain resources can be used as an API-based lookup. +There are [three alphaMountain API integrations](https://app.limacharlie.io/add-ons/category/api). You subscribe to each one with the correct API key. After you enable and configure an integration, you can use the alphaMountain resource as an API lookup. ## alphaMountain Category -Returns categorization for Internet URIs, generated by alphaMountain's own statistical and neural network models. For more information on alphaMountain's categories, visit [this page](https://alphamountain.freshdesk.com/support/solutions/articles/66000280079-a9-web-protection-categories-grouped-). +Returns the category of an Internet URI. alphaMountain generates the category with its own statistical and neural network models. For more about the categories, see the [alphaMountain web protection categories](https://alphamountain.freshdesk.com/support/solutions/articles/66000280079-a9-web-protection-categories-grouped-). ### alphaMountain Popularity -Returns the popularity of a domain, as measured by a combination of page-rank, daily traffic bandwidth, total number of requests, and passive DNS activity for a given hostname. For more information, visit [this page](https://www.alphamountain.ai/api/#tag/Domain/paths/~1popularity~1domain/post). +Returns the popularity of a domain. alphaMountain measures the popularity with a combination of page-rank, daily traffic bandwidth, the total number of requests, and passive DNS activity for the hostname. For more information, see the [alphaMountain domain popularity API](https://www.alphamountain.ai/api/#tag/Domain/paths/~1popularity~1domain/post). #### alphaMountain Threat -Returns threat ratings for Internet URIs, generated by alphaMountain's own statistical and neural network models, cross-validated by a variety of sources as appropriate. For more information, visit [this page](https://www.alphamountain.ai/threat-intelligence-feeds-api/). +Returns threat ratings for Internet URIs. alphaMountain generates the ratings with its own statistical and neural network models, and cross-validates them with other sources when applicable. For more information, see the [alphaMountain threat intelligence feeds API](https://www.alphamountain.ai/threat-intelligence-feeds-api/). ## Detection & Response Rule -The following is an example rule that pulls domain names from DNS_REQUEST events and performs a lookup using alphaMountain's category API. +This example rule takes the domain name from a DNS_REQUEST event. It then does a lookup with the alphaMountain category API. ```yaml event: DNS_REQUEST @@ -25,7 +25,7 @@ path: event/DOMAIN_NAME resource: lcr://api/alphamountain-category ``` -The data returned is in JSON format, and includes the API response and a threatYeti URL, which is appended by LimaCharlie. For example: +The returned data is in JSON format. It includes the API response and a threatYeti URL that LimaCharlie adds. For example: ```json { diff --git a/docs/5-integrations/api-integrations/echotrail.md b/docs/5-integrations/api-integrations/echotrail.md index d83fa219f..985f4fae3 100644 --- a/docs/5-integrations/api-integrations/echotrail.md +++ b/docs/5-integrations/api-integrations/echotrail.md @@ -1,8 +1,8 @@ # EchoTrail -[EchoTrail](https://echotrail.io/) is an API service that allows you to perform a lookup of a file name or hash value. EchoTrail will return a summary of statistical details that describes the behavior of the submitted value, as observed from their sensors over time. +[EchoTrail](https://echotrail.io/) is an API service that does a lookup of a file name or a hash value. EchoTrail returns a summary of statistical details. The summary describes the behavior of the value that you submit, as seen by the EchoTrail sensors over time. -LimaCharlie has an integration available for EchoTrail's `insights` API lookup, accepting one of the following: +LimaCharlie has an integration for the EchoTrail `insights` API lookup. The lookup accepts one of these values: - MD5 Hash - SHA256 Hash @@ -10,7 +10,7 @@ LimaCharlie has an integration available for EchoTrail's `insights` API lookup, ## Detection & Response Rule -The following detection and response rule utilizes a file name from a `NEW_PROCESS` event to query the EchoTrail `insights` API: +This D&R rule takes a file name from a `NEW_PROCESS` event. It then queries the EchoTrail `insights` API: ```yaml event: NEW_PROCESS @@ -19,7 +19,7 @@ path: event/FILE_PATH resource: lcr://api/echotrail-insights ``` -EchoTrail's response data includes the following: +The response data from EchoTrail includes these details: ```json { diff --git a/docs/5-integrations/api-integrations/greynoise.md b/docs/5-integrations/api-integrations/greynoise.md index 1b406d10f..bccb9c469 100644 --- a/docs/5-integrations/api-integrations/greynoise.md +++ b/docs/5-integrations/api-integrations/greynoise.md @@ -1,15 +1,15 @@ # GreyNoise -GreyNoise collects, analyzes, and labels data on IP addresses that scan the Internet and often saturate security tools with noise. By querying IP addresses against GreyNoise, teams can spend less time on irrelevant or harmless activity and focus on targeted and/or emerging threats. +GreyNoise collects, analyzes, and labels data on IP addresses that scan the Internet. These IP addresses often saturate security tools with noise. When you query IP addresses against GreyNoise, your team spends less time on irrelevant or harmless activity. The team can then focus on targeted threats and new threats. -LimaCharlie offers integrations with two GreyNoise API lookups: +LimaCharlie has integrations with two GreyNoise API lookups: - [IP Context](https://docs.greynoise.io/reference/noisecontextip-1) - - Get more information about a given IP address. Returns time ranges, IP metadata (network owner, ASN, reverse DNS pointer, country), associated actors, activity tags, and raw port scan and web request information. + - Gets more information about an IP address. Returns time ranges, IP metadata (network owner, ASN, reverse DNS pointer, country), associated actors, activity tags, and raw data about port scans and web requests. - [RIOT IP Lookups](https://docs.greynoise.io/reference/riotip) - - RIOT identifies IPs from known benign services and organizations that commonly cause false positives in network security and threat intelligence products. The collection of IPs in RIOT is continually curated and verified to provide accurate results. + - RIOT identifies IPs from known benign services and companies. These IPs often cause false positives in products for network security and threat intelligence. The collection of IPs in RIOT is continually curated and verified for accurate results. ## IP Context diff --git a/docs/5-integrations/api-integrations/hybrid-analysis.md b/docs/5-integrations/api-integrations/hybrid-analysis.md index 70e99f947..debd09a7c 100644 --- a/docs/5-integrations/api-integrations/hybrid-analysis.md +++ b/docs/5-integrations/api-integrations/hybrid-analysis.md @@ -1,6 +1,6 @@ # Hybrid Analysis -Hybrid Analysis, aka Falcon Sandbox, is a powerful, free malware analysis service for the community that detects and analyzes unknown threats. Hybrid Analysis has its own unique approach, and offers both public-facing and private team-based sandboxing capabilities. +Hybrid Analysis, also known as Falcon Sandbox, is a free malware analysis service for the community. It detects and analyzes unknown threats. Hybrid Analysis gives public sandboxing and private team-based sandboxing. LimaCharlie integrates with the following Hybrid Analysis API calls: @@ -11,11 +11,11 @@ LimaCharlie integrates with the following Hybrid Analysis API calls: ### Overview -The Search API accepts a SHA256 value, and provides an extensive overview of a hash (if previously observed by the platform). +The Search API accepts a SHA256 value. If the platform saw the hash before, the API returns a detailed overview of the hash. **Rule:** -The following D&R rule +The D&R rule is: ```yaml event: NEW_PROCESS @@ -154,7 +154,7 @@ resource: lcr://api/hybrid-analysis-overview ### Search -The Search lookup provides a basic lookup of a hash value. This look accepts one of the following values: +The Search lookup gives basic information about a hash value. It accepts one of these values: - MD5 - SHA1 diff --git a/docs/5-integrations/api-integrations/index.md b/docs/5-integrations/api-integrations/index.md index db6cdf782..a79248b35 100644 --- a/docs/5-integrations/api-integrations/index.md +++ b/docs/5-integrations/api-integrations/index.md @@ -1,13 +1,13 @@ # API Integrations -API Integrations let D&R rules and [lookups](../../7-administration/config-hive/lookups.md) query external services for context — threat intelligence reputation, IP geolocation, ASN lookups, and similar enrichment sources. Each integration is read-only: it pulls data *from* the external service into LimaCharlie at evaluation time. +API Integrations let D&R rules and [lookups](../../7-administration/config-hive/lookups.md) query external services for context. These services include threat intelligence reputation, IP geolocation, ASN lookups, and similar sources of enrichment. Each integration is read-only. It pulls data *from* the external service into LimaCharlie at the time of evaluation. ## When to use an API Integration vs Cloud CLI - **API Integrations** — *read* from an external service to enrich a detection (this section). -- **[Cloud CLI](../extensions/cloud-cli/index.md)** — *write* actions into a cloud service as a response (e.g., disable a user, isolate an instance). +- **[Cloud CLI](../extensions/cloud-cli/index.md)** — *write* actions into a cloud service as a response. For example, disable a user or isolate an instance. -The two complement each other: API integrations add context to detections; Cloud CLI takes action on them. +The two work together. API integrations add context to detections. Cloud CLI takes action on them. ## Available Integrations @@ -17,10 +17,10 @@ The two complement each other: API integrations add context to detections; Cloud - [Hybrid Analysis](hybrid-analysis.md) — file analysis - [IP ASN](ip-asn.md) — IP-to-ASN lookups - [IP Geolocation](ip-geolocation.md) — IP-to-location lookups -- [Pangea](pangea.md) — multi-source intel via Pangea +- [Pangea](pangea.md) — intel from many sources through Pangea - [VirusTotal](virustotal.md) — file / URL / domain reputation ## See Also -- [Lookups](../../7-administration/config-hive/lookups.md) — the underlying mechanism API integrations plug into -- [Cloud CLI](../extensions/cloud-cli/index.md) — action-side complement +- [Lookups](../../7-administration/config-hive/lookups.md) — the mechanism that API integrations use +- [Cloud CLI](../extensions/cloud-cli/index.md) — the action side of integrations diff --git a/docs/5-integrations/api-integrations/ip-asn.md b/docs/5-integrations/api-integrations/ip-asn.md index c56365d76..a6991b4ee 100644 --- a/docs/5-integrations/api-integrations/ip-asn.md +++ b/docs/5-integrations/api-integrations/ip-asn.md @@ -2,9 +2,9 @@ > No Subscription Required > -> LimaCharlie provides access to this integration free of charge for all users, so no additional subscription is required. +> LimaCharlie gives all users access to this integration free of charge. You do not need a subscription. -With the `ip-geo` [add-on](https://app.limacharlie.io/add-ons/detail/ip-geo) subscribed, the `ip-asn` resource can be used as an API-based lookup to resolve IP addresses to their Autonomous System Number (ASN) and organization. +If you subscribe to the `ip-geo` [add-on](https://app.limacharlie.io/add-ons/detail/ip-geo), you can use the `ip-asn` resource as an API-based lookup. The lookup resolves an IP address to its Autonomous System Number (ASN) and organization. ```yaml event: USER_LOGIN @@ -17,12 +17,12 @@ metadata_rules: path: autonomous_system_number ``` -Step-by-step, this rule will do the following: +This rule does these steps: -- Upon seeing a `USER_LOGIN` event, retrieve the `event/SOURCE_IP` value and look it up via the `api/ip-asn` resource -- Upon receiving a response from `api/ip-asn`, evaluate it using `metadata_rules` to see if the ASN matches 13335 (Cloudflare) +- When a `USER_LOGIN` event occurs, the rule gets the `event/SOURCE_IP` value and looks it up with the `api/ip-asn` resource +- When `api/ip-asn` sends a response, the rule evaluates it with `metadata_rules` to see if the ASN matches 13335 (Cloudflare) -The format of the metadata returned looks like this: +The metadata has this format: ```json { @@ -31,9 +31,9 @@ The format of the metadata returned looks like this: } ``` -The ASN data comes from the MaxMind GeoLite2-ASN database. For more information, visit [maxmind.com](http://www.maxmind.com). +The ASN data comes from the MaxMind GeoLite2-ASN database. For more information, see [maxmind.com](http://www.maxmind.com). ## See Also - [IP Geolocation](ip-geolocation.md) — country, city, and location data -- [Behavioral Detection — First-Seen with Lookup Metadata](../../3-detection-response/behavioral-detection.md#first-seen-with-lookup-metadata) — using ASN in suppression keys +- [Behavioral Detection — First-Seen with Lookup Metadata](../../3-detection-response/behavioral-detection.md#first-seen-with-lookup-metadata) — how to use ASN in suppression keys diff --git a/docs/5-integrations/api-integrations/ip-geolocation.md b/docs/5-integrations/api-integrations/ip-geolocation.md index 6bc8ac4a6..4c6f7ac63 100644 --- a/docs/5-integrations/api-integrations/ip-geolocation.md +++ b/docs/5-integrations/api-integrations/ip-geolocation.md @@ -2,9 +2,9 @@ > No Subscription Required > -> LimaCharlie provides access to this integration free of charge for all users, so no additional subscription is required. +> LimaCharlie gives all users access to this integration free of charge. You do not need a subscription. -With the `ip-geo` [add-on](https://app.limacharlie.io/add-ons/detail/ip-geo) subscribed, it can be used as an API-based lookup. +If you subscribe to the `ip-geo` [add-on](https://app.limacharlie.io/add-ons/detail/ip-geo), you can use it as an API-based lookup. ```yaml event: CONNECTED @@ -17,12 +17,12 @@ metadata_rules: path: country/is_in_european_union ``` -Step-by-step, this rule will do the following: +This rule does these steps: -- Upon seeing a `CONNECTED` event, retrieve the `routing/ext_ip` value and send it to MaxMind via the `api/ip-geo` resource -- Upon receiving a response from `api/ip-geo`, evaluate it using `metadata_rules` to see if the country associated with the IP is located in the EU +- When a `CONNECTED` event occurs, the rule gets the `routing/ext_ip` value and sends it to MaxMind through the `api/ip-geo` resource +- When `api/ip-geo` sends a response, the rule evaluates it with `metadata_rules` to see if the country of the IP is in the EU -The format of the metadata returned is documented in the [MaxMind DB Reader (Python) repository](https://github.com/maxmind/MaxMind-DB-Reader-python) and looks like this: +The [MaxMind DB Reader (Python) repository](https://github.com/maxmind/MaxMind-DB-Reader-python) documents the format of the metadata. The metadata has this format: ```json { @@ -79,4 +79,4 @@ The format of the metadata returned is documented in the [MaxMind DB Reader (Pyt } ``` -The geolocation data comes from the maxmind GeoLite2 database. For more information, visit [maxmind.com](http://www.maxmind.com). +The geolocation data comes from the maxmind GeoLite2 database. For more information, see [maxmind.com](http://www.maxmind.com). diff --git a/docs/5-integrations/api-integrations/pangea.md b/docs/5-integrations/api-integrations/pangea.md index b044f85bf..c5f0675ed 100644 --- a/docs/5-integrations/api-integrations/pangea.md +++ b/docs/5-integrations/api-integrations/pangea.md @@ -1,8 +1,8 @@ # Pangea -Pangea is a collection of API-based security services that can quickly be added to enrich data. Pangea is designed make it easy to add security into an application, but also perform lookups for various data types. +Pangea is a collection of API-based security services that you can add to enrich data. Pangea helps you add security to an application, and also do lookups for many data types. -LimaCharlie supports the following Pangea lookups: +LimaCharlie supports these Pangea lookups: - [Domain](https://pangea.cloud/docs/api/domain-intel#reputation) - Check malicious behavior on a domain @@ -11,19 +11,19 @@ LimaCharlie supports the following Pangea lookups: - [IP](https://pangea.cloud/docs/api/ip-intel#reputation) - Check for malicious behavior on an IP - [URL](https://pangea.cloud/docs/api/url-intel#reputation) - - Retrieve an intelligence report + - Get an intelligence report - [User](https://pangea.cloud/docs/user-intel/) - - Checks to see if any PII data or credentials have been exposed by an attack. + - Check if an attack exposed PII data or credentials. ## API Keys > Subscription Required > -> A Pangea subscription is required to utilize this service. Pangea offers a $5 monthly credit for development purposes, provided the account balance is not negative. +> You need a Pangea subscription to use this service. Pangea gives a $5 monthly credit for development if the account balance is not negative. -The Pangea API key (known as a token within the Pangea platform) is added via the integrations menu within LimaCharlie. +Add the Pangea API key (Pangea calls it a token) in the integrations menu in LimaCharlie. -The API key follows this format: +The API key has this format: ```text domain/token @@ -37,7 +37,7 @@ aws.us.pangea.cloud/pts_7kb33fyz313372vuu5zgnotarealtoken ## Domain -The Domain Intel service allows you to retrieve intelligence about known domain names, giving you insight into the reputation of a domain. +The Domain Intel service gets intelligence about known domain names. It shows you the reputation of a domain. ### Rule @@ -64,7 +64,7 @@ resource: lcr://api/pangea-domain-reputation ## File Reputation -The File Intel service enables you to submit a file's hash and get the file's attributes back - giving you insight into the disposition of the file. +The File Intel service lets you submit the hash of a file and get the attributes of the file. It shows you the disposition of the file. ### D&R Rule @@ -91,7 +91,7 @@ resource: lcr://api/pangea-file-reputation ## IP Reputation -The IP Intel service allows you to retrieve security information about known IP addresses that have been collected across the internet for several decades, giving you insight into the reputation of an IP. +The IP Intel service gets security information about known IP addresses. Pangea collected this information across the internet for several decades. The service shows you the reputation of an IP. ### D&R Rule @@ -116,7 +116,7 @@ resource: lcr://api/pangea-ip-reputation ## URL Reputation -The URL Intel service allows you to retrieve intelligence about known URLs, giving you insight into the reputation of a URL. +The URL Intel service gets intelligence about known URLs. It shows you the reputation of a URL. ### D&R Rule @@ -141,7 +141,7 @@ resource: lcr://api/pangea-url-reputation ## User -The User Intel service allows you to check a large repository of breach data to see if a user's Personally Identifiable Data (PII) or credentials have been compromised. +The User Intel service checks a large repository of breach data. It shows you if an attacker compromised the Personally Identifiable Data (PII) or the credentials of a user. ### D&R Rule diff --git a/docs/5-integrations/api-integrations/virustotal.md b/docs/5-integrations/api-integrations/virustotal.md index 96f98e4e7..8de3adcee 100644 --- a/docs/5-integrations/api-integrations/virustotal.md +++ b/docs/5-integrations/api-integrations/virustotal.md @@ -2,11 +2,11 @@ ## API Keys -The VirusTotal API key is added via the integrations menu within LimaCharlie. +Add the VirusTotal API key in the integrations menu in LimaCharlie. ## Usage -With the `vt` add-on subscribed and a VirusTotal API Key configured in the Integrations page, VirusTotal can be used as an API-based lookup. +If you subscribe to the `vt` add-on and configure a VirusTotal API Key on the Integrations page, you can use VirusTotal as an API-based lookup. ```yaml event: CODE_IDENTITY @@ -20,10 +20,10 @@ metadata_rules: length of: true ``` -Step-by-step, this rule will do the following: +This rule does these steps: -- Upon seeing a `CODE_IDENTITY` event, retrieve the `event/HASH` value and send it to VirusTotal via the `api/vt` resource. -- Upon receiving a response from `api/vt`, evaluate it using `metadata_rules` to see if the length of the response is greater than 1 (in this case meaning that more than 1 vendor reporting a hash is bad). +- When a `CODE_IDENTITY` event occurs, the rule gets the `event/HASH` value and sends it to VirusTotal through the `api/vt` resource. +- When `api/vt` sends a response, the rule evaluates it with `metadata_rules` to see if the length of the response is greater than 1. Here, this means that more than 1 vendor reports that a hash is bad. ## Related Articles diff --git a/docs/5-integrations/extensions/cloud-cli/1password.md b/docs/5-integrations/extensions/cloud-cli/1password.md index b04b1312b..d3faf58a7 100644 --- a/docs/5-integrations/extensions/cloud-cli/1password.md +++ b/docs/5-integrations/extensions/cloud-cli/1password.md @@ -1,16 +1,16 @@ # 1Password -The 1Password CLI brings 1Password to the terminal, allowing you to interact with a 1Password instance from LimaCharlie. +The 1Password CLI gives access to 1Password from the terminal. It lets you interact with a 1Password instance from LimaCharlie. This extension uses [1Password's native CLI](https://developer.1password.com/docs/cli). ## 1Password Account Types -Please note that some 1Password functionality is limited to 1Password Business. Please validate you have the correct type of account(s) to ensure that commands run. +Some 1Password functions are limited to 1Password Business. Check that you have the correct type of account, to make sure that the commands run. ## Example -Returns a list of all items the account has read access to by default. +By default, this returns a list of all the items that the account can read. ```yaml - action: extension request @@ -24,9 +24,9 @@ Returns a list of all items the account has read access to by default. ## Credentials -To utilize 1Password's automated CLI capabilities, you will need to create and utilize a Service Account. See 1Password's [Service Accounts getting-started guide](https://developer.1password.com/docs/service-accounts/get-started/) for more detail. +To use the automated CLI capabilities of 1Password, create and use a Service Account. For more detail, see the [Service Accounts getting-started guide](https://developer.1password.com/docs/service-accounts/get-started/) from 1Password. -- Create a secret in the secrets manager in the following format: +- Create a secret in the secrets manager in this format: ```text serviceAccountToken diff --git a/docs/5-integrations/extensions/cloud-cli/aws.md b/docs/5-integrations/extensions/cloud-cli/aws.md index fc972638b..9de3a3621 100644 --- a/docs/5-integrations/extensions/cloud-cli/aws.md +++ b/docs/5-integrations/extensions/cloud-cli/aws.md @@ -1,12 +1,12 @@ # AWS -AWS CLI is a unified tool that provides a consistent interface for interacting with AWS from the command line. With this component of the Cloud CLI Extension, you can interact with AWS directly from LimaCharlie. +The AWS CLI is a single tool with a consistent interface to AWS from the command line. This component of the Cloud CLI Extension lets you interact with AWS directly from LimaCharlie. This extension uses [AWS's native CLI tool](https://awscli.amazonaws.com/v2/documentation/api/latest/index.html). ## Example -The following example would execute in response to AWS telemetry that 1) met certain criteria and 2) had an `instance_id` for an EC2 instance(s). The following response action would utilize the `.event.instance_id` to stop the corresponding EC2 instances. +This example runs in response to AWS telemetry that 1) matches certain criteria and 2) has an `instance_id` for one or more EC2 instances. The response action uses the `.event.instance_id` value to stop those EC2 instances. ```yaml - action: extension request @@ -26,13 +26,13 @@ The following example would execute in response to AWS telemetry that 1) met cer ## Credentials -To utilize AWS CLI capabilities, you will need: +To use the AWS CLI capabilities, you need: -- You will need an AWS access key ID and AWS secret access key -- Create a secret in the secrets manager in the following format: +- An AWS access key ID and an AWS secret access key +- Create a secret in the secrets manager in this format: ```text accessKeyID/secretAccessKey ``` -AWS provides [documentation on creating and managing access keys and other IAM components](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). +AWS supplies [documentation about how to create and manage access keys and other IAM components](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). diff --git a/docs/5-integrations/extensions/cloud-cli/azure.md b/docs/5-integrations/extensions/cloud-cli/azure.md index 9c7db46e3..80d2cac8d 100644 --- a/docs/5-integrations/extensions/cloud-cli/azure.md +++ b/docs/5-integrations/extensions/cloud-cli/azure.md @@ -1,12 +1,12 @@ # Azure -The Azure CLI is a set of commands used to create and manage Azure resources. With this component of the Cloud CLI Extension, you can interact with Azure directly from LimaCharlie. +The Azure CLI is a set of commands that create and manage Azure resources. This component of the Cloud CLI Extension lets you interact with Azure directly from LimaCharlie. This extension uses [the Azure CLI](https://learn.microsoft.com/en-us/cli/azure/get-started-with-azure-cli). ## Example -The following example returns a list of virtual machines and their respective details in Azure. +This example returns a list of the virtual machines in Azure and their details. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following example returns a list of virtual machines and their respective de ## Credentials -To utilize the Azure CLI, you will need: +To use the Azure CLI, you need: -- An application and a [service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal) with the appropriate permissions and a [client secret](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret) -- Create a secret in the secrets manager in the following format: +- An application and a [service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal) with the correct permissions and a [client secret](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret) +- Create a secret in the secrets manager in this format: ```text appID/clientSecret/tenantID diff --git a/docs/5-integrations/extensions/cloud-cli/digitalocean.md b/docs/5-integrations/extensions/cloud-cli/digitalocean.md index b3acf78aa..e5c707327 100644 --- a/docs/5-integrations/extensions/cloud-cli/digitalocean.md +++ b/docs/5-integrations/extensions/cloud-cli/digitalocean.md @@ -1,12 +1,12 @@ # DigitalOcean -The DigitalOcean CLI, or `doctl`, is the official CLI for the DigitalOcean API. With this component of the Cloud CLI Extension, you can interact with DigitalOcean directly from LimaCharlie. +The DigitalOcean CLI, or `doctl`, is the official CLI for the DigitalOcean API. This component of the Cloud CLI Extension lets you interact with DigitalOcean directly from LimaCharlie. This extension uses [DigitalOcean's official `doctl` CLI tool](https://github.com/digitalocean/doctl). [Reference documentation](https://docs.digitalocean.com/reference/doctl/reference/) is also available. ## Example -The following example of a response action will enumerate a list of compute droplets within a DigitalOcean instance. +This example of a response action lists the compute droplets in a DigitalOcean instance. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following example of a response action will enumerate a list of compute drop ## Credentials -To utilize `doctl` capabilities, you will need: +To use the `doctl` capabilities, you need: -- A personal access token. See DigitalOcean's [create-personal-access-token reference](https://docs.digitalocean.com/reference/api/create-personal-access-token/). -- Create a secret in the secrets manager in the following format: +- A personal access token. See the [create-personal-access-token reference](https://docs.digitalocean.com/reference/api/create-personal-access-token/) from DigitalOcean. +- Create a secret in the secrets manager in this format: ```text personalAccessToken diff --git a/docs/5-integrations/extensions/cloud-cli/github.md b/docs/5-integrations/extensions/cloud-cli/github.md index af085b938..ad63c6b20 100644 --- a/docs/5-integrations/extensions/cloud-cli/github.md +++ b/docs/5-integrations/extensions/cloud-cli/github.md @@ -1,12 +1,12 @@ # GitHub -The GitHub CLI is a tool that brings GitHub to the terminal, allowing you to interact with and control Git accounts, repositories, organizations, and users from the CLI. With this component of the Cloud CLI Extension, you can interact with GitHub directly from LimaCharlie. +The GitHub CLI is a tool that gives access to GitHub from the terminal. It lets you control Git accounts, repositories, organizations, and users from the CLI. This component of the Cloud CLI Extension lets you interact with GitHub directly from LimaCharlie. This extension uses [the GitHub CLI](https://cli.github.com/manual/). ## Example -The following example returns a list of GitHub organizations. +This example returns a list of GitHub organizations. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following example returns a list of GitHub organizations. ## Credentials -To utilize the GitHub CLI, you will need: +To use the GitHub CLI, you need: - A [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) -- Create a secret in the secrets manager in the following format: +- Create a secret in the secrets manager in this format: ```text access_token diff --git a/docs/5-integrations/extensions/cloud-cli/google-cloud.md b/docs/5-integrations/extensions/cloud-cli/google-cloud.md index 86025ec54..d55badc69 100644 --- a/docs/5-integrations/extensions/cloud-cli/google-cloud.md +++ b/docs/5-integrations/extensions/cloud-cli/google-cloud.md @@ -1,12 +1,12 @@ # Google Cloud -The Google Cloud command line interface, or gcloud CLI, allows you to create and manage Google Cloud resources and services directly on the command line. With this component of the Cloud CLI Extension, you can interact with Google Cloud directly from LimaCharlie. +The Google Cloud command line interface, or gcloud CLI, lets you create and manage Google Cloud resources and services on the command line. This component of the Cloud CLI Extension lets you interact with Google Cloud directly from LimaCharlie. This extension uses [Google Cloud's native CLI tool](https://cloud.google.com/cli). ## Example -The following example stops the specified GCP compute instance. +This example stops the specified GCP compute instance. ```yaml - action: extension request @@ -24,10 +24,10 @@ The following example stops the specified GCP compute instance. ## Credentials -To utilize Google Cloud CLI capabilities, you will need: +To use the Google Cloud CLI capabilities, you need: -- A GCP service account JSON key. See Google Cloud's [service account keys guide](https://cloud.google.com/iam/docs/keys-create-delete). -- Create a secret in the secrets manager in the following format: +- A GCP service account JSON key. See the [service account keys guide](https://cloud.google.com/iam/docs/keys-create-delete) from Google Cloud. +- Create a secret in the secrets manager in this format: ```json { diff --git a/docs/5-integrations/extensions/cloud-cli/index.md b/docs/5-integrations/extensions/cloud-cli/index.md index 9abb288f0..55925cc69 100644 --- a/docs/5-integrations/extensions/cloud-cli/index.md +++ b/docs/5-integrations/extensions/cloud-cli/index.md @@ -1,15 +1,15 @@ # Cloud CLI -The Cloud CLI extension runs cloud-provider CLIs (AWS, Azure, GCP, Okta, etc.) as D&R response actions. Use it to take action *in* a cloud service when a LimaCharlie detection fires — for example, disable an Okta user, isolate an EC2 instance, or revoke a GitHub token directly from a rule. +The Cloud CLI extension runs cloud-provider CLIs (AWS, Azure, GCP, Okta, etc.) as D&R response actions. Use it to take action *in* a cloud service when a LimaCharlie detection fires. For example, a rule can disable an Okta user, isolate an EC2 instance, or revoke a GitHub token. -It uses each platform's native CLI under the hood, so anything the CLI can do is available as an automated response. +The extension uses the native CLI of each platform. Every action that the CLI can do is available as an automated response. ## When to use Cloud CLI vs API Integrations - **Cloud CLI** — *write* actions into an external service (run a command, change state). - **[API Integrations](../../api-integrations/index.md)** — *read* from an external service for enrichment (look up reputation, geolocation, etc.). -Most setups end up using both: API integrations enrich detections with context, Cloud CLI acts on them. +Most setups use both. API integrations enrich detections with context, and Cloud CLI acts on them. ## Supported Platforms diff --git a/docs/5-integrations/extensions/cloud-cli/microsoft365.md b/docs/5-integrations/extensions/cloud-cli/microsoft365.md index 7ee8c4b90..e515e5d0b 100644 --- a/docs/5-integrations/extensions/cloud-cli/microsoft365.md +++ b/docs/5-integrations/extensions/cloud-cli/microsoft365.md @@ -1,12 +1,12 @@ # Microsoft 365 -The CLI **for Microsoft 365** is a tool created to help manage Microsoft 365 tenant(s) and SharePoint framework projects. With this component of the Cloud CLI Extension, you can interact with a Microsoft 365 tenant(s) directly from LimaCharlie. +The CLI **for Microsoft 365** is a tool that helps you manage Microsoft 365 tenants and SharePoint framework projects. This component of the Cloud CLI Extension lets you interact with Microsoft 365 tenants directly from LimaCharlie. This extension uses [the PnP Microsoft 365 CLI](https://github.com/pnp/cli-microsoft365). ## Example -The following example disables the user account with the provided user ID. +This example disables the user account that has the given user ID. ```yaml - action: extension request @@ -27,9 +27,9 @@ The following example disables the user account with the provided user ID. ## Credentials -- Per the Microsoft 365 CLI documentation, multiple authentication mechanisms are available. The current LimaCharlie implementation uses a client secret. See Microsoft's [Register an app quickstart](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) for provisioning details. -- Upon invocation, LimaCharlie will first run the `m365 login` command with the credentials provided. -- Create a secret in the secrets manager in the following format: +- The Microsoft 365 CLI documentation shows that many authentication mechanisms are available. LimaCharlie now uses a client secret. For details about how to provision an app, see the [Register an app quickstart](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) from Microsoft. +- When you call the extension, LimaCharlie first runs the `m365 login` command with the credentials that you supply. +- Create a secret in the secrets manager in this format: ```text appID/clientSecret/tenantID diff --git a/docs/5-integrations/extensions/cloud-cli/okta.md b/docs/5-integrations/extensions/cloud-cli/okta.md index 99825aff4..acad009e2 100644 --- a/docs/5-integrations/extensions/cloud-cli/okta.md +++ b/docs/5-integrations/extensions/cloud-cli/okta.md @@ -1,12 +1,12 @@ # Okta -The Okta CLI allows you to interact with your Okta instance(s) via the command line. With this component of the Cloud CLI Extension, you can interact with Okta directly from LimaCharlie. +The Okta CLI lets you interact with your Okta instances from the command line. This component of the Cloud CLI Extension lets you interact with Okta directly from LimaCharlie. This extension uses [the Okta CLI](https://cli.okta.com/manual/). ## Example -The following example returns a list of registered Okta applications. +This example returns a list of registered Okta applications. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following example returns a list of registered Okta applications. ## Credentials -To make use of the Okta CLI, you will need: +To use the Okta CLI, you need: -- An API key. See Okta's [Create an API token guide](https://developer.okta.com/docs/guides/create-an-api-token/main/). -- Create a secret in the secrets manager in the following format: +- An API key. See the [Create an API token guide](https://developer.okta.com/docs/guides/create-an-api-token/main/) from Okta. +- Create a secret in the secrets manager in this format: ```text okta_domain/api_key @@ -31,11 +31,11 @@ okta_domain/api_key ## Available Commands -> All "USERID" fields require the Okta User ID, not the user's name +> All "USERID" fields need the Okta User ID, not the name of the user ### Get User Details -Fetches a user from your Okta organization. +Gets a user from your Okta organization. #### Command @@ -102,9 +102,9 @@ user get 00untroxqpl08VcNC5d7 ### Get List of Users -Lists users that do not have a status of "DEPROVISIONED" (by default), up to the maximum (200 for most orgs), with pagination in most cases. A subset of users can be returned that match a supported filter expression or search criteria. +By default, this lists the users that do not have a status of "DEPROVISIONED", up to the maximum (200 for most orgs). Most responses use pagination. The command can return a subset of users that match a supported filter expression or search criteria. -> This command takes an optional filter. If no filter is provided, all users are returned. For more information on Okta's query filters, visit +> This command takes an optional filter. If you do not give a filter, the command returns all users. For more information about the query filters of Okta, see #### Command @@ -161,7 +161,7 @@ user list Deactivates a user. -> This operation can only be performed on users that do not have a "DEPROVISIONED" status. +> You can do this operation only on users that do not have a "DEPROVISIONED" status. #### Command @@ -185,7 +185,7 @@ None Activates a user. -> This operation can only be performed on users with a "STAGED" status. +> You can do this operation only on users that have a "STAGED" status. #### Command @@ -207,7 +207,7 @@ None ### Expire User Password -This operation transitions the user to the status of "PASSWORD\_EXPIRED" so that the user is required to change their password at their next login. +This operation moves the user to the status "PASSWORD\_EXPIRED". The user must then change the password at the next login. #### Command @@ -229,9 +229,9 @@ None ### Suspend User -Suspends a user. The user will have a status of "SUSPENDED" when the process is complete. +Suspends a user. The user has a status of "SUSPENDED" when the process is complete. -> This operation can only be performed on users with an "ACTIVE" status. +> You can do this operation only on users that have an "ACTIVE" status. #### Command @@ -253,9 +253,9 @@ None ### Unsuspend User -Unsuspends a user and returns them to the "ACTIVE" state. This operation can only be performed on users that have a "SUSPENDED" status. +Unsuspends a user and returns the user to the "ACTIVE" state. You can do this operation only on users that have a "SUSPENDED" status. -> This operation can only be performed on users that have a "SUSPENDED" status. +> You can do this operation only on users that have a "SUSPENDED" status. #### Command @@ -277,7 +277,7 @@ None ### Unlock User -Unlocks a user with a "LOCKED\_OUT" status and returns them to "ACTIVE" status. Users will be able to login with their current password. +Unlocks a user that has a "LOCKED\_OUT" status and returns the user to "ACTIVE" status. The user can then log in with the current password. #### Command diff --git a/docs/5-integrations/extensions/cloud-cli/sdm.md b/docs/5-integrations/extensions/cloud-cli/sdm.md index f4ca68a66..374e92327 100644 --- a/docs/5-integrations/extensions/cloud-cli/sdm.md +++ b/docs/5-integrations/extensions/cloud-cli/sdm.md @@ -1,12 +1,12 @@ # StrongDM -The StrongDM CLI allows you to manage your StrongDM platform(s) via the command-line. With this component of the Cloud CLI Extension, you can interact with StrongDM's directly from LimaCharlie. +The StrongDM CLI lets you manage your StrongDM platforms from the command line. This component of the Cloud CLI Extension lets you interact with StrongDM directly from LimaCharlie. See the [StrongDM CLI documentation](https://www.strongdm.com/docs/cli/) for more detail. ## Example -The following response action returns a list of all users in your Organization. +This response action returns a list of all the users in your Organization. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following response action returns a list of all users in your Organization. ## Credentials -To utilize StrongDM's CLI capabilities, you will need: +To use the CLI capabilities of StrongDM, you need: -- An admin or service account token. See StrongDM's [tokens and keys reference](https://www.strongdm.com/docs/admin/tokens-and-keys/) for provisioning details. -- Create a secret in the secrets manager in the following format: +- An admin or service account token. For details about how to provision a token, see the [tokens and keys reference](https://www.strongdm.com/docs/admin/tokens-and-keys/) from StrongDM. +- Create a secret in the secrets manager in this format: ```text token diff --git a/docs/5-integrations/extensions/cloud-cli/sublime.md b/docs/5-integrations/extensions/cloud-cli/sublime.md index f8f7291b9..6e6c4aa05 100644 --- a/docs/5-integrations/extensions/cloud-cli/sublime.md +++ b/docs/5-integrations/extensions/cloud-cli/sublime.md @@ -1,12 +1,12 @@ # Sublime -The Sublime Security CLI brings the power of Sublime's email platform to the command-line. With this component of the Cloud CLI Extension, you can interact with Sublime's email platform directly from LimaCharlie. +The Sublime Security CLI gives access to the email platform of Sublime from the command line. This component of the Cloud CLI Extension lets you interact with the email platform of Sublime directly from LimaCharlie. This extension uses [Sublime Security's native CLI](https://docs.sublimesecurity.com/reference/analysis-api-cli). The CLI is a Python package — its [source code](https://github.com/sublime-security/sublime-cli) is on GitHub. ## Example -The following response action returns information about the currently authentication Sublime Security user. +This response action returns information about the authenticated Sublime Security user. ```yaml - action: extension request @@ -20,10 +20,10 @@ The following response action returns information about the currently authentica ## Credentials -To utilize Sublime's CLI capabilities, you will need: +To use the CLI capabilities of Sublime, you need: -- You will need an API key. See Sublime Security's [authentication reference](https://docs.sublimesecurity.com/reference/authentication) for provisioning details. -- Create a secret in the secrets manager in the following format: +- An API key. For details about how to provision a key, see the [authentication reference](https://docs.sublimesecurity.com/reference/authentication) from Sublime Security. +- Create a secret in the secrets manager in this format: ```text api_key diff --git a/docs/5-integrations/extensions/cloud-cli/tailscale.md b/docs/5-integrations/extensions/cloud-cli/tailscale.md index 545fce983..b0c2726f9 100644 --- a/docs/5-integrations/extensions/cloud-cli/tailscale.md +++ b/docs/5-integrations/extensions/cloud-cli/tailscale.md @@ -1,6 +1,6 @@ # Tailscale -The Tailscale CLI brings Tailscale's powerful software-defined networking, based on WireGuard, to the command line. This Extension allows you to interact with a Tailscale network(s) from LimaCharlie. +The Tailscale CLI gives access to the software-defined networking of Tailscale, based on WireGuard, from the command line. This Extension lets you interact with Tailscale networks from LimaCharlie. This extension uses [Tailscale's native CLI](https://tailscale.com/kb/1031/install-linux). @@ -20,10 +20,10 @@ Returns the current Tailscale status. ## Credentials -To utilize Tailscale's CLI capabilities, you will need: +To use the CLI capabilities of Tailscale, you need: - An [auth key](https://tailscale.com/kb/1085/auth-keys) -- Create a secret in the secrets manager in the following format: +- Create a secret in the secrets manager in this format: ```text authKey @@ -31,4 +31,4 @@ authKey ## Command-line Interface -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. Extensions integrate third-party tools, automate workflows, and add new capabilities. Organizations subscribe to Extensions. Each Extension gets specific permissions to interact with the infrastructure of the organization. An Extension can be private for custom use, or public to share with the community. This framework supports scalability, flexibility, and secure, repeatable deployments. diff --git a/docs/5-integrations/extensions/cloud-cli/vultr.md b/docs/5-integrations/extensions/cloud-cli/vultr.md index b985be46a..4aad236b5 100644 --- a/docs/5-integrations/extensions/cloud-cli/vultr.md +++ b/docs/5-integrations/extensions/cloud-cli/vultr.md @@ -1,12 +1,12 @@ # Vultr -The [Vultr](https://vultr.com/) CLI, or `vultr-cli`, is the official CLI for the Vultr API. With this component of the Cloud CLI Extension, you can interact with Vultr directly from LimaCharlie. +The [Vultr](https://vultr.com/) CLI, or `vultr-cli`, is the official CLI for the Vultr API. This component of the Cloud CLI Extension lets you interact with Vultr directly from LimaCharlie. This extension uses [Vultr's official CLI tool](https://github.com/vultr/vultr-cli). [Reference documentation](https://www.vultr.com/news/how-to-easily-manage-instances-with-vultr-cli/) is also available. ## Example -The following example of a response action will enumerate a list of instance within a Vultr account. +This example of a response action lists the instances in a Vultr account. ```yaml - action: extension request @@ -20,12 +20,12 @@ The following example of a response action will enumerate a list of instance wit ## Credentials -To utilize `vultr-cli` capabilities, you will need: +To use the `vultr-cli` capabilities, you need: -- A personal access token from [Vultr's API settings page](https://my.vultr.com/settings/#settingsapi). -- Your access token will need to have access control open to IPv6 +- A personal access token from the [Vultr API settings page](https://my.vultr.com/settings/#settingsapi). +- Your access token must have access control open to IPv6 -- Create a secret in the secrets manager in the following format: +- Create a secret in the secrets manager in this format: ```text personalAccessToken diff --git a/docs/5-integrations/extensions/index.md b/docs/5-integrations/extensions/index.md index 31a0073e6..efdc394e4 100644 --- a/docs/5-integrations/extensions/index.md +++ b/docs/5-integrations/extensions/index.md @@ -1,12 +1,12 @@ # Extensions -Extensions add capabilities to LimaCharlie. Each extension is a separate piece of functionality that an organization subscribes to from the marketplace; once subscribed, extensions can be configured, called from D&R rules, or invoked directly. +Extensions add capabilities to LimaCharlie. Each extension is a separate piece of functionality that an organization subscribes to from the marketplace. After you subscribe, you can configure an extension, call it from a D&R rule, or invoke it directly. -See [Using Extensions](using-extensions.md) for the subscription / configuration model and how extensions are invoked. +For the subscription and configuration model, and how to invoke extensions, see [Using Extensions](using-extensions.md). ## Categories -- [**LimaCharlie Extensions**](limacharlie/index.md) — built and maintained by LimaCharlie. Includes platform features (Git Sync, YARA Manager, Sensor Cull, Usage Alerts), forensic data collection (Artifact, BinLib, Dumper, Payload Manager), workflow tools (Cases, Feedback, Playbook), and protection / detection tooling (EPP, Exfil, Integrity, Lookup Manager, Reliable Tasking). +- [**LimaCharlie Extensions**](limacharlie/index.md) — built and maintained by LimaCharlie. Includes platform features (Git Sync, YARA Manager, Sensor Cull, Usage Alerts) and forensic data collection (Artifact, BinLib, Dumper, Payload Manager). Also includes workflow tools (Cases, Feedback, Playbook) and protection / detection tooling (EPP, Exfil, Integrity, Lookup Manager, Reliable Tasking). - [**Third-Party Extensions**](third-party/index.md) — built by partners or the community to integrate external tools and services. Examples: Velociraptor (DFIR collections), Zeek (network analysis), Hayabusa / Atomic Red Team / YARA (detection tooling), PagerDuty / Twilio (notifications), OTX / SecureAnnex (threat intel). @@ -14,10 +14,10 @@ See [Using Extensions](using-extensions.md) for the subscription / configuration ## Building extensions -If you want to publish your own extension, see the [Building Extensions](../../6-developer-guide/extensions/building-extensions.md) developer guide. +To publish your own extension, see the [Building Extensions](../../6-developer-guide/extensions/building-extensions.md) developer guide. ## See Also - [Using Extensions](using-extensions.md) -- [API Integrations](../api-integrations/index.md) — the lookup-side complement to Cloud CLI's action-side -- [Outputs](../outputs/index.md) — for streaming data out instead of acting on it +- [API Integrations](../api-integrations/index.md) — the lookup side that goes with the action side of Cloud CLI +- [Outputs](../outputs/index.md) — to send data out instead of to act on it diff --git a/docs/5-integrations/extensions/limacharlie/artifact.md b/docs/5-integrations/extensions/limacharlie/artifact.md index 8ecb4b4ab..5ed212703 100644 --- a/docs/5-integrations/extensions/limacharlie/artifact.md +++ b/docs/5-integrations/extensions/limacharlie/artifact.md @@ -1,36 +1,40 @@ # Artifact -The Artifact Extension provides low-level collection capabilities which can be configured to run automatically via Detection & Response rules, Sensor collections, or pushed via REST API. When enabled, an Artifact Collection menu will be available within the LimaCharlie web UI. +The Artifact Extension gives low-level collection capabilities. You can configure these collections to run automatically from Detection & Response rules or Sensor collections, or push them through the REST API. When you enable the extension, an Artifact Collection menu is available in the LimaCharlie web app. > Billing for Artifacts > -> Note that while the Artifact extension is free to enable, ingested artifacts do incur a charge. Please refer to pricing details to confirm Artifact ingestion and retention costs. +> The Artifact extension is free to enable, but ingested artifacts do incur a charge. Refer to the pricing details for the costs of Artifact ingestion and retention. ## Enabling the Artifact Extension -To enable the Artifact extension, navigate to the [Artifact extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-artifact) in the marketplace. Select the Organization you wish to enable the extension for, and select **Subscribe.** +To enable the Artifact extension, do these steps: -![artifact 1](../../../assets/images/artifact-1.png) +1. Go to the [Artifact extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-artifact) in the marketplace. +2. Select the Organization that you want to enable the extension for. +3. Select **Subscribe.** -After clicking **Subscribe**, the Artifact extension should be available almost immediately. + ![artifact 1](../../../assets/images/artifact-1.png) -> Note that the Artifact extension first requires enabling the [Reliable Tasking extension](reliable-tasking.md). +After you select **Subscribe**, the Artifact extension is available almost immediately. + +> Enable the [Reliable Tasking extension](reliable-tasking.md) first. The Artifact extension needs it. ## Using the Artifact Extension -When enabled, you will see an **Artifact Collection** option under **Sensors** menu for the respective organization. +When you enable the extension, an **Artifact Collection** option shows under the **Sensors** menu for that organization. ![artifact 2](../../../assets/images/artifact-2.png) -Within the Artifact Collection page, you can configure: +On the Artifact Collection page, you can configure: - Artifact collection rules for files. - Artifact collection rules to stream Windows Event Log (WEL) events. - Artifact collection rules to stream Mac Unified Log (MUL) events. - PCAP capture rules to capture network traffic (Only available on Linux) -The following screenshot provides examples of capturing Windows Security and Sysmon Windows Event Logs via Artifact Collection. Rather than using an Adapter, capturing WEL events via the `wel://` pattern adds the corresponding events to the sensor telemetry, creating a real-time stream of Windows Event Log data. However, you can also specify the pattern to collect the specific `.evtx` files. +The screenshot below shows examples of how to capture Windows Security and Sysmon Windows Event Logs with Artifact Collection. The `wel://` pattern captures WEL events without an adapter. It adds the events to the sensor telemetry and makes a real-time stream of Windows Event Log data. You can also specify the pattern to collect the specific `.evtx` files. -More information on Artifact collections can be found below. +More information about Artifact collections is below. ![artifact 3](../../../assets/images/artifact-3.png) diff --git a/docs/5-integrations/extensions/limacharlie/binlib.md b/docs/5-integrations/extensions/limacharlie/binlib.md index 17a462138..8974d8eed 100644 --- a/docs/5-integrations/extensions/limacharlie/binlib.md +++ b/docs/5-integrations/extensions/limacharlie/binlib.md @@ -1,29 +1,29 @@ # BinLib -Binary Library, or "BinLib", is a collection of executable binaries (such as EXE or ELF files) that have been observed within your environment. If enabled, this Extension helps you build your own private collection of observed executables for subsequent analysis and searching. +Binary Library, or "BinLib", is a collection of executable binaries, such as EXE or ELF files, that are observed in your environment. If you enable this Extension, it builds your own private collection of the observed executables. You can then analyze and search that collection. -When LimaCharlie observes a binary and path for the first time a `CODE_IDENTITY` event is generated. The metadata from this event is stored within `binlib`, and is available for searching, tagging, and downloading. Additionally, you can run [YARA](../third-party/yara.md) scans against observed binaries. +When LimaCharlie observes a binary and path for the first time, it generates a `CODE_IDENTITY` event. The metadata from this event is stored in `binlib`. You can search it, tag it, and download it. You can also run [YARA](../third-party/yara.md) scans against observed binaries. ## Enabling BinLib -BinLib requires subscribing to the `ext-reliable-tasking` Extension in order to function properly. This can be enabled [in the Add-ons marketplace](https://app.limacharlie.io/add-ons/extension-detail/ext-reliable-tasking). +BinLib needs a subscription to the `ext-reliable-tasking` Extension to work correctly. Enable that Extension [in the Add-ons marketplace](https://app.limacharlie.io/add-ons/extension-detail/ext-reliable-tasking). -BinLib can be a powerful additional to your detection and response capabilities. Analysts can: +BinLib adds to your detection and response capabilities. Analysts can: - Look for historical evidence of malicious binaries -- Tag previously-observed files for data enrichment (i.e. [MITRE ATT&CK Techniques](https://attack.mitre.org/matrices/enterprise/)) +- Tag previously-observed files for data enrichment (for example, [MITRE ATT&CK Techniques](https://attack.mitre.org/matrices/enterprise/)) - Compare observed hashes to known good or known bad lists - [YARA scan](../third-party/yara.md) and auto-tag for integration in detection & response rules ## Usage -First, subscribe your tenant to the [BinLib](https://app.limacharlie.io/add-ons/extension-detail/binlib) extension. +First, subscribe your organization to the [BinLib](https://app.limacharlie.io/add-ons/extension-detail/binlib) extension. ![binlib 1](../../../assets/images/binlib-1.png) -To perform one of the following operations against your own library, choose the command and select **Run Request.** +To do one of the operations below against your own library, choose the command and select **Run Request.** -The BinLib page in the web app offers an easy way to get started with some of the core requests exposed by the extension: Check Hash, Search, and Yara Scan. +The BinLib page in the web app gives you the main requests of the extension: Check Hash, Search, and Yara Scan. ![binlib 2](../../../assets/images/binlib-2.png) @@ -31,7 +31,7 @@ The BinLib page in the web app offers an easy way to get started with some of th #### Accepted Values: MD5, SHA1, SHA256 -The `check_hash` operation lets you search to see if a particular hash has been observed in your Organization. Output includes a boolean if the hash was found and three hash values, if available. +The `check_hash` operation shows you if a hash was observed in your Organization. The output includes a boolean that shows if the hash was found. It also includes three hash values, if they are available. Sample Output: @@ -52,9 +52,9 @@ Sample Output: #### Careful Downloading Binaries -LimaCharlie does not filter the binaries observed by your organization. You must exercise caution if downloading a malicious file. We recommend downloading potential malicious binaries to an isolated analysis system. +Be careful when you download a file that can be malicious. LimaCharlie does not filter the binaries that your organization observes. Download binaries that can be malicious to an isolated analysis system. -The `get_hash_data` operation provides a link to the raw data for the hash of interest, allowing you to download the resulting binary file (if previously observed within your environment). +The `get_hash_data` operation gives a link to the raw data for the hash. Use the link to download the binary file, if the file was observed before in your environment. Sample Output: @@ -74,7 +74,7 @@ Sample Output: #### Accepted Values: MD5, SHA1, SHA256 -The `get_hash_metadata` operation obtains the metadata for a hash of interest, including signing details, file type, and additional hashes. +The `get_hash_metadata` operation gets the metadata for a hash. The metadata includes signing details, the file type, and more hashes. ```json { @@ -103,7 +103,7 @@ The `get_hash_metadata` operation obtains the metadata for a hash of interest, i ### search -The `search` operation searches the library for binary data points, including or *other than* a known hash. +The `search` operation searches the library for data points of binaries. The data points can include a known hash, or they can be *other than* a known hash. Searchable fields include: @@ -119,21 +119,21 @@ Searchable fields include: - size - type -Note that search criteria are ANDed. Binaries must meet ALL criteria to be returned. +The search criteria are ANDed. A binary must meet ALL criteria before the search returns it. -Search results can be downloaded as a CSV. +You can download the search results as a CSV. ![binlib 3](../../../assets/images/binlib-3.png) ### tag -The `tag` operation allows you to add tag(s) to a hash, allowing for additional classification within binlib. +The `tag` operation adds one or more tags to a hash. The tags give more classification in binlib. -The below example Tags the Google Installer with the `google` tag. +The example below tags the Google Installer with the `google` tag. ![binlib 4](../../../assets/images/binlib-4.png) -Successful tagging yields an `updated` event: +A successful tag operation gives an `updated` event: ```json { @@ -153,24 +153,24 @@ The `untag` operation removes a tag from a binary. ### YARA scan -The `yara_scan` operation lets you run YARA scans across observed files. Scans require: +The `yara_scan` operation runs YARA scans across observed files. A scan needs: - Criteria or hash to filter files to be scanned - [Rule name(s)](../../../7-administration/config-hive/yara.md) or rule(s) -You also have the option to tag hits on match. +You can also tag the files that match. -Note that search criteria are ANDed. Binaries must meet ALL criteria to be returned. +The search criteria are ANDed. A binary must meet ALL criteria before the search returns it. ![binlib 5](../../../assets/images/binlib-5.png) ## Automating -Here are some examples of useful rules that could be used to automate interactions with Binlib. +These example rules automate interactions with Binlib. ### Scan all acquired files with Yara -This rule will automatically scan all acquired files in binlib with a Yara rule: +This rule scans all acquired files in binlib with a Yara rule: ```yaml detect: @@ -192,7 +192,7 @@ respond: - yara_rule_name_here ``` -and this rule will alert on matches: +This rule alerts on matches: ```yaml detect: diff --git a/docs/5-integrations/extensions/limacharlie/cases.md b/docs/5-integrations/extensions/limacharlie/cases.md index a99519147..7730e0110 100644 --- a/docs/5-integrations/extensions/limacharlie/cases.md +++ b/docs/5-integrations/extensions/limacharlie/cases.md @@ -1,48 +1,48 @@ # Cases !!! warning "Public Beta" - Cases is currently in Public Beta. It will change without warnings, and no backward compatibility is promised or provided. + Cases is in Public Beta. It will change without a warning, and there is no backward compatibility. -The Cases extension is a purpose-built SOC triage system that automatically converts LimaCharlie detections into trackable cases with SLA enforcement, investigation tooling, and performance reporting. It is designed for high-volume environments where every detection needs to be acknowledged, investigated, classified, and resolved within measurable timeframes. +The Cases extension is a SOC triage system. It converts LimaCharlie detections into cases that you can track, and it adds SLA enforcement, investigation tools, and performance reports. It is made for environments with a high volume of detections. In these environments, an analyst must acknowledge, investigate, classify, and resolve every detection in a measurable time. -Once subscribed, detections from the organization are ingested and converted into cases. By default all detections are ingested automatically; alternatively, [Tailored mode](#ingestion-mode) lets you select which detections create cases via D&R rules. Analysts work the case queue through a defined lifecycle, attach investigation evidence, and classify outcomes. SOC managers get real-time dashboards and MTTA/MTTR reports. +After you subscribe, the extension ingests the detections of the organization and converts them into cases. By default, it ingests all detections. With [Tailored mode](#ingestion-mode), you select which detections create cases through D&R rules. Analysts work the case queue through a defined lifecycle, attach investigation evidence, and classify outcomes. SOC managers get real-time dashboards and MTTA/MTTR reports. ## Enabling the Extension -Navigate to the [Cases extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-cases) in the marketplace. Select the organization you wish to enable it for, and select **Subscribe**. +Open the [Cases extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-cases) in the marketplace. Select the organization that you want to enable it for, then select **Subscribe**. -On subscription, the extension automatically: +When you subscribe, the extension automatically: -1. Installs D&R rules that forward detections to the cases system via extension requests +1. Installs D&R rules that forward detections to the cases system through extension requests 2. Initializes the organization with default configuration (severity mapping, SLA targets, retention) -No additional setup is required to begin receiving cases. Detections start flowing immediately. +No more setup is necessary before you receive cases. Detections start immediately. The full API specification is available as an OpenAPI document at [cases.limacharlie.io/openapi](https://cases.limacharlie.io/openapi). !!! info "Permissions" - The cases extension uses LimaCharlie's existing RBAC permissions. Analysts need `investigation.get` to view cases and reports, and `investigation.set` to update cases, add notes, and manage investigation data. Configuration management requires `org.conf.get` to read and `org.conf.set` to update organization settings. + The cases extension uses the existing RBAC permissions of LimaCharlie. Analysts need `investigation.get` to see cases and reports. They need `investigation.set` to update cases, add notes, and manage investigation data. To read the organization settings, you need `org.conf.get`. To update them, you need `org.conf.set`. ## How Cases Are Created -Every detection generated by D&R rules in a subscribed organization automatically becomes a case. The mapping is one detection to one case by default. +Every detection that D&R rules generate in a subscribed organization becomes a case. By default, one detection maps to one case. Each case captures from the detection: -- **Severity** (derived from the detection priority via the configured severity mapping) +- **Severity** (comes from the detection priority through the configured severity mapping) - **Detection count** (number of linked detections) -The individual detection fields (detection category, source, priority, sensor ID, hostname, and detection ID) are stored on the linked **CaseDetection** records, not on the case itself. When listing cases, aggregated fields `detection_cats` (unique detection categories) and `sids` (unique SIDs) are populated from linked detections. +The linked **CaseDetection** records store the individual detection fields, not the case. These fields are the detection category, source, priority, sensor ID, hostname, and detection ID. When you list cases, the linked detections fill the aggregated fields `detection_cats` (unique detection categories) and `sids` (unique SIDs). -Duplicate detections (same `detect_id`) are silently dropped to prevent case duplication. +The extension drops duplicate detections (same `detect_id`) to stop duplicate cases. ### Auto-Grouping -When auto-grouping is enabled in the organization configuration, incoming detections can be attached to an existing open case instead of creating a new one. This significantly reduces case volume for noisy rules. +If auto-grouping is enabled in the organization configuration, a new detection can attach to an open case instead of a new case. This reduces the number of cases for noisy rules. -The grouping behavior is configurable along two axes: +You configure the grouping behavior in two ways: -**Group key** -- which identity dimensions must match for detections to group together: +**Group key** -- which identity values must match before detections group together: - `auto_grouping_include_sensor` (default `true`) -- only detections from the same sensor group together. - `auto_grouping_include_category` (default `false`) -- only detections of the same category group together. @@ -53,20 +53,20 @@ If both are disabled, all detections in the org group into one case during the w - `auto_grouping_window_minutes` (default `1440`, range `1`--`10080`) -- maximum time span used to group detections. - `auto_grouping_window_mode` (default `sliding`): - - `sliding` -- the window resets on each new detection. A case stays groupable as long as matching detections keep arriving within the window of its most recent activity. - - `fixed` -- detections are bucketed by wall-clock boundaries of size `window_minutes`. Two detections group only if they fall in the same bucket. + - `sliding` -- the window resets on each new detection. The case continues to group new detections while matching detections arrive in the window after its most recent activity. + - `fixed` -- the extension puts detections into buckets with wall-clock boundaries of size `window_minutes`. Two detections group only if they are in the same bucket. -**Reopening closed cases** -- `auto_grouping_reopen_closed` (default `true`) controls whether a matching detection can reopen an already `resolved` or `closed` case. When true, the case is reopened and a `case_reopened` event with `source=auto_grouping` is added to its audit trail. When false, a matching detection against a closed case creates a new case instead. +**Reopening closed cases** -- `auto_grouping_reopen_closed` (default `true`) controls if a matching detection can reopen a `resolved` or `closed` case. If it is true, the extension reopens the case and adds a `case_reopened` event with `source=auto_grouping` to its audit trail. If it is false, a matching detection against a closed case creates a new case. -When a detection is grouped into an existing case: +When the extension groups a detection into an existing case: - The case's `detection_count` increments -- The severity may be upgraded if the new detection has a higher priority -- An event is recorded in the case's audit trail +- The severity can increase if the new detection has a higher priority +- The extension records an event in the case's audit trail ## Case Lifecycle -Cases follow a defined state machine that tracks progress from creation through resolution. +Cases obey a defined state machine. The state machine tracks progress from creation to resolution. ```mermaid stateDiagram-v2 @@ -80,15 +80,15 @@ stateDiagram-v2 closed --> in_progress: reopen ``` -Manual updates can move a case from `resolved` only to `closed`. Auto-grouping (when `auto_grouping_reopen_closed` is enabled) can additionally reopen a `resolved` or `closed` case directly back to `in_progress` when a matching detection arrives. When an auto-grouping reopen happens, the stale `resolved_at` / `closed_at` timestamps and `ttr_seconds` are cleared so that re-resolution recalculates TTR correctly. +A manual update can move a case from `resolved` only to `closed`. If `auto_grouping_reopen_closed` is enabled, auto-grouping can also move a `resolved` or `closed` case back to `in_progress` when a matching detection arrives. An auto-grouping reopen clears the stale `resolved_at` / `closed_at` timestamps and `ttr_seconds`, so the next resolution calculates TTR correctly. ### Status Definitions | Status | Description | |--------|-------------| | `new` | Case created, not yet reviewed by an analyst | -| `in_progress` | Active investigation underway. Records TTA timestamp on first entry | -| `resolved` | Investigation complete, findings documented. Records TTR timestamp | +| `in_progress` | An analyst investigates the case. Records the TTA timestamp on first entry | +| `resolved` | Investigation complete, findings documented. Records the TTR timestamp | | `closed` | Case fully closed. Terminal state | ### Key Timestamps @@ -102,17 +102,17 @@ Manual updates can move a case from `resolved` only to `closed`. Auto-grouping ( ### Severity Mapping -LimaCharlie detection priorities (integer 0--10) are mapped to four severity levels. The thresholds are configurable per organization. A fifth level, `info`, exists for manual use only. +The extension maps LimaCharlie detection priorities (integer 0--10) to four severity levels. You configure the thresholds for each organization. A fifth level, `info`, is for manual use only. | Severity | Default Priority Range | Description | |----------|----------------------|-------------| -| `critical` | 8--10 | Requires immediate response | -| `high` | 5--7 | Urgent, handle promptly | +| `critical` | 8--10 | Needs an immediate response | +| `high` | 5--7 | Urgent, handle quickly | | `medium` | 3--4 | Standard priority | -| `low` | 0--2 | Informational, handle when available | -| `info` | _(manual only)_ | Non-actionable; lets analysts associate activity without implying a real problem | +| `low` | 0--2 | Informational, handle when you have time | +| `info` | _(manual only)_ | Not actionable; lets analysts link activity without a statement of a real problem | -`info` is never assigned automatically from detection priority. It can only be set explicitly when creating or updating a case. +The extension never assigns `info` automatically from the detection priority. You can set it only when you create or update a case. ### SLA Targets @@ -131,7 +131,7 @@ Default SLA targets: | `low` | 100 minutes | ~47 hours | | `info` | 8 hours | 7 days | -SLA breaches are tracked in the dashboard and reporting views. +The dashboard and the reporting views track SLA breaches. ## Configuration @@ -139,7 +139,7 @@ Each organization has its own configuration that controls severity mapping, SLA ### Configuration Options -The following settings are available through the REST API (`GET/PUT /api/v1/config/{oid}`): +You set the settings below through the REST API (`GET/PUT /api/v1/config/{oid}`): | Setting | Type | Default | Description | |---------|------|---------|-------------| @@ -156,20 +156,20 @@ The following settings are available through the REST API (`GET/PUT /api/v1/conf | `sla_config.low.mttr_minutes` | int | `2800` | MTTR target for low cases (minutes) | | `sla_config.info.mtta_minutes` | int | `480` | MTTA target for info cases (minutes) | | `sla_config.info.mttr_minutes` | int | `10080` | MTTR target for info cases (minutes) | -| `retention_days` | int | `90` | Days to retain resolved/closed cases before archival | -| `auto_close_resolved_after_days` | int | `7` | Automatically close resolved cases after this many days. Set to `0` to disable | -| `auto_grouping_enabled` | bool | `false` | Enable auto-grouping of related detections into single cases (see [Auto-Grouping](#auto-grouping)) | +| `retention_days` | int | `90` | Days to keep resolved/closed cases before archival | +| `auto_close_resolved_after_days` | int | `7` | Close resolved cases automatically after this many days. Set to `0` to disable | +| `auto_grouping_enabled` | bool | `false` | Group related detections into single cases automatically (see [Auto-Grouping](#auto-grouping)) | | `auto_grouping_include_sensor` | bool | `true` | Only applies when auto-grouping is enabled. When true, only detections from the same sensor group together | | `auto_grouping_include_category` | bool | `false` | Only applies when auto-grouping is enabled. When true, only detections of the same category group together | | `auto_grouping_window_minutes` | int | `1440` | Only applies when auto-grouping is enabled. Maximum time span used to group detections (1--10080 minutes) | -| `auto_grouping_window_mode` | string | `"sliding"` | Only applies when auto-grouping is enabled. `"sliding"` resets the window on each new detection; `"fixed"` buckets by wall-clock boundaries | -| `auto_grouping_reopen_closed` | bool | `true` | Only applies when auto-grouping is enabled. When true, a matching detection reopens an already resolved/closed case instead of creating a new one | +| `auto_grouping_window_mode` | string | `"sliding"` | Only applies when auto-grouping is enabled. `"sliding"` resets the window on each new detection; `"fixed"` groups by wall-clock boundaries | +| `auto_grouping_reopen_closed` | bool | `true` | Only applies when auto-grouping is enabled. When true, a matching detection reopens a resolved/closed case instead of a new case | -The following settings are managed through the extension configuration page in the LimaCharlie web UI (not through the REST API): +You manage the settings below on the extension configuration page in the LimaCharlie web app, not through the REST API: | Setting | Type | Default | Description | |---------|------|---------|-------------| -| `ingestion_mode` | string | `"all"` | Controls which detections create cases. `"all"` forwards every detection; `"tailored"` only creates cases for detections explicitly sent via D&R rules (see [Ingestion Mode](#ingestion-mode)) | +| `ingestion_mode` | string | `"all"` | Controls which detections create cases. `"all"` forwards every detection; `"tailored"` creates cases only for the detections that D&R rules send (see [Ingestion Mode](#ingestion-mode)) | ### Get Configuration @@ -232,7 +232,7 @@ The following settings are managed through the extension configuration page in t ### Creating a Case -While detections are automatically converted to cases, you can also create cases manually via the CLI or SDK. This is useful for ad-hoc investigations or when integrating with external detection sources. You can also create empty investigation cases (without linking a detection) by omitting the `--detection` flag. +The extension converts detections to cases automatically, but you can also create cases manually with the CLI or the SDK. Manual cases are useful for ad-hoc investigations, or when you integrate an external source of detections. To create an empty investigation case, with no linked detection, omit the `--detection` flag. === "CLI" @@ -266,7 +266,7 @@ While detections are automatically converted to cases, you can also create cases ### Listing Cases -Query the case queue with filtering, sorting, and pagination. Supports cross-organization queries for multi-tenant SOCs. +Query the case queue with filters, sort options, and pagination. A query can cross organizations, for a SOC that manages many organizations. === "REST API" @@ -285,7 +285,7 @@ Query the case queue with filtering, sorting, and pagination. Supports cross-org limacharlie case list --sid SENSOR_ID --status new ``` -Available query parameters: +Query parameters that you can use: | Parameter | Description | |-----------|-------------| @@ -318,11 +318,11 @@ Available query parameters: limacharlie case get --case-number 42 ``` -Returns the full case including the event timeline (audit trail of all changes). +Returns the full case with the event timeline (the audit trail of all changes). ### Exporting a Case -Export a case with all its components (case record, event timeline, detections, entities, telemetry, and artifacts) in a single JSON object. +Export a case with all its parts in a single JSON object. The parts are the case record, the event timeline, detections, entities, telemetry, and artifacts. === "CLI" @@ -343,14 +343,14 @@ Export a case with all its components (case record, event timeline, detections, # data contains: case, events, detections, entities, telemetry, artifacts ``` -Without `--with-data`, the combined metadata JSON is printed to stdout. With `--with-data `, the command creates a directory containing: +Without `--with-data`, the command prints the combined metadata JSON to stdout. With `--with-data `, the command creates a directory that contains: - `case.json` -- case record, event timeline, entities -- `detections/` -- one JSON file per linked detection (fetched from Insight) -- `telemetry/` -- one JSON file per linked telemetry event (fetched by atom+sid) +- `detections/` -- one JSON file for each linked detection (fetched from Insight) +- `telemetry/` -- one JSON file for each linked telemetry event (fetched by atom+sid) - `artifacts/` -- downloaded artifact binaries -Fetches that fail (e.g. expired or retained data) emit a warning and are skipped. +A fetch that fails (for example, expired or retained data) gives a warning. The command skips it. ### Updating a Case @@ -383,13 +383,13 @@ Updatable fields: | `severity` | string | Case severity: `critical`, `high`, `medium`, `low`, or `info` | | `assignees` | string[] | Analysts to assign the case to | | `classification` | string | `true_positive`, `false_positive`, or `pending` | -| `summary` | string | Investigation summary narrative (max 8192 characters, Markdown supported) | +| `summary` | string | Investigation summary text (max 8192 characters, Markdown supported) | | `conclusion` | string | Final conclusion (max 8192 characters, Markdown supported) | | `tags` | string[] | Arbitrary tags for categorization (see [Tags](#tags)) | ### Bulk Updates -Update multiple cases at once, useful for bulk-closing false positives or reassigning workload. +Update many cases at the same time. This is useful when you close many false positives, or when you reassign work. === "REST API" @@ -416,24 +416,24 @@ Update multiple cases at once, useful for bulk-closing false positives or reassi limacharlie case bulk-update --input-file case_numbers.txt --status resolved ``` -Up to 200 cases can be updated in a single bulk operation. Bulk updates support only `status` and `classification` fields. For other fields (severity, assignees, tags, etc.), update cases individually. +One bulk operation can update a maximum of 200 cases. A bulk update supports only the `status` and `classification` fields. For other fields, such as severity, assignees, and tags, update each case separately. ### Tags -Cases support arbitrary string tags for custom categorization and workflow organization (e.g., "phishing", "ransomware", "shift-b"). +Cases support arbitrary string tags for custom categorization and workflow organization (for example, "phishing", "ransomware", "shift-b"). **Constraints:** | Constraint | Value | |-----------|-------| | Max tag length | 128 characters | -| Max tags per case | 50 | +| Max tags for each case | 50 | | Case sensitivity | Case-preserved, case-insensitive deduplication | | Allowed characters | Any printable character (no control characters) | #### Setting Tags -Tags are set by replacing the full tag array on the case. +To set tags, replace the full tag array on the case. === "REST API" @@ -460,7 +460,7 @@ Tags are set by replacing the full tag array on the case. #### Tag Management CLI -The CLI provides convenience commands for adding or removing individual tags without replacing the full array. +The CLI has commands that add or remove one tag. These commands do not replace the full array. ```bash # Replace all tags @@ -475,7 +475,7 @@ limacharlie case tag remove --case-number 42 --tag old-label --oid YOUR_OID #### Filtering by Tag -Filter the case list to only cases that have all specified tags (AND logic). +Filter the case list to the cases that have all the specified tags (AND logic). === "REST API" @@ -498,23 +498,23 @@ Filter the case list to only cases that have all specified tags (AND logic). c.list_cases(tag=["phishing", "urgent"]) ``` -Tag changes create a `case_tags_updated` event in the case's audit trail with old and new tag values in the event metadata. +A tag change creates a `case_tags_updated` event in the case's audit trail. The event metadata contains the old and the new tag values. ### Classification -Cases are classified to track detection accuracy. Classification can be set at any status. +You classify cases to track detection accuracy. You can set the classification at any status. | Classification | Description | |---------------|-------------| | `pending` | Not yet classified (default) | | `true_positive` | Confirmed malicious or policy-violating activity | -| `false_positive` | Benign activity incorrectly flagged | +| `false_positive` | Benign activity that a rule flagged incorrectly | -Classification rates are tracked in reports and feed into detection rule tuning. +Reports track the classification rates. Use the rates to tune the detection rules. ## Detections -Each case is created from a detection and can have additional detections linked to it (for example, when auto-grouping is enabled or when manually associating related detections). +Each case is created from a detection. More detections can link to the case, for example when auto-grouping is enabled, or when you link related detections manually. ### Link a Detection @@ -541,7 +541,7 @@ Each case is created from a detection and can have additional detections linked }' ``` - The `detection` field accepts a full LC detection object. The fields `detect_id`, `cat`, `source`, `routing` (with `sid` and `hostname`), and `detect_mtd` (with `level`) are extracted automatically. + The `detection` field accepts a full LC detection object. The extension extracts the fields `detect_id`, `cat`, `source`, `routing` (with `sid` and `hostname`), and `detect_mtd` (with `level`) automatically. === "CLI" @@ -623,7 +623,7 @@ Verdict values: `malicious`, `suspicious`, `benign`, `unknown`, `informational` ### Cross-Case Entity Search -Find all cases containing a specific indicator. This is critical for understanding the blast radius of an IOC across the organization. +Find all cases that contain a specific indicator. The result shows how far an IOC extends across the organization. === "REST API" @@ -641,7 +641,7 @@ Find all cases containing a specific indicator. This is critical for understandi ### Telemetry References -Link specific LimaCharlie events to the case. This creates a direct reference back to the raw telemetry for forensic review. +Link specific LimaCharlie events to the case. Each link is a direct reference to the raw telemetry for forensic review. #### Add Telemetry @@ -665,7 +665,7 @@ Link specific LimaCharlie events to the case. This creates a direct reference ba }' ``` - The `event` field accepts a full LC event object. The `routing.this` (atom), `routing.sid`, and `routing.event_type` fields are extracted automatically. + The `event` field accepts a full LC event object. The extension extracts the `routing.this` (atom), `routing.sid`, and `routing.event_type` fields automatically. === "CLI" @@ -772,7 +772,7 @@ Attach references to forensic artifacts such as memory dumps, packet captures, o ### Notes -Add structured notes to document analysis, remediation steps, and handoff information. Note content supports Markdown formatting (headers, bullet lists, tables, code blocks). +Add structured notes that record analysis, remediation steps, and handoff information. The content of a note supports Markdown format (headers, bullet lists, tables, code blocks). === "REST API" @@ -803,17 +803,17 @@ Note types: | `general` | General-purpose note | | `analysis` | Analysis findings and observations | | `remediation` | Remediation steps taken or planned | -| `recommendation` | Suggested actions or next steps for reviewers | +| `recommendation` | Recommended actions or next steps for reviewers | | `escalation` | Escalation context and rationale | | `handoff` | Shift or team handoff information | | `to_stakeholder` | Communication sent to external stakeholders (customers, management) | | `from_stakeholder` | Communication received from external stakeholders | -Notes support an optional `is_public` boolean field. When set to `true`, the note is marked as visible and shareable to external stakeholders. Defaults to `false`. +Notes support an optional `is_public` boolean field. If it is `true`, the note is visible to external stakeholders and you can share it with them. The default is `false`. #### Updating Note Visibility -After a note is created, you can toggle its `is_public` flag: +After you create a note, you can change its `is_public` flag: === "REST API" @@ -832,11 +832,11 @@ After a note is created, you can toggle its `is_public` flag: limacharlie case update-note --case-number 42 --event-id EVENT_ID --no-is-public ``` -The `EVENT_ID` is the `event_id` returned when the note was created. +The `EVENT_ID` is the `event_id` that the API returns when you create the note. ## Case Merging -Related cases can be merged when multiple detections are part of the same incident. Merging consolidates the investigation into a single primary case. +You can merge related cases when many detections are part of the same incident. A merge combines the investigation into one primary case. === "REST API" @@ -858,17 +858,17 @@ Related cases can be merged when multiple detections are part of the same incide limacharlie case merge --target 10 --sources 11,12 ``` -Up to 20 source cases can be merged at once. +One merge can include a maximum of 20 source cases. -When cases are merged: +When you merge cases: -- The target case inherits all detections from source cases -- Source cases are closed with `merged_into_case_id` set to the target case -- Merge events are recorded in the audit trail of all affected cases +- The target case inherits all detections from the source cases +- The source cases close with `merged_into_case_id` set to the target case +- The extension records merge events in the audit trail of all affected cases ## Assignees -List all unique assignee emails across your accessible organizations. Useful for populating assignment dropdowns. +List all unique assignee emails in the organizations that you can access. Use the list to fill assignment dropdowns. === "REST API" @@ -886,7 +886,7 @@ List all unique assignee emails across your accessible organizations. Useful for ## Subscribed Organizations -List all organizations subscribed to the Cases extension that you have access to. +List all organizations that subscribe to the Cases extension and that you can access. ```bash curl -s -X GET \ @@ -894,18 +894,18 @@ curl -s -X GET \ -H "Authorization: Bearer $LC_JWT" ``` -Returns `{"oids": ["oid1", "oid2", ...]}`. Requires `investigation.get` permission. Useful for discovering which of your organizations have Cases enabled without checking each one individually. +Returns `{"oids": ["oid1", "oid2", ...]}`. Needs the `investigation.get` permission. The list shows which of your organizations have Cases enabled, so you do not check each organization separately. ## D&R Rule Integration -The cases extension exposes request handlers that can be used in D&R rule response actions. This enables automated case management based on detection logic. +The cases extension has request handlers that you can use in D&R rule response actions. These handlers give automatic case management that is based on detection logic. ### Ingestion Mode The `ingestion_mode` configuration controls how detections become cases: -- **`all`** (default) -- Every detection in the organization automatically creates a case. No D&R rules are required. Internal detections (categories starting with `__`) are excluded automatically. -- **`tailored`** -- Only detections explicitly forwarded via D&R rules using the `ingest_detection` action create cases. This gives you fine-grained control over which detections enter the case queue. +- **`all`** (default) -- Every detection in the organization creates a case automatically. No D&R rules are necessary. The extension excludes internal detections (categories that start with `__`) automatically. +- **`tailored`** -- Only the detections that D&R rules forward with the `ingest_detection` action create cases. This gives you fine-grained control over which detections enter the case queue. To forward a specific detection to the cases system in tailored mode, create a D&R rule: @@ -930,11 +930,11 @@ respond: detect_mtd: detect_mtd ``` -The extension configuration page includes a sample D&R rule template for tailored mode that you can copy and modify. +The extension configuration page includes a sample D&R rule template for tailored mode. You can copy the template and change it. ### Create a Case Manually -Create a case from a D&R rule response action. The `create_case` action accepts an optional `detection` object containing the full detection data, and an optional `severity` override. If `detection` is omitted, an empty investigation case is created. +Create a case from a D&R rule response action. The `create_case` action accepts an optional `detection` object that contains the full detection data, and an optional `severity` override. If you omit `detection`, the extension creates an empty investigation case. ```yaml respond: @@ -951,16 +951,16 @@ respond: ``` !!! note "Value resolution" - Values in `extension request` are resolved as gjson paths against the triggering event. Bare names like `detect_id` extract the actual field value, preserving nested object structure for fields like `routing`. Do not use Go template syntax (`{{ }}`), as it stringifies objects. + The extension resolves the values in `extension request` as gjson paths against the event that triggers the rule. Bare names such as `detect_id` extract the field value and keep the nested object structure for fields such as `routing`. Do not use Go template syntax (`{{ }}`). It converts objects into strings. | Parameter | Type | Description | |-----------|------|-------------| -| `detection` | object | Optional. Full LC detection object. Fields `detect_id`, `cat`, `source`, `routing`, and `detect_mtd` are extracted automatically. Omit to create an empty investigation case. | -| `severity` | string | Optional. Severity override: `critical`, `high`, `medium`, `low`, `info`. Defaults to the severity derived from the detection priority. When calling from the REST API or SDK, pass as a top-level string field. | +| `detection` | object | Optional. Full LC detection object. The extension extracts the fields `detect_id`, `cat`, `source`, `routing`, and `detect_mtd` automatically. Omit to create an empty investigation case. | +| `severity` | string | Optional. Severity override: `critical`, `high`, `medium`, `low`, `info`. The default is the severity that comes from the detection priority. When you call from the REST API or the SDK, pass it as a top-level string field. | ### Query Open Case Count -The `get_case_count` extension action returns the number of open cases broken down by status. It is available as an extension request via the REST API or SDK and is useful for building automation and monitoring workflows. +The `get_case_count` extension action returns the number of open cases for each status. You send it as an extension request through the REST API or the SDK. Use it to build automation and monitoring workflows. === "REST API" @@ -973,11 +973,11 @@ The `get_case_count` extension action returns the number of open cases broken do -d data='{}' ``` -Returns counts per status and a `total` field, for example: `{"new": 5, "in_progress": 3, "resolved": 2, "closed": 10, "total": 20}`. +Returns a count for each status and a `total` field, for example: `{"new": 5, "in_progress": 3, "resolved": 2, "closed": 10, "total": 20}`. ## Dashboard -The dashboard provides real-time visibility into the case queue. +The dashboard shows the case queue in real time. === "REST API" @@ -997,11 +997,11 @@ Returns: - Case counts by status - Case counts by severity -- SLA breach counts (cases exceeding MTTA or MTTR targets) +- SLA breach counts (cases that exceed the MTTA or MTTR targets) ## Reporting -SOC performance reports provide aggregated metrics for measuring team effectiveness and detection quality. +SOC performance reports give aggregated metrics. Use the metrics to measure team effectiveness and detection quality. ### Summary Report @@ -1028,7 +1028,7 @@ Query parameters: | `from` | Start of reporting period (RFC 3339 timestamp) | | `to` | End of reporting period (RFC 3339 timestamp) | -The summary report includes per-organization and aggregate metrics: +The summary report includes metrics for each organization and aggregate metrics: - **MTTA** -- Average and median time to acknowledge, with SLA compliance - **MTTR** -- Average and median time to resolve, with SLA compliance @@ -1037,9 +1037,9 @@ The summary report includes per-organization and aggregate metrics: ## Webhook Notifications -The extension automatically sends webhook notifications for case events via LimaCharlie's extension hooks mechanism. These are delivered as gzip-compressed HTTP POST requests to the organization's configured webhook adapter endpoint. +The extension sends webhook notifications for case events automatically. It uses the extension hooks mechanism of LimaCharlie. The notifications are gzip-compressed HTTP POST requests to the webhook adapter endpoint that you configure for the organization. -Events forwarded via webhook include: case creation, status changes, assignments, classifications, notes, and investigation updates. +The webhook forwards these events: case creation, status changes, assignments, classifications, notes, and investigation updates. Each webhook payload includes: @@ -1047,31 +1047,31 @@ Each webhook payload includes: - `case_id` -- The affected case ID - `case_number` -- The human-readable case number - `oid` -- The organization ID -- `by` -- The user who performed the action +- `by` -- The user who did the action - `ts` -- Timestamp of the event - `metadata` -- Event-specific details (e.g. old/new status values) ## Real-Time Updates (WebSocket) -The cases API provides a WebSocket endpoint for real-time case event delivery at `GET /api/v1/ws`. +The cases API has a WebSocket endpoint for real-time delivery of case events at `GET /api/v1/ws`. To connect: 1. Open a WebSocket connection to `wss://cases.limacharlie.io/api/v1/ws` -2. Authenticate by sending `{"type": "auth", "token": ""}` -3. Subscribe to case updates by sending `{"type": "subscribe", "case_id": ""}` +2. Send `{"type": "auth", "token": ""}` to authenticate +3. Send `{"type": "subscribe", "case_id": ""}` to subscribe to case updates -The server pushes `case_event` messages as changes occur, including status transitions, assignments, notes, and investigation updates. Presence tracking shows which users are currently viewing a case. +The server pushes `case_event` messages when changes occur. The messages include status transitions, assignments, notes, and investigation updates. Presence tracking shows which users look at a case now. ## Rate Limiting -The API enforces a rate limit of 20 requests per second (sustained) with a burst allowance of 50 requests per user. Requests exceeding the limit receive a `429 Too Many Requests` response. +The API enforces a rate limit of 20 requests each second (sustained), with a burst allowance of 50 requests for each user. A request above the limit gets a `429 Too Many Requests` response. -Detection ingestion is separately rate-limited per organization at 100 detections per minute. Organizations on the free tier (sensor quota of 2 or fewer) are limited to 5 detections per minute. +Detection ingestion has a separate rate limit for each organization of 100 detections each minute. Organizations on the free tier (a sensor quota of 2 or fewer) have a limit of 5 detections each minute. ## Audit Trail -Every action on a case is recorded as an immutable event in the case's timeline. This provides a complete chain of custody for compliance and review. +The extension records every action on a case as an immutable event in the case's timeline. The timeline gives a complete chain of custody for compliance and review. Tracked event types: @@ -1087,10 +1087,10 @@ Tracked event types: | `case_closed` | Case closed | | `case_reopened` | Closed case reopened | | `case_note_added` | Note added to case | -| `case_note_visibility_changed` | Note public visibility toggled | +| `case_note_visibility_changed` | Public visibility of the note changed | | `case_detection_added` | Detection grouped into case | | `case_detection_removed` | Detection removed from case | -| `case_severity_upgraded` | Severity increased due to higher-priority detection | +| `case_severity_upgraded` | Severity increased because of a detection with a higher priority | | `case_merged_into` | Case merged into another case | | `case_merged_from` | Case received merge from another case | | `case_entity_added` | IOC/entity attached | @@ -1101,7 +1101,7 @@ Tracked event types: | `case_telemetry_removed` | Telemetry reference removed | | `case_artifact_added` | Forensic artifact attached | | `case_artifact_removed` | Artifact removed | -| `case_tags_updated` | Tags modified (old and new values in metadata) | +| `case_tags_updated` | Tags changed (old and new values in metadata) | | `case_summary_updated` | Investigation summary edited | | `case_conclusion_updated` | Investigation conclusion edited | | `case_config_updated` | Organization configuration updated | @@ -1109,20 +1109,20 @@ Tracked event types: ## Data Retention -Resolved and closed cases are retained for the configured `retention_days` (default 90 days). After the retention period, cases are archived to long-term storage and removed from the active case store. +The extension keeps resolved and closed cases for the configured `retention_days` (default 90 days). After the retention period, the extension moves the cases to long-term storage and removes them from the active case store. -Archived data is retained for 2 years in long-term storage for compliance and historical reporting. +Long-term storage keeps the archived data for 2 years, for compliance and historical reports. ## Unsubscribing -Unsubscribing from the extension removes the detection-forwarding D&R rules and deletes all case data for the organization. This action is irreversible. +When you unsubscribe from the extension, it removes the D&R rules that forward detections. It also deletes all case data for the organization. You cannot undo this action. --- ## See Also - [D&R Rules Overview](../../../3-detection-response/index.md) -- Detection rules that generate the detections ingested as cases -- [Response Actions](../../../8-reference/response-actions.md) -- The `extension request` action used for D&R rule integration +- [Response Actions](../../../8-reference/response-actions.md) -- The `extension request` action for D&R rule integration - [Using Extensions](../using-extensions.md) -- General extension subscription and management -- [Compliance Case-Reviewer Agent](../../../9-ai-sessions/compliance/case-reviewer-agent.md) -- Per-framework AI agents (PCI, HIPAA, CMMC, SOC 2, NIST 800-53, ISO 27001, CIS v8) that classify in-scope cases against control citations on `case_created` events and write audit-grade documentation directly into the case record +- [Compliance Case-Reviewer Agent](../../../9-ai-sessions/compliance/case-reviewer-agent.md) -- AI agents for each framework (PCI, HIPAA, CMMC, SOC 2, NIST 800-53, ISO 27001, CIS v8). They classify in-scope cases against control citations on `case_created` events, and write audit-grade documentation into the case record - [Compliance Plugin Overview](../../../9-ai-sessions/compliance/index.md) -- Installation and capabilities of the `lc-compliance` Claude Code plugin diff --git a/docs/5-integrations/extensions/limacharlie/dumper.md b/docs/5-integrations/extensions/limacharlie/dumper.md index 22415833a..c4b04702b 100644 --- a/docs/5-integrations/extensions/limacharlie/dumper.md +++ b/docs/5-integrations/extensions/limacharlie/dumper.md @@ -1,21 +1,21 @@ # Dumper -The Dumper Extension provides the ability to do dumping of several forensic artifacts on Windows hosts. It supports a single action, which is to dump. +The Dumper Extension dumps several forensic artifacts on Windows hosts. It supports one action, which is to dump. -It supports multiple targets -- `memory` to dump the memory of the host, and `mft` to dump the MFT of the file system to CSV. The extension then automates the ingestion of the resulting dump (and dump metadata) to LimaCharlie's [Artifact Ingestion system](artifact.md) where it can be downloaded or analyzed, and where you can create rules to automate detections of characteristics of those dumps. +It supports two targets. `memory` dumps the memory of the host. `mft` dumps the MFT of the file system to CSV. The extension then sends the dump and the dump metadata to the LimaCharlie [Artifact Ingestion system](artifact.md). There you can download or analyze the dump. You can also create rules that detect characteristics of those dumps. ## Usage -When enabled, dumper will be added to the Extensions view inside your Organization. It will accept the following parameters: +When you enable dumper, LimaCharlie adds it to the Extensions view in your Organization. It accepts these parameters: -- `sid` - a Sensor ID for the host to perform the memory dump +- `sid` - a Sensor ID for the host to do the memory dump - `target` - memory or mft -- `retention` - the number of days the memory dump should be retained for (default is 30) -- `ignore_cert` - ignore cert errors for payload and collection purposes (default `false`) +- `retention` - the number of days to keep the memory dump (default is 30) +- `ignore_cert` - ignore certificate errors for payloads and collection (default `false`) -Upon submission of a request, the extension will perform a full memory dump of a host and upload the resulting dumps to LimaCharlie's artifact ingestion system and delete the local dumps afterwards. +After you submit a request, the extension does a full memory dump of the host. It uploads the dumps to the LimaCharlie artifact ingestion system. It then deletes the local dumps. -Dumper requests can also be made via D&R rules. Here is is example of a D&R rule action that makes a request to Dumper: +You can also make Dumper requests with D&R rules. This example shows a D&R rule action that makes a request to Dumper: ```yaml - action: extension request @@ -30,4 +30,4 @@ Dumper requests can also be made via D&R rules. Here is is example of a D&R rule **Notes:** -The dumper extension does not currently validate that the host has enough available disc space for the memory dump. Although the dumper extension is free, the resulting memory dumps uploaded to LimaCharlie are subject to external logs pricing. This add-on relies on other paid resources (payloads) billed based on usage. +The dumper extension does not check that the host has enough free disc space for the memory dump. The dumper extension is free, but the memory dumps that you upload to LimaCharlie are subject to external logs pricing. This add-on uses other paid resources (payloads) that are billed based on usage. diff --git a/docs/5-integrations/extensions/limacharlie/epp.md b/docs/5-integrations/extensions/limacharlie/epp.md index afefecb80..16cbd60f2 100644 --- a/docs/5-integrations/extensions/limacharlie/epp.md +++ b/docs/5-integrations/extensions/limacharlie/epp.md @@ -2,75 +2,86 @@ ## Overview -The Endpoint Protection (EPP) management in LimaCharlie enables users to view the status of existing EPP solutions (including Windows Free Defender), manage parameters of the deployment and unify alerting from the deployment at scale. This makes it perfect for teams wanting a unified view of the EPP solution, or service providers looking to offer Managed EPP to their customers at scale. +Endpoint Protection (EPP) management in LimaCharlie lets you see the status of existing EPP solutions, which include Windows Free Defender. It also lets you manage the parameters of the deployment and unify the alerts from the deployment at scale. Teams that need one view of the EPP solution can use it. Service providers that offer Managed EPP to their customers at scale can also use it. -The only requirement is for the LimaCharlie agent to be deployed and the EPP Extension enabled (free). +The only requirement is to deploy the LimaCharlie agent and to enable the EPP Extension (free). -Once deployed, EPP can be used natively along with the rest of LimaCharlie's automation and routing capabilities. +After you deploy EPP, you can use it directly with the other LimaCharlie automation and routing capabilities. ## How it Works -LimaCharlie Endpoint Protection integrates with third-party EDR solutions to provide a better view of security operations and extend agent's capabilities. Currently this extension applies to: +LimaCharlie Endpoint Protection integrates with third-party EDR solutions. The integration gives a better view of security operations and extends the capabilities of the agent. This extension applies to: - Microsoft Windows Defender -The LimaCharlie agent communicates with Windows Defender to determine its status, transfer events, and trigger remediation commands. LimaCharlie Endpoint Protection codifies the best practices of collecting events and alerting on detections. When enabled, this extension creates a starter set of rules. In addition to alerting, these rules can be customized to better align with the operational complexity of user's environments. The LC Endpoint Protection extension provides a reliable and cost efficient way of securing endpoints at scale. +The LimaCharlie agent communicates with Windows Defender to find its status, transfer events, and trigger remediation commands. LimaCharlie Endpoint Protection codifies the best practices to collect events and to alert on detections. When you enable this extension, it creates a starter set of rules. These rules alert you, and you can also customize them for the operational complexity of your environment. The LC Endpoint Protection extension is a reliable and cost efficient way to secure endpoints at scale. -The Endpoint Protection add-on requires agent version `4.33.5` or higher. +The Endpoint Protection add-on needs agent version `4.33.5` or higher. ## Enabling and configuring Endpoint Protection -To enable Endpoint Protection, first ensure LimaCharlie Endpoint Agent version is 4.33.5 and above, [update](../../../2-sensors-deployment/endpoint-agent/versioning-upgrades.md) if necessary. +To enable Endpoint Protection, do these steps: -Navigate to the [Endpoint Protection extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-epp) in the Add-Ons marketplace. Choose the target Organization and select `Subscribe`. +1. Make sure the LimaCharlie Endpoint Agent version is 4.33.5 or above. If necessary, [update the agent](../../../2-sensors-deployment/endpoint-agent/versioning-upgrades.md). +2. Open the [Endpoint Protection extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-epp) in the Add-Ons marketplace. +3. Choose the target Organization. +4. Select `Subscribe`. -![To enable Endpoint Protection, first ensure LimaCharlie Endpoint Agent version is 4](../../../assets/images/image(335).png) + ![To enable Endpoint Protection, first ensure LimaCharlie Endpoint Agent version is 4](../../../assets/images/image(335).png) -Once subscribed, you can see the Endpoint Protection in the list of Extensions. +After you subscribe, Endpoint Protection is in the list of Extensions. ![Once subscribed, you can see the Endpoint Protection in the list of Extensions](../../../assets/images/image(332).png) -The Endpoint Protection extension does two things once both sync settings are enabled: +The Endpoint Protection extension does two things when both sync settings are enabled: -1. Creates an artifact collection rule named `defender-log-streaming` +1. It creates an artifact collection rule named `defender-log-streaming` - - This rule adds a WEL pattern that collects MS Defender logs, `wel://Microsoft-Windows-Windows Defender/Operational:*` so that LimaCharlie receives the events the Defender produces. + - This rule adds a WEL pattern that collects MS Defender logs, `wel://Microsoft-Windows-Windows Defender/Operational:*`. LimaCharlie then receives the events that Defender produces. - > Note - > - > If you already have Defender logs coming in via the Artifact extension, you can uncheck the `Sync Extension Config` box to avoid duplicating entries. -2. Creates D&R rules + > Note + > + > If Defender logs already come in through the Artifact extension, clear the `Sync Extension Config` box to avoid duplicate entries. + +2. It creates D&R rules + + - The extension generates several D&R rules that alert on detections and actions by Defender.![Defender D&R rules generated by the EPP extension](../../../assets/images/image(291).png) - - Generates several D&R rules that alert on various detections and actions taken by Defender.![Defender D&R rules generated by the EPP extension](../../../assets/images/image(291).png) 3. To apply the Artifact extension configuration and D&R rules, click `Apply Configuration`. -When the SYNC toggles are on, the collection rules and D&R rules are continuously synchronized with LimaCharlie library of best practices. +When the SYNC toggles are on, LimaCharlie synchronizes the collection rules and D&R rules continuously with its library of best practices. -Once the extension is enabled, it also extends the Web UI with Endpoint Protection functionality, as described below. +The extension also adds Endpoint Protection functions to the Web UI, as described below. ## Using the Endpoint Protection extension -Endpoint Protection capabilities are used in three ways. +You can use the Endpoint Protection capabilities in three ways. ### Verify Protection -Select a Windows Sensor in the organization. In the Sensor Overview, there is a new section, "Endpoint Protection" that shows the current protection status. Verify that Defender is listed as active on the sensor. +1. Select a Windows Sensor in the organization. +2. In the Sensor Overview, find the new "Endpoint Protection" section. This section shows the current protection status. +3. Check that Defender is active on the sensor. ![Verify Protection Select a Windows Sensor in the organization](../../../assets/images/image(333).png) ### Perform Scan -Select a Windows Sensor. - -Click on File System. Select the folder, and click on the scan icon `Scan with EPP` +1. Select a Windows Sensor. +2. Click File System. +3. Select the folder. +4. Click the scan icon `Scan with EPP`. ### Endpoint Protection Commands -Select a Windows Sensor. Open the Sensor Console As you type "epp" you'll see the available commands. Try `epp_status` - it will return the status. +1. Select a Windows Sensor. +2. Open the Sensor Console. +3. Type "epp". The console shows the available commands. +4. Type `epp_status`. The command returns the status. > Events required in Exfil config > -> The EPP solution relies on some new events. They are now defaults, and the extension adds them to existing orgs. In rare case you may need to add them manually to Sensor / Event Collection / Event Collection or your Infra As Code. Here is the list: +> The EPP solution uses some new events. These events are now defaults, and the extension adds them to existing orgs. In rare cases you must add them manually to Sensor / Event Collection / Event Collection or to your Infra As Code. This is the list: > > ```text > EPP_STATUS_REP,EPP_LIST_EXCLUSIONS_REP,EPP_ADD_EXCLUSION_REP,EPP_REM_EXCLUSION_REP, diff --git a/docs/5-integrations/extensions/limacharlie/exfil.md b/docs/5-integrations/extensions/limacharlie/exfil.md index d4c48a784..16e071b2e 100644 --- a/docs/5-integrations/extensions/limacharlie/exfil.md +++ b/docs/5-integrations/extensions/limacharlie/exfil.md @@ -1,37 +1,41 @@ # Exfil (Event Collection) -The Exfil Extension helps manage which real-time [events](../../../8-reference/edr-events.md) get sent from EDR sensors to LimaCharlie. By default, LimaCharlie Sensors send events to the cloud based on a standard profile. This extension exposes those profiles for customization. The Exfil extension allows you to customize Event Collection from LimaCharlie Sensors, as well as mitigate sensors with high I/O or large [detection and response](../../../3-detection-response/examples.md) rulesets. +The Exfil Extension helps you manage which real-time [events](../../../8-reference/edr-events.md) the EDR sensors send to LimaCharlie. By default, LimaCharlie Sensors send events to the cloud based on a standard profile. This extension makes those profiles available for customization. With the Exfil extension you can customize Event Collection from LimaCharlie Sensors. You can also mitigate sensors with high I/O or large [detection and response](../../../3-detection-response/examples.md) rulesets. > Event Collection Rule Synchronization > -> Please note that Exfil (or Event Collection) rule configurations are synchronized with sensors every few minutes. +> LimaCharlie synchronizes Exfil (or Event Collection) rule configurations with sensors every few minutes. ## Enabling the Exfil Extension -To enable the Exfil extension, navigate to the [Exfil extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-exfil) in the marketplace. Select the Organization you wish to enable the extension for, and select **Subscribe**. +To enable the Exfil extension, do these steps: + +1. Open the [Exfil extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-exfil) in the marketplace. +2. Select the Organization for which you want the extension. +3. Select **Subscribe**. ![exfil 1.png "image(231).png"](../../../assets/images/exfil-1.png "image(231).png") -After clicking subscribe, the Exfil extension should be available almost immediately. +After you select Subscribe, the Exfil extension becomes available almost immediately. ## Using the Exfil Extension -Once the extension is enabled, you will see an **Event Collection** option under **Sensors** in the LimaCharlie web UI. +After you enable the extension, an **Event Collection** option is under **Sensors** in the LimaCharlie web UI. ![exfil 2.png "image(227).png"](../../../assets/images/exfil-2.png "image(227).png") There are three rule options within the Exfil extension: -- **Event Collection Rules** manage events sent by the Sensor to the LimaCharlie cloud. -- **Performance Rules** are useful for high I/O servers, but may impact event accuracy. This feature is available only on Windows Sensors. -- **Watch Rules** allow for conditional operators for an event, allowing you to specify a list of sensors to help manage high-volume events. Conditional operators for Watch Rule events include: +- **Event Collection Rules** manage the events that the Sensor sends to the LimaCharlie cloud. +- **Performance Rules** are useful for high I/O servers, but they can affect event accuracy. This feature is available only on Windows Sensors. +- **Watch Rules** give conditional operators for an event. You can specify a list of sensors to help manage high-volume events. The conditional operators for Watch Rule events include: - The **event** itself, such as `MODULE_LOAD`. - - The **path** within the event component to be evaluated, such as `FILE_PATH`. - - The **operator** to evaluate or compare that should be done between the path and the value. - - The **value** to be used in comparison with the operator. + - The **path** in the event component that LimaCharlie evaluates, such as `FILE_PATH`. + - The **operator** that compares the path and the value. + - The **value** that the operator compares. -A sample **Watch Rule** might be +A sample **Watch Rule** is: ```text Event: MODULE_LOAD @@ -40,11 +44,11 @@ Operator: ends with Value: wininet.dll ``` -The above rule would configures the sensor(s) to send *only* `MODULE_LOAD` events where the `FILE_PATH` ends with the value `wininet.dll`. +This rule configures the sensor or sensors to send *only* `MODULE_LOAD` events where the `FILE_PATH` ends with the value `wininet.dll`. ### Watch Rule Fields -When authoring Watch Rules outside of the web UI (REST API, hive, or git-sync), the schema is strict about types. The most common cause of a Watch Rule failing to apply is a scalar where a list is expected. +When you author Watch Rules outside of the web UI (REST API, hive, or git-sync), the schema is strict about types. The most common cause of a Watch Rule that does not apply is a scalar where the schema needs a list. | Field | Type | Required | |----------------------|-------------------------------------------------------------|----------| @@ -57,63 +61,63 @@ When authoring Watch Rules outside of the web UI (REST API, hive, or git-sync), > Common gotcha > -> `path`, `filters.platforms`, and `filters.tags` must be YAML lists, not bare scalars. `path: FILE_PATH` will fail validation; `path: [FILE_PATH]` (or the multi-line `- FILE_PATH` form) is correct. The same applies for `filters.platforms` and `filters.tags`. +> `path`, `filters.platforms`, and `filters.tags` must be YAML lists, not bare scalars. `path: FILE_PATH` fails validation. `path: [FILE_PATH]`, or the multi-line `- FILE_PATH` form, is correct. The same is true for `filters.platforms` and `filters.tags`. ### Watch Rule Operators -Watch Rules support exactly four operators. The configured `value` is compared **literally** (not as a pattern) against the string at `path` in the event: +Watch Rules support exactly four operators. LimaCharlie compares the configured `value` **literally**, not as a pattern, against the string at `path` in the event: | Operator | Match condition | |---------------|----------------------------------------------------------------| | `is` | The field value exactly equals the configured value. | | `contains` | The configured value appears anywhere in the field value. | -| `starts with` | The field value begins with the configured value. | +| `starts with` | The field value starts with the configured value. | | `ends with` | The field value ends with the configured value. | -Additional behavior to be aware of: +The operators also have this behavior: -- **No regular expressions, globs, or wildcards.** A value such as `^/Users/[^/]+/(Downloads|Desktop)/` is matched character-for-character — including the `^`, `[`, `(`, etc. — and will not behave as a regex. -- **Case-insensitive.** Both the configured value and the event field are lowercased before comparison, so `wininet.dll` and `WININET.DLL` match. -- **String fields only.** Only string-typed event fields are evaluated; numeric fields at the configured `path` are skipped. -- **Unknown operators are dropped silently.** A Watch Rule whose `operator` is anything other than the four values above will not match any event. Use one of the supported operators above (or combine multiple Watch Rules) to express the condition you need. +- **No regular expressions, globs, or wildcards.** LimaCharlie matches a value such as `^/Users/[^/]+/(Downloads|Desktop)/` character-for-character. This includes the `^`, `[`, `(`, and other characters. The value does not behave as a regex. +- **Case-insensitive.** LimaCharlie changes the configured value and the event field to lowercase before the comparison. Thus `wininet.dll` and `WININET.DLL` match. +- **String fields only.** LimaCharlie evaluates only string-typed event fields. It skips numeric fields at the configured `path`. +- **Unknown operators are dropped silently.** A Watch Rule with an `operator` that is not one of the four values above does not match any event. Use one of the supported operators above, or combine more than one Watch Rule, to express the condition that you need. > Performance Rules > -> Performance rules, applied via tag to a set of Sensors, are useful for high I/O systems. These rules can be set via the web application or REST API. +> You apply performance rules with a tag to a set of Sensors. These rules are useful for high I/O systems. You can set these rules with the web application or the REST API. ### Throughput Limits -Enabling *every* event for Exfil can produce an exceedingly large amount of traffic. Our first recommendation would be to optimize events required for detection & response rules, in order to ensure that all rules are active. We'd also recommend prioritizing events that contribute to outputs, such as forwarded `DNS_REQUESTS`. +If you enable *every* event for Exfil, this can produce a large amount of traffic. First, optimize the events that detection & response rules need, to make sure that all rules are active. Then give priority to the events that contribute to outputs, such as forwarded `DNS_REQUESTS`. -LimaCharlie attempts to process all events in real-time. However, if events fall behind, they are enqueued to a certain limit. If that limit is reached (e.g. in the case of a long, sustained burst or enabling *all* events at the same time), the queue may eventually get dropped. In that event, an error is emitted to the platform logs. +LimaCharlie tries to process all events in real time. If events fall behind, LimaCharlie puts them in a queue up to a limit. The queue can be dropped if it reaches that limit, for example during a long burst or if you enable *all* events at the same time. LimaCharlie then sends an error to the platform logs. -Seeing event collection errors is a sign you may need to do one of the following: +If you see event collection errors, it is possible that you must do one of these actions: -1. Reduce the population of events collected. -2. Reduce the number of rules you run or rule complexity. -3. Adopt a selective subset of events by utilizing Watch Rules that only bring back events with specific values. +1. Reduce the number of events that you collect. +2. Reduce the number of rules that you run, or their complexity. +3. Use Watch Rules that return only the events with specific values. 4. Enable the IR mode (below). #### Afterburner -Before a backlogged queue is dropped, LimaCharlie attempts to increase performance by entering a special mode we call "afterburner." This mode tries to address one of the common scenarios that can lead to a large influx of data: spammy processes starting over and over. This happens in situations such as the building of software, in which executables like `devenv.exe` or `git` can be called hundreds of times per second. The afterburner mode attempts to (1) de-duplicate those processes and (2) assess only each one through the D&R rules and Outputs. +Before LimaCharlie drops a queue with a backlog, it tries to increase performance. It enters a special mode with the name "afterburner". This mode addresses one common cause of a large influx of data: processes that start again and again. This occurs when software is built, because executables such as `devenv.exe` or `git` can be called hundreds of times per second. The afterburner mode tries to (1) de-duplicate those processes and (2) assess only each one through the D&R rules and Outputs. #### IR Mode -The afterburner mode does not address all possible causes or situations. To help with this, LimaCharlie offers "IR mode." This mode is enabled by tagging a LimaCharlie sensor with the tag `ir`. The goal of "IR mode" is to provide a solution for users who want to record a very large number of events, but do not need to run D&R rules over all of them. When enabled, "IR mode" will not de-duplicate events. Furthermore, D&R rules will *only* be run against the follow event types: +The afterburner mode does not address all possible causes or situations. For these, LimaCharlie supplies "IR mode". To enable this mode, tag a LimaCharlie sensor with the tag `ir`. "IR mode" is for users who must record a large number of events, but do not need to run D&R rules over all of them. "IR mode" does not de-duplicate events. Also, LimaCharlie runs D&R rules *only* against the following event types: 1. `CODE_IDENTITY` 2. `DNS_REQUEST` 3. `NETWORK_CONNECTIONS` 4. `NEW_PROCESS` -IR mode is designed to give a balance between recording all events, while maintaining basic D&R rule capabilities. +IR mode gives a balance between the record of all events and basic D&R rule capabilities. ## Configuration via Hive -In addition to the web UI and the REST actions below, the full Exfil configuration is stored under the `extension_config` hive at the key `ext-exfil` and can be managed via [git-sync](git-sync.md) or directly with the LimaCharlie CLI. +The full Exfil configuration is stored under the `extension_config` hive at the key `ext-exfil`. You can manage it with the web UI, with the REST actions below, with [git-sync](git-sync.md), or directly with the LimaCharlie CLI. -A complete, valid Watch Rule looks like: +This is a complete, valid Watch Rule: ```yaml exfil_rules: @@ -131,11 +135,11 @@ exfil_rules: - file-watch ``` -Note the YAML list form (`-`) used for `path`, `filters.platforms`, and `filters.tags`. See [Watch Rule Fields](#watch-rule-fields) for the full schema. +The example uses the YAML list form (`-`) for `path`, `filters.platforms`, and `filters.tags`. For the full schema, see [Watch Rule Fields](#watch-rule-fields). ### Validate Before Pushing -If a hive `set` against `extension_config/ext-exfil` fails or times out without surfacing a clear error, the most likely cause is a schema-validation failure. You can dry-run any config against the live schema before writing it: +If a hive `set` against `extension_config/ext-exfil` fails or times out with no clear error, the most likely cause is a schema-validation failure. Before you write a config, you can test it against the live schema: ```bash limacharlie hive validate \ @@ -145,13 +149,13 @@ limacharlie hive validate \ --output yaml ``` -An empty (`{}`) response means the record is valid and would be accepted by a subsequent `hive set`. Any other output is a description of the validation failure — fix the offending field and re-run `validate` until it returns empty. +An empty (`{}`) response means that the record is valid and that a subsequent `hive set` accepts it. Any other output describes the validation failure. Correct the bad field and run `validate` again until it returns empty. -`validate` is read-only: it never modifies the stored configuration regardless of the result. +`validate` is read-only. It never changes the stored configuration, whatever the result. ## Actions via REST API -The following REST API actions can be sent to interact with the Exfil extension: +You can send these REST API actions to the Exfil extension: ### List Rules @@ -251,5 +255,5 @@ The following REST API actions can be sent to interact with the Exfil extension: ## See Also -- [Compliance Frameworks](../../../9-ai-sessions/compliance/frameworks.md) -- Exfil rules ship as part of every framework's recommended baseline. The `compliance-baseline-deploy` skill writes them under `data.exfil_rules.list` while preserving existing default rules (e.g., `default-chrome`, `default-linux`). -- [Compliance Gap Analysis](../../../9-ai-sessions/compliance/gap-analysis.md) -- Section A of the gap report enumerates missing exfil events per framework and per platform, with the relevant control citations. +- [Compliance Frameworks](../../../9-ai-sessions/compliance/frameworks.md) -- Exfil rules are part of the recommended baseline of every framework. The `compliance-baseline-deploy` skill writes them under `data.exfil_rules.list` and keeps the existing default rules (for example, `default-chrome` and `default-linux`). +- [Compliance Gap Analysis](../../../9-ai-sessions/compliance/gap-analysis.md) -- Section A of the gap report lists the missing exfil events for each framework and for each platform, with the relevant control citations. diff --git a/docs/5-integrations/extensions/limacharlie/feedback.md b/docs/5-integrations/extensions/limacharlie/feedback.md index e52e4f42e..b0a3c8353 100644 --- a/docs/5-integrations/extensions/limacharlie/feedback.md +++ b/docs/5-integrations/extensions/limacharlie/feedback.md @@ -1,32 +1,32 @@ # Feedback -The Feedback extension enables interactive feedback requests across external channels. It sends approval/denial prompts, acknowledgement requests, or free-form questions to Slack, Telegram, Microsoft Teams, email, or a built-in web UI. It collects responses and dispatches them to LimaCharlie subsystems (case notes via ext-cases, playbook triggers via ext-playbook, or AI agent sessions via the AI Sessions API). +The Feedback extension sends interactive feedback requests to external channels. It can send an approve-or-deny prompt, an acknowledgement request, or a free-form question. The channel can be Slack, Telegram, Microsoft Teams, email, or a built-in web UI. The extension collects the responses and sends them to LimaCharlie subsystems: case notes through ext-cases, playbook triggers through ext-playbook, or AI agent sessions through the AI Sessions API. -Designed for AI-driven and human-initiated workflows where operator approval or input is required before taking an automated action. For example, a D&R rule or playbook can ask a human "Should we isolate host compromised-01?" and wait for a response before proceeding. +Use the extension in AI-driven and human-initiated workflows that need operator approval or input before an automated action. For example, a D&R rule or a playbook can ask a person "Should we isolate host compromised-01?". The rule then waits for a response before it continues. ## Enabling the Extension -Navigate to the [Feedback extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-feedback) in the marketplace. Select the organization you wish to enable it for, and select **Subscribe**. +Open the [Feedback extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-feedback) in the marketplace. Select the organization that you want to enable the extension for. Select **Subscribe**. -On subscription, the extension automatically: +When you subscribe, the extension automatically: 1. Creates a webhook adapter for the organization -2. Installs a D&R rule that routes feedback responses to the extension for processing +2. Installs a D&R rule that sends feedback responses to the extension for processing -No additional configuration is required. You can immediately start configuring channels and sending feedback requests. +No more configuration is necessary. You can configure channels and send feedback requests immediately. ## Concepts ### Channels -A **channel** defines how feedback requests are delivered to respondents. Each channel has a name and a type. Channels are configured through the extension config (see [Channel Configuration](#channel-configuration)). +A **channel** defines how the extension delivers feedback requests to respondents. Each channel has a name and a type. You configure channels in the extension config. For more information, see [Channel Configuration](#channel-configuration). | Channel Type | Description | In-Chat Buttons | Requirements | |-------------|-------------|:---------------:|--------------| -| `web` | Built-in web UI. Returns a shareable URL that displays the question with response buttons or text input. | N/A | None | -| `slack` | Sends an interactive Block Kit message to a Slack channel with action buttons. | Yes | A [Slack Tailored Output](../../outputs/destinations/slack.md) with `slack_api_token` and `slack_channel`. See [Slack Setup](#slack-setup). | -| `telegram` | Sends a message with inline keyboard buttons to a Telegram chat via Bot API. | Yes | A [Telegram Tailored Output](../../outputs/destinations/telegram.md) with `bot_token` and `chat_id`. See [Telegram Setup](#telegram-setup). | -| `ms_teams` | Sends an Adaptive Card to a Microsoft Teams channel via webhook. A button links to the web UI for response. | No (link to web UI) | A [Microsoft Teams Tailored Output](../../outputs/destinations/ms-teams.md) with `webhook_url`. See [Microsoft Teams Setup](#microsoft-teams-setup). | +| `web` | Built-in web UI. Returns a URL that you can share. The page shows the question with response buttons or a text input. | N/A | None | +| `slack` | Sends an interactive Block Kit message with action buttons to a Slack channel. | Yes | A [Slack Tailored Output](../../outputs/destinations/slack.md) with `slack_api_token` and `slack_channel`. See [Slack Setup](#slack-setup). | +| `telegram` | Sends a message with inline keyboard buttons to a Telegram chat through the Bot API. | Yes | A [Telegram Tailored Output](../../outputs/destinations/telegram.md) with `bot_token` and `chat_id`. See [Telegram Setup](#telegram-setup). | +| `ms_teams` | Sends an Adaptive Card to a Microsoft Teams channel through a webhook. A button links to the web UI, where the respondent answers. | No (link to web UI) | A [Microsoft Teams Tailored Output](../../outputs/destinations/ms-teams.md) with `webhook_url`. See [Microsoft Teams Setup](#microsoft-teams-setup). | | `email` | Sends an HTML email with the question and a link to the web approval page. | No (link to web UI) | An [SMTP Tailored Output](../../outputs/destinations/smtp.md) with `dest_host`, `dest_email`, `from_email`, and SMTP credentials. See [Email Setup](#email-setup). | ### Feedback Types @@ -41,39 +41,39 @@ Each feedback type has a dedicated action: ### Feedback Destinations -When a respondent answers, the extension dispatches the response to the configured destination: +When a respondent answers, the extension sends the response to the configured destination: | Destination | Behavior | |-------------|----------| -| `case` | Adds a note to the specified case via ext-cases. Requires a `case_id`. | -| `playbook` | Triggers the specified playbook via ext-playbook with the response data. Requires a `playbook_name`. | -| `ai_agent` | Starts an AI agent session with the response data appended to the agent's prompt. Requires an `ai_agent_name` referencing an `ai_agent` hive record. | +| `case` | Adds a note to the specified case through ext-cases. Needs a `case_id`. | +| `playbook` | Triggers the specified playbook through ext-playbook with the response data. Needs a `playbook_name`. | +| `ai_agent` | Starts an AI agent session. The extension adds the response data to the prompt of the agent. Needs an `ai_agent_name` that refers to an `ai_agent` hive record. | ### Response Content -Each feedback request can include optional JSON data per choice. When the respondent selects a choice, the corresponding content is included in the dispatched response. This allows automation to carry structured payloads through the human decision point. +Each feedback request can include optional JSON data for each choice. When the respondent selects a choice, the extension includes the related content in the response that it sends. Automation can then carry structured payloads through the human decision point. - For `request_simple_approval`, use `approved_content` and `denied_content`. - For `request_acknowledgement`, use `acknowledged_content`. -- For `request_question`, no content fields are available -- the respondent's free-form text IS the response. +- For `request_question`, there are no content fields. The free-form text from the respondent is the response. ### Timeouts -All feedback actions accept an optional timeout. When `timeout_seconds` is set (minimum 60), the system automatically responds with a default choice if no human responds before the deadline. The timeout response flows through the same webhook/D&R/dispatch path as a normal response, with `responder` set to `"timeout"`. +All feedback actions accept an optional timeout. If you set `timeout_seconds` (minimum 60) and no person responds before the deadline, the extension responds with a default choice. The timeout response uses the same webhook, D&R, and dispatch path as a normal response. In a timeout response, `responder` is `"timeout"`. | Parameter | Applies To | Description | |-----------|-----------|-------------| -| `timeout_seconds` | All actions | Number of seconds to wait before auto-responding (minimum 60) | -| `timeout_choice` | `request_simple_approval` | Which choice to auto-select: `approved` or `denied`. Required when `timeout_seconds` is set. | -| `timeout_content` | All actions | JSON data to include in the timeout response (overrides the per-choice content). Required for `request_question` when `timeout_seconds` is set. | +| `timeout_seconds` | All actions | Number of seconds to wait before an automatic response (minimum 60) | +| `timeout_choice` | `request_simple_approval` | The choice to select automatically: `approved` or `denied`. Necessary when you set `timeout_seconds`. | +| `timeout_content` | All actions | JSON data to include in the timeout response. It replaces the content of the choice. Necessary for `request_question` when you set `timeout_seconds`. | -For `request_acknowledgement`, the timeout choice is always `acknowledged`. For `request_question`, the timeout choice is always `answered` and `timeout_content` provides the automatic answer. +For `request_acknowledgement`, the timeout choice is always `acknowledged`. For `request_question`, the timeout choice is always `answered`, and `timeout_content` gives the automatic answer. -When a timeout is configured, the channel message includes a note like "(Auto-denied in 5 minutes if no response)" so the respondent knows the deadline. +If you configure a timeout, the channel message includes a note such as "(Auto-denied in 5 minutes if no response)". The note shows the deadline to the respondent. ## Channel Configuration -Channels are managed through the extension config, not via extension actions. You can configure channels through the LimaCharlie web UI (extension settings page), via the CLI, or through infrastructure-as-code with git-sync. +You manage channels in the extension config, not with extension actions. You can configure channels in the LimaCharlie web app (the extension settings page), with the CLI, or as infrastructure-as-code with git-sync. === "CLI" ```bash @@ -98,7 +98,7 @@ Channels are managed through the extension config, not via extension actions. Yo ``` === "Infrastructure as Code" - Channels can be managed via [git-sync](git-sync.md) by including the extension config in your synced repository: + You can manage channels with [git-sync](git-sync.md). Add the extension config to your synced repository: ```yaml # extension_config/ext-feedback channels: @@ -118,7 +118,7 @@ Channels are managed through the extension config, not via extension actions. Yo output_name: my-smtp-output ``` -For all channel types except `web`, the `output_name` field references a LimaCharlie [Tailored Output](../../outputs/index.md) that holds the credentials for the channel. +For all channel types except `web`, the `output_name` field refers to a LimaCharlie [Tailored Output](../../outputs/index.md) that holds the credentials for the channel. ## Sending Feedback Requests @@ -172,7 +172,7 @@ The response includes: } ``` -The `url` is the shareable link to the web UI where the respondent can answer. For Slack, Telegram, Microsoft Teams, and email channels, no URL is returned in the response -- the message is sent directly to the configured channel. +The `url` is the link to the web UI where the respondent answers. You can share this link. For Slack, Telegram, Microsoft Teams, and email channels, the response contains no URL. The extension sends the message directly to the configured channel. ### Acknowledgement @@ -250,7 +250,7 @@ The response event includes `choice: "answered"` and a `text` field with the res ### D&R Rule Example -A D&R rule can request human approval before taking automated action. The response is dispatched to a playbook that performs the action. +A D&R rule can request human approval before an automated action. The extension sends the response to a playbook that does the action. **Detection:** @@ -282,11 +282,11 @@ value: /usr/bin/suspicious-tool timeout_choice: '{{ "denied" }}' ``` -The `timeout_seconds: 300` and `timeout_choice: "denied"` ensure the rule auto-denies if no one responds within 5 minutes, preventing the workflow from hanging indefinitely. +The `timeout_seconds: 300` and `timeout_choice: "denied"` values make sure that the rule denies automatically if no person responds in 5 minutes. The workflow does not wait forever. ### Playbook Example -A playbook can request approval during execution: +A playbook can request approval while it runs: ```python def playbook(sdk, data): @@ -315,33 +315,33 @@ def playbook(sdk, data): ## Response Flow -1. A feedback request is created and stored with a 7-day TTL -2. The question is delivered via the configured channel (Slack message or web URL) -3. The respondent clicks a button or submits a text response (or the timeout fires if configured) -4. The response is routed through the organization's webhook adapter (authenticated via `lc-secret` header) -5. A D&R rule matches the response event and triggers the extension's `process_response` action -6. The extension atomically claims the request (preventing duplicate processing) and dispatches the response to the configured destination +1. The extension creates the feedback request and stores it with a 7-day TTL +2. The extension delivers the question through the configured channel (a Slack message or a web URL) +3. The respondent clicks a button or sends a text response (or the timeout occurs, if you configured one) +4. The response goes through the webhook adapter of the organization (the `lc-secret` header authenticates it) +5. A D&R rule matches the response event and triggers the `process_response` action of the extension +6. The extension claims the request atomically (this stops duplicate processing) and sends the response to the configured destination -If a timeout is configured and no human responds before the deadline, the system automatically sends a response with the configured default choice. The timeout response includes `responder: "timeout"` so downstream automation can distinguish it from human responses. +If you configure a timeout and no person responds before the deadline, the extension sends a response with the configured default choice. The timeout response includes `responder: "timeout"`. Downstream automation can use this value to tell a timeout response from a human response. -Feedback requests expire after **7 days**. Expired requests show an error in the web UI and are rejected by the extension. +Feedback requests expire after **7 days**. An expired request shows an error in the web UI, and the extension rejects it. -Responses are protected against replay: once a response is processed, any duplicate deliveries (from webhook retries or replay) are rejected. This also prevents races between a human response and a timeout firing simultaneously -- whichever is processed first claims the request. +The extension protects responses against replay. After it processes a response, it rejects duplicate deliveries from webhook retries or replay. This also stops a race between a human response and a timeout that occur at the same time. The first response that the extension processes claims the request. ## Slack Setup To use Slack channels: -1. Create a Slack App with "Interactivity & Shortcuts" enabled +1. Create a Slack App and enable "Interactivity & Shortcuts" 2. Set the Request URL to the Slack callback endpoint: `https://feedback-system.limacharlie.io/callback/slack` -3. Install the app to your Slack workspace and note the Bot User OAuth Token +3. Install the app in your Slack workspace and record the Bot User OAuth Token 4. In LimaCharlie, create a [Slack Tailored Output](../../outputs/destinations/slack.md) with: - `slack_api_token`: the Bot User OAuth Token - `slack_channel`: the target channel (e.g. `#security-ops`) -5. Add a Slack channel to your extension config referencing the output name (see [Channel Configuration](#channel-configuration)). For example, a channel with `name: "ops"`, `channel_type: "slack"`, and `output_name: "my-slack-output"`. +5. Add a Slack channel to your extension config that refers to the output name. For more information, see [Channel Configuration](#channel-configuration). For example, use a channel with `name: "ops"`, `channel_type: "slack"`, and `output_name: "my-slack-output"`. !!! note - For `request_question` feedback type, Slack shows a "Respond" button that links to the web UI, since Slack interactive messages do not support inline text input fields. + For the `request_question` feedback type, Slack shows a "Respond" button that links to the web UI. Slack interactive messages do not support inline text input fields. ## Telegram Setup @@ -350,12 +350,12 @@ To use Telegram channels, you need a Telegram bot and a LimaCharlie Tailored Out ### Step 1: Create a Telegram Bot 1. Open Telegram and start a conversation with [**@BotFather**](https://t.me/BotFather) ([Telegram Bot API documentation](https://core.telegram.org/bots#botfather)) -2. Send `/newbot` and follow the prompts to choose a name and username -3. BotFather will respond with a **bot token** (e.g. `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`). Save this token. -4. Add the bot to the Telegram group or channel where you want feedback messages delivered -5. Get the **chat ID** of the group or channel. You can do this by: - - Adding the bot to the group, sending a message, then checking `https://api.telegram.org/bot/getUpdates` for the `chat.id` field - - For channels, the chat ID is typically a negative number like `-1001234567890` +2. Send `/newbot`. Obey the prompts to choose a name and a username. +3. BotFather responds with a **bot token** (e.g. `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`). Save this token. +4. Add the bot to the Telegram group or channel that receives the feedback messages +5. Get the **chat ID** of the group or channel: + - Add the bot to the group, send a message, then look for the `chat.id` field at `https://api.telegram.org/bot/getUpdates` + - For channels, the chat ID is usually a negative number such as `-1001234567890` For more information, see the [Telegram Bot API documentation](https://core.telegram.org/bots/api). @@ -368,7 +368,7 @@ In LimaCharlie, create a Telegram [Tailored Output](../../outputs/index.md) with ### Step 3: Add a Telegram Channel -Add a channel to your extension config referencing the output name: +Add a channel to your extension config that refers to the output name: ```yaml channels: @@ -379,33 +379,33 @@ channels: ### How Telegram Responses Work -For `simple_approval` and `acknowledgement` feedback types, Telegram messages include **inline keyboard buttons** (Approve/Deny or Acknowledge) that the respondent can tap directly in the chat. The response is processed immediately without leaving Telegram. +For the `simple_approval` and `acknowledgement` feedback types, Telegram messages include **inline keyboard buttons** (Approve/Deny or Acknowledge). The respondent taps a button in the chat. The extension processes the response immediately, and the respondent stays in Telegram. -For `request_question`, a "Respond" button links to the web UI since Telegram inline keyboards do not support text input. +For `request_question`, a "Respond" button links to the web UI. Telegram inline keyboards do not support text input. -When a response is received, the original Telegram message is updated to show the choice and who responded. +When the extension receives a response, it updates the original Telegram message. The message then shows the choice and the respondent. !!! note - The extension automatically registers a webhook with the Telegram bot (using [`setWebhook`](https://core.telegram.org/bots/api#setwebhook)) to receive button-click callbacks. If the bot is also used for other webhook-based integrations, the ext-feedback webhook registration will override the existing one. Use a dedicated bot for ext-feedback if this is a concern. + The extension automatically registers a webhook with the Telegram bot to receive the callbacks from button clicks. It uses [`setWebhook`](https://core.telegram.org/bots/api#setwebhook) for this registration. If you also use the bot for other webhook integrations, the ext-feedback registration replaces the existing webhook. Use a dedicated bot for ext-feedback if this is a problem. ## Microsoft Teams Setup To use Microsoft Teams channels, you need a Teams Workflow webhook URL and a LimaCharlie Tailored Output. !!! warning "Incoming Webhooks retired" - Microsoft retired Office 365 Connectors (including Incoming Webhooks) from Teams. You must use a Power Automate Workflow as described below. + You must use a Power Automate Workflow, as described in the next steps. Microsoft retired Office 365 Connectors (including Incoming Webhooks) from Teams. ### Create a Workflow Webhook -1. In Microsoft Teams, navigate to the channel where you want feedback messages +1. In Microsoft Teams, open the channel that receives the feedback messages 2. Click **...** (More options) next to the channel name 3. Select **Workflows** -4. Search for and select the **Send webhook alerts to a channel** template +4. Find and select the **Send webhook alerts to a channel** template 5. Give the workflow a name (e.g. "LimaCharlie Feedback") and authenticate your account -6. Click **Next**, confirm the Team and Channel, then click **Add workflow** +6. Click **Next**, confirm the Team and the Channel, then click **Add workflow** 7. Copy the webhook URL from the confirmation dialog -For details, see [Create incoming webhooks with Workflows](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498). +For more information, see [Create incoming webhooks with Workflows](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498). ### Create the Tailored Output @@ -415,7 +415,7 @@ In LimaCharlie, create a Microsoft Teams [Tailored Output](../../outputs/index.m ### Add a Teams Channel -Add a channel to your extension config referencing the output name: +Add a channel to your extension config that refers to the output name: ```yaml channels: @@ -426,7 +426,7 @@ channels: ### How Teams Responses Work -Feedback requests are delivered as [Adaptive Cards](https://learn.microsoft.com/en-us/adaptive-cards/) in the Teams channel. The card displays the question and a button that opens the web approval page in a browser. Responses are collected through the web UI. +The extension delivers feedback requests as [Adaptive Cards](https://learn.microsoft.com/en-us/adaptive-cards/) in the Teams channel. The card shows the question and a button that opens the web approval page in a browser. The extension collects the responses through the web UI. ## Email Setup @@ -436,15 +436,15 @@ To use email channels, you need an SMTP server and a LimaCharlie Tailored Output In LimaCharlie, create an SMTP [Tailored Output](../../outputs/index.md) with: -- `dest_host`: SMTP server address, optionally with port (e.g. `smtp.example.com:587`). Defaults to port 587 if not specified. +- `dest_host`: the SMTP server address, with an optional port (e.g. `smtp.example.com:587`). If you do not give a port, the default is 587. - `dest_email`: the recipient email address (e.g. `soc@example.com`) - `from_email`: the sender email address (e.g. `limacharlie@example.com`) -- `username` (optional): SMTP authentication username -- `password` (optional): SMTP authentication password +- `username` (optional): the username for SMTP authentication +- `password` (optional): the password for SMTP authentication ### Add an Email Channel -Add a channel to your extension config referencing the output name: +Add a channel to your extension config that refers to the output name: ```yaml channels: @@ -455,7 +455,7 @@ channels: ### How Email Responses Work -The extension sends an HTML email containing the feedback question and a **Respond** button that links to the web approval page. Responses are collected through the web UI. +The extension sends an HTML email with the feedback question and a **Respond** button. The button links to the web approval page. The extension collects the responses through the web UI. ## Actions Reference @@ -464,7 +464,7 @@ The extension sends an HTML email containing the feedback question and a **Respo | `request_simple_approval` | Yes | Send a feedback request with Approve/Deny buttons | | `request_acknowledgement` | Yes | Send a feedback request with an Acknowledge button | | `request_question` | Yes | Send a question with a free-form text input | -| `process_response` | No | Internal: processes a response received via webhook | +| `process_response` | No | Internal: processes a response that comes through the webhook | ### request_simple_approval Parameters @@ -478,9 +478,9 @@ The extension sends an HTML email containing the feedback question and a **Respo | `ai_agent_name` | When destination is `ai_agent` | Name of the `ai_agent` hive record to start a session with | | `approved_content` | No | JSON data included when the respondent approves | | `denied_content` | No | JSON data included when the respondent denies | -| `timeout_seconds` | No | Auto-respond after this many seconds if no response (minimum 60) | -| `timeout_choice` | When `timeout_seconds` is set | Choice to auto-select on timeout: `approved` or `denied` | -| `timeout_content` | No | JSON data for the timeout response (overrides the choice's content) | +| `timeout_seconds` | No | Respond automatically after this many seconds if there is no response (minimum 60) | +| `timeout_choice` | When `timeout_seconds` is set | Choice to select automatically on timeout: `approved` or `denied` | +| `timeout_content` | No | JSON data for the timeout response. It replaces the content of the choice. | ### request_acknowledgement Parameters @@ -493,8 +493,8 @@ The extension sends an HTML email containing the feedback question and a **Respo | `playbook_name` | When destination is `playbook` | Playbook to trigger with the response | | `ai_agent_name` | When destination is `ai_agent` | Name of the `ai_agent` hive record to start a session with | | `acknowledged_content` | No | JSON data included when the respondent acknowledges | -| `timeout_seconds` | No | Auto-acknowledge after this many seconds if no response (minimum 60) | -| `timeout_content` | No | JSON data for the timeout response (overrides `acknowledged_content`) | +| `timeout_seconds` | No | Acknowledge automatically after this many seconds if there is no response (minimum 60) | +| `timeout_content` | No | JSON data for the timeout response. It replaces `acknowledged_content`. | ### request_question Parameters @@ -506,5 +506,5 @@ The extension sends an HTML email containing the feedback question and a **Respo | `case_id` | When destination is `case` | Case to add the response note to | | `playbook_name` | When destination is `playbook` | Playbook to trigger with the response | | `ai_agent_name` | When destination is `ai_agent` | Name of the `ai_agent` hive record to start a session with | -| `timeout_seconds` | No | Auto-answer after this many seconds if no response (minimum 60) | -| `timeout_content` | When `timeout_seconds` is set | JSON data used as the automatic answer on timeout (required for question type) | +| `timeout_seconds` | No | Answer automatically after this many seconds if there is no response (minimum 60) | +| `timeout_content` | When `timeout_seconds` is set | JSON data for the automatic answer on timeout. Necessary for the question type. | diff --git a/docs/5-integrations/extensions/limacharlie/git-sync.md b/docs/5-integrations/extensions/limacharlie/git-sync.md index 565a05426..b81b9f018 100644 --- a/docs/5-integrations/extensions/limacharlie/git-sync.md +++ b/docs/5-integrations/extensions/limacharlie/git-sync.md @@ -1,37 +1,37 @@ # Git Sync -The Git Sync Extension is a tool that automates the management of Infrastructure-as-Code (IaC) configurations. It simplifies the process of deploying and managing infrastructure by synchronizing changes between a Git repository and target organizations. +The Git Sync Extension automates the management of Infrastructure-as-Code (IaC) configurations. It synchronizes changes between a Git repository and target organizations. This makes the deployment and management of infrastructure less complex. **Key features:** - **Centralized Configuration:** Stores all IaC configurations in a single Git repository. -- **Recurring Apply:** Can automatically sync IaC changes between Git and LC organizations at regular intervals. -- **Recurring Export:** Can automatically export IaC from LC organizations to GitHub at regular intervals. -- **Export Request:** Allows you to export the configuration of an Organization into the Git repository. -- **Automated Deployment:** Helps automate the deployment process, reducing manual effort. -- MSSP**-Friendly:** Designed to accommodate multiple organizations within a single repository, allowing for global configurations to be shared between orgs. -- **Flexible Configuration:** Allows for customization and additional configuration directories. +- **Recurring Apply:** Can synchronize IaC changes between Git and LC organizations automatically at regular intervals. +- **Recurring Export:** Can export IaC from LC organizations to GitHub automatically at regular intervals. +- **Export Request:** Lets you export the configuration of an Organization into the Git repository. +- **Automated Deployment:** Helps automate the deployment process. This decreases manual work. +- MSSP**-Friendly:** Designed for many organizations in a single repository. Orgs can share global configurations. +- **Flexible Configuration:** Lets you customize the configuration and add more configuration directories. - **Transparent Operations:** Tracks operations through an extension Sensor. -By using `ext-git-sync`, you can streamline your IaC workflows, improve consistency, and reduce the risk of errors. +Use `ext-git-sync` to make your IaC workflows more efficient, improve consistency, and decrease the risk of errors. ## Use Cases ### Sync FROM Git -If you have a properly structured git repository containing org configurations, the extension can sync the running org configurations with the contents of the configs in git. +If your git repository has the correct structure and contains org configurations, the extension can synchronize the running org configurations with the configs in git. ![d2 (1).png "pull config(1).png"](../../../assets/images/d2-(1).png "pull_config(1).png") ### Export TO Git -Assuming you have an empty git repository, you can configure the extension to export the current org configuration to the repository. It will be placed in an `exports` subdirectory. +If you have an empty git repository, you can configure the extension to export the current org configuration to it. The extension puts the configuration in an `exports` subdirectory. ![d2 (2).png "push config(1).png"](../../../assets/images/d2-(2).png "push_config(1).png") ## Git Repo Structure -For applying org configs from a git repository, the repo must adhere to the following structure. The root of the repository must contain an `orgs` directory with `[org-id]` child directories, each containing an `index.yaml` . +To apply org configs from a git repository, the repo must obey this structure. The root of the repository must contain an `orgs` directory. The `orgs` directory must contain `[org-id]` child directories, and each one must contain an `index.yaml`. ```text . @@ -40,9 +40,9 @@ For applying org configs from a git repository, the repo must adhere to the foll └── index.yaml [required] ``` -The `index.yaml` determines which other files in the repo are included in the configuration for this org. +The `index.yaml` file decides which other files in the repo are part of the configuration for this org. -For instance, assume all of the configurations for this org were unique to this org and could be nested inside of the org's directory. +For example, assume that all configurations for this org are unique to it, and that they are inside the directory of the org. ```text . @@ -67,7 +67,7 @@ For instance, assume all of the configurations for this org were unique to this └── resources.yaml ``` -Notice that all configurations for this org are contained within the org's own directory. In this case, the `index.yaml` would simply contain references to the relative path of this org's configuration files. See below for an example of the contents of `index.yaml` for this use case. +All configurations for this org are in the directory of the org. In this case, the `index.yaml` file contains the relative paths of the configuration files for this org. The next example shows the contents of `index.yaml` for this use case. ```yaml version: 3 @@ -91,7 +91,7 @@ include: ### Sharing configurations across multiple orgs -Now, assume you have a global rule set you want to apply across many orgs. You could structure the repo similar to the example below. +Assume that you have a global rule set that you want to apply to many orgs. You can structure the repo as in the next example. ```text . @@ -107,7 +107,7 @@ Now, assume you have a global rule set you want to apply across many orgs. You c └── index.yaml ``` -The corresponding `index.yaml` at each org level would look similar to the following +The related `index.yaml` file at each org level is similar to this ```yaml version: 3 @@ -118,7 +118,7 @@ include: ### Exporting configurations -Configuration exports will be placed in a separate `exports` subdirectory to avoid overwriting configurations that are pushed across multiple organizations. +The extension puts configuration exports in a separate `exports` subdirectory. This stops the exports from overwriting configurations that you push to many organizations. ```text . @@ -146,26 +146,26 @@ Configuration exports will be placed in a separate `exports` subdirectory to avo ## Setting up Git Sync with Github -This guide walks you through the process of configuring Git synchronization between GitHub and LimaCharlie, allowing for automated deployment and version control of your security configurations. +This guide explains how to configure Git synchronization between GitHub and LimaCharlie. Git synchronization gives you automated deployment and version control of your security configurations. ### Step 0: Making a Git Sync specific SSH Key -- First create the directory +- Create the directory `mkdir -p ~/.ssh/gitsync` -- Set appropriate permissions for the directory +- Set the correct permissions on the directory `chmod 700 ~/.ssh/gitsync` -- Now generate the SSH key +- Generate the SSH key `ssh-keygen -t ed25519 -C "limacharlie-gitsync" -f ~/.ssh/gitsync/id_ed25519` ### Step 1: Generate GitHub Deploy Keys -1. Navigate to your GitHub repository -2. Click on the **Settings** tab +1. Open your GitHub repository +2. Click the **Settings** tab 3. In the left sidebar, select **Deploy keys** 4. Click the **Add deploy key** button 5. Enter a descriptive title for your key (e.g., "LimaCharlie Git Sync Integration") @@ -176,7 +176,7 @@ This guide walks you through the process of configuring Git synchronization betw ### Step 2: Store SSH Private Key in LimaCharlie 1. Log in to your LimaCharlie account -2. Navigate to the **Secret Manager** section of your Organization +2. Open the **Secret Manager** section of your Organization 3. Click **Create New Secret** 4. Choose a descriptive name for your secret (e.g., "github-deploy-key") 5. Paste the **private** part of your SSH key into the value field @@ -184,29 +184,29 @@ This guide walks you through the process of configuring Git synchronization betw ### Step 3: Configure Git Sync in LimaCharlie -1. Navigate to the **Git Sync** section in LimaCharlie +1. Open the **Git Sync** section in LimaCharlie 2. Under the **SSH Key** section, select **Secret Manager** 3. From the dropdown menu, select the secret you created in Step 2 4. Set the **user name** to `git` 5. Copy the SSH URL from your GitHub repository (found on the repository's main page, under Code) 6. Paste the SSH URL into the **repository** URL field in LimaCharlie 7. Configure the **branch** name (required) -8. Select the push and pull options which allow you to specify which items to push to or pull from Git configurations. -9. Optionally, select push and pull schedules if you wish to regularly sync or export your Infrastructure as Code configurations to and from LimaCharlie. This will create D&R rules on the backend that kick off the push and pull actions on the selected schedule/interval. +8. Select the push and pull options. These options set which items to push to or pull from Git configurations. +9. Optionally, select push and pull schedules to synchronize or export your Infrastructure as Code configurations to and from LimaCharlie at regular times. This creates D&R rules in the cloud that start the push and pull actions on the selected schedule or interval. 10. Click **save settings**. ### Step 4: Verify Integration -1. Perform a test commit to your GitHub repository by clicking "Push to Git" in the upper right corner. +1. Do a test commit to your GitHub repository. Click "Push to Git" in the upper right corner. -2. Verify that your configuration has been pushed to Github. +2. Check that your configuration is now in Github. ### Troubleshooting -If you encounter synchronization issues: +If you have synchronization problems: -- Verify that the deploy key has proper write permissions -- Ensure the correct SSH URL format is used (should begin with `git@github.com:`) -- Check that the private key in Secret Manager matches the public key added to GitHub +- Check that the deploy key has write permissions +- Make sure that the SSH URL has the correct format (it must begin with `git@github.com:`) +- Check that the private key in Secret Manager matches the public key that you added to GitHub [Infrastructure](infrastructure.md) diff --git a/docs/5-integrations/extensions/limacharlie/index.md b/docs/5-integrations/extensions/limacharlie/index.md index e680fef37..9d12696ea 100644 --- a/docs/5-integrations/extensions/limacharlie/index.md +++ b/docs/5-integrations/extensions/limacharlie/index.md @@ -1,6 +1,6 @@ # LimaCharlie Extensions -Extensions built and maintained by LimaCharlie that extend the platform with additional capabilities. +LimaCharlie builds and maintains these extensions. Each extension adds more capabilities to the platform. ## Available Extensions diff --git a/docs/5-integrations/extensions/limacharlie/infrastructure.md b/docs/5-integrations/extensions/limacharlie/infrastructure.md index 0b431b372..436862004 100644 --- a/docs/5-integrations/extensions/limacharlie/infrastructure.md +++ b/docs/5-integrations/extensions/limacharlie/infrastructure.md @@ -1,40 +1,44 @@ # Infrastructure -The Infrastructure Extension allows you to perform infrastructure-as-code (IaC) modifications to your Organization. IaC modifications can be made in the web UI or via the LimaCharlie [CLI tool](https://github.com/refractionPOINT/python-limacharlie/#configs-1). Users can create new organizations from known templates or maintain a common configuration across multiple organizations. +The Infrastructure Extension lets you make infrastructure-as-code (IaC) changes to your Organization. You can make IaC changes in the web app or with the LimaCharlie [CLI tool](https://github.com/refractionPOINT/python-limacharlie/#configs-1). You can create new organizations from known templates. You can also keep one common configuration across many organizations. > Scaling Organization Management > -> If you're a managed service company or need to manage a large number of Organizations, consider LimaCharlie's [MSSP demo setup](https://github.com/refractionPOINT/mssp-demo). +> If you are a managed service company, or if you must manage many Organizations, look at the LimaCharlie [MSSP demo setup](https://github.com/refractionPOINT/mssp-demo). ## Enabling the Infrastructure Extension -To enable the Infrastructure extension, navigate to the [Infrastructure extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-infrastructure) in the marketplace. Select the organization you wish to enable the extension for, and select **Subscribe**. +To enable the Infrastructure extension, do these steps: + +1. Open the [Infrastructure extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-infrastructure) in the marketplace. +2. Select the organization that you want to enable the extension for. +3. Select **Subscribe**. ![infra 1.png "image(234).png"](../../../assets/images/infra-1.png "image(234).png") -After clicking **Subscribe**, the Infrastructure extension should be available almost immediately. +After you select **Subscribe**, the Infrastructure extension becomes available almost immediately. > Where to start? > -> IaC can be a powerful tool for rapidly deploying and managing Organizations within LimaCharlie. We provide [example templates and configurations](https://github.com/refractionPOINT/templates) on GitHub. +> IaC deploys and manages Organizations in LimaCharlie quickly. LimaCharlie supplies [example templates and configurations](https://github.com/refractionPOINT/templates) on GitHub. ## Using the Infrastructure Extension -Once enabled, you will see an Infrastructure as Code option under the **Organization Settings** within the LimaCharlie web UI. The extension also becomes available via the REST API. +After you enable the extension, an Infrastructure as Code option shows under **Organization Settings** in the LimaCharlie web app. The extension also becomes available through the REST API. ![infra 2.png "image(240).png"](../../../assets/images/infra-2.png "image(240).png") -Within the Infrastructure As Code module, you can: +In the Infrastructure As Code module, you can do these actions: -- **Apply a New Config** to an existing organization. Changes are made additively, and are good for merging new configuration parameters into your organization. -- **Edit the Entire Configuration** for an existing organization. This is your current configuration, and can be modified directly in the web UI. -- Perform **Fetch**, **Push**, or **Push-from-file** operations. +- **Apply a New Config** to an existing organization. The extension adds the changes to the current configuration. Use this action to merge new configuration parameters into your organization. +- **Edit the Entire Configuration** for an existing organization. This is your current configuration. You can change it directly in the web app. +- Do **Fetch**, **Push**, or **Push-from-file** operations. ![infra 3.png "image(241).png"](../../../assets/images/infra-3.png "image(241).png") ## Actions via REST API -The REST interface for the Infrastructure extension mimics the CLI tool. The following REST API actions can be sent to interact with the Infrastructure extension: +The REST interface for the Infrastructure extension copies the CLI tool. Send these REST API actions to the Infrastructure extension: ```json { diff --git a/docs/5-integrations/extensions/limacharlie/integrity.md b/docs/5-integrations/extensions/limacharlie/integrity.md index 08516ffb1..8781f3ea6 100644 --- a/docs/5-integrations/extensions/limacharlie/integrity.md +++ b/docs/5-integrations/extensions/limacharlie/integrity.md @@ -1,34 +1,38 @@ # Integrity -The Integrity Extension helps you manage all aspects of file or registry integrity monitoring (FIM and RIM, respectively). This extension automates integrity checks of file system and registry values through pattern-based rules. +The Integrity Extension helps you manage file integrity monitoring (FIM) and registry integrity monitoring (RIM). The extension automates integrity checks of file system values and registry values with pattern-based rules. ## Enabling the Integrity Extension -To enable the Integrity extension, navigate to the [Integrity extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-integrity) in the marketplace. Select the Organization you wish to enable the extension for, and select **Subscribe**. +To enable the Integrity extension, do these steps: + +1. Open the [Integrity extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-integrity) in the marketplace. +2. Select the Organization that you want to enable the extension for. +3. Select **Subscribe**. ![integrity 1(1).png "image(242).png"](../../../assets/images/integrity-1(1).png "image(242).png") -After clicking **Subscribe**, the Infrastructure extension should be available almost immediately. +After you select **Subscribe**, the Infrastructure extension becomes available almost immediately. ## Using the Integrity Extension -Once enabled, you will see an **File/Reg Integrity** option under **Automation** within the LimaCharlie web UI. +After you enable the extension, a **File/Reg Integrity** option shows under **Automation** in the LimaCharlie web app. ![integrity 2.png "image(243).png"](../../../assets/images/integrity-2.png "image(243).png") -Selecting this option allows you to customize **File & Registry Integrity Monitoring** rules, as seen in the screenshot below. +Select this option to customize **File & Registry Integrity Monitoring** rules. The screenshot below shows this page. ![integrity 3.png "image(244).png"](../../../assets/images/integrity-3.png "image(244).png") -Selecting **Add Monitoring Rule** will allow you to create a FIM or RIM rule, specifying a platform, Tag(s), and pattern(s). +Select **Add Monitoring Rule** to create a FIM or RIM rule. For each rule, specify a platform, Tag(s), and pattern(s). ![integrity 4.png "image(245).png"](../../../assets/images/integrity-4.png "image(245).png") ### Rule Patterns -Patterns are file or registry patterns and support wildcards (\*, ?, +). Windows directory separators (backslash, `"\"`) must be escape with a double-slash `"\\"`. +Patterns are file patterns or registry patterns. They support the wildcards \*, ?, and +. You must escape Windows directory separators (backslash, `"\"`) with a double-slash `"\\"`. -When a FIM or RIM rule is tripped, you will see a `FIM_HIT` event in the Sensor(s) timeline. +When a FIM or RIM rule triggers, a `FIM_HIT` event shows in the Sensor(s) timeline. ![integrity 5](../../../assets/images/integrity-5.png) @@ -43,7 +47,7 @@ When a FIM or RIM rule is tripped, you will see a `FIM_HIT` event in the Sensor( #### Windows Registry Monitoring -> All registry monitoring patterns MUST begin with **\\REGISTRY**, followed by the hive and then the path or value to monitor. +> Every registry monitoring pattern MUST begin with **\\REGISTRY**. After that, give the hive and then the path or value to monitor. | Monitor for changes to system Run and RunOnce | Monitor all users for additions to a user's Run | | --- | --- | @@ -64,19 +68,19 @@ When a FIM or RIM rule is tripped, you will see a `FIM_HIT` event in the Sensor( ### Linux Support -FIM is supported on Linux systems, however, support may vary based on Linux distribution and software. +LimaCharlie supports FIM on Linux systems. The level of support can change with the Linux distribution and the software. #### Linux with eBPF Support -Linux hosts capable of running with [eBPF](https://ebpf.io/) have file notification and FIM capabilities on par with Windows and macOS. +Linux hosts that can run [eBPF](https://ebpf.io/) have the same file notification capabilities and FIM capabilities as Windows and macOS. #### Legacy Support -FIM is partially supported on systems without eBPF. Specified file expressions are actively monitored via `inotify` (as opposed to macOS and Windows, which utilize passive kernel monitoring). Due to [inotify](https://man7.org/linux/man-pages/man7/inotify.7.html) limitations, paths with wildcards are less efficient and only support monitoring up to 20 sub-directories covered by the wildcard. In addition to this, the path expressions should specify a final wildcard of *when all files under a directory need to be monitored. Omitting the final* `*` will result in only the top-level directory being monitoring. +Systems without eBPF have partial FIM support. `inotify` actively monitors the file expressions that you specify. macOS and Windows use passive kernel monitoring instead. Because of the limits of [inotify](https://man7.org/linux/man-pages/man7/inotify.7.html), paths with wildcards are less efficient. They monitor a maximum of 20 sub-directories under the wildcard. Also, a path expression must end with the `*` wildcard when you must monitor all files under a directory. If you omit the final `*`, LimaCharlie monitors only the top-level directory. ## Actions via REST API -The following REST API actions can be sent to interact with the Integrity extension: +Send these REST API actions to the Integrity extension: ### List Rules @@ -118,5 +122,5 @@ The following REST API actions can be sent to interact with the Integrity extens - [Reference: Endpoint Agent Commands](../../../8-reference/endpoint-commands.md) - [Detection and Response Examples](../../../3-detection-response/examples.md) -- [Compliance Frameworks](../../../9-ai-sessions/compliance/frameworks.md) -- FIM rules ship as part of every framework's recommended baseline (PCI DSS Req 11.5.x, HIPAA §164.312(c)(1), CMMC SI.L2-3.14.1, etc.). The Compliance plugin's `compliance-baseline-deploy` skill deploys these rules into `ext-integrity` automatically. -- [Compliance Gap Analysis](../../../9-ai-sessions/compliance/gap-analysis.md) -- Surfaces missing FIM rules per framework and flags when `ext-integrity` is not subscribed. +- [Compliance Frameworks](../../../9-ai-sessions/compliance/frameworks.md) -- FIM rules are part of the recommended baseline of every framework (PCI DSS Req 11.5.x, HIPAA §164.312(c)(1), CMMC SI.L2-3.14.1, etc.). The `compliance-baseline-deploy` skill of the Compliance plugin deploys these rules into `ext-integrity` automatically. +- [Compliance Gap Analysis](../../../9-ai-sessions/compliance/gap-analysis.md) -- Shows the missing FIM rules for each framework, and flags when `ext-integrity` is not subscribed. diff --git a/docs/5-integrations/extensions/limacharlie/lookup-manager.md b/docs/5-integrations/extensions/limacharlie/lookup-manager.md index 47ae229cf..2ff128987 100644 --- a/docs/5-integrations/extensions/limacharlie/lookup-manager.md +++ b/docs/5-integrations/extensions/limacharlie/lookup-manager.md @@ -1,12 +1,12 @@ # Lookup Manager -The Lookup Manager Extension allows you to create, maintain & automatically refresh lookups in the Organization to then reference them in Detection & Response Rules. +The Lookup Manager Extension lets you create, maintain, and automatically refresh lookups in the Organization. You can then reference these lookups in Detection & Response Rules. -The saved Lookup Configurations can be managed across tenants using Infrastructure as Code extension. To manage lookup versions across all of your tenants, update the file under the original Authenticated Resource Locator. +You can manage the saved Lookup Configurations across tenants with the Infrastructure as Code extension. To manage lookup versions across all of your tenants, update the file under the original Authenticated Resource Locator. -Every 24 hours, LimaCharlie will sync all of the lookups in the configuration. Lookups can also be manually synced by clicking the `Manual Sync` button on the extension page. When a lookup configuration is added, it will **not** be automatically synced immediately, unless you click on `Manual Sync`. +Every 24 hours, LimaCharlie syncs all of the lookups in the configuration. To sync the lookups manually, click the `Manual Sync` button on the extension page. When you add a lookup configuration, LimaCharlie does **not** sync it immediately. To sync it immediately, click `Manual Sync`. -Lookup sources can be either direct links (URLs) to a given lookup or [ARLs](../../../8-reference/authentication-resource-locator.md). +A lookup source is a direct link (URL) to a lookup, or an [ARL](../../../8-reference/authentication-resource-locator.md). Example JSON lookup: [LOLDrivers API](https://loldrivers.io/api/drivers.json) @@ -14,9 +14,9 @@ Example JSON lookup: [LOLDrivers API](https://loldrivers.io/api/drivers.json) ### Option 1: Preconfigured Lookups -LimaCharlie provides a curated list of several publicly available JSON lookups for use within your organization. These are provided in the lookup manager GUI. +LimaCharlie supplies a curated list of public JSON lookups for your organization. The lookup manager GUI shows these lookups. -See [lc-public-lookups](https://github.com/refractionpoint/lc-public-lookups) for the contents of each public lookup. +For the contents of each public lookup, see [lc-public-lookups](https://github.com/refractionpoint/lc-public-lookups). ![image (1).png "Screenshot 2024 10 22 at 13.23.35(2).png"](../../../assets/images/image-(1).png "Screenshot 2024-10-22 at 13.23.35(2).png") @@ -24,23 +24,29 @@ See [lc-public-lookups](https://github.com/refractionpoint/lc-public-lookups) fo ### Option 2: Publicly available Lookups -Giving the lookup configuration a name, the URL *or* [ARL](../../../8-reference/authentication-resource-locator.md), and clicking the Save button will create the new lookup source to sync to your lookups. +Give the lookup configuration a name and the URL *or* [ARL](../../../8-reference/authentication-resource-locator.md). Then click the Save button. LimaCharlie creates the new lookup source and syncs it to your lookups. `[github,my-org/my-repo-name/path/to/lookup]` ### Option 3: Private Lookup Repository -To use a lookup from a private Github repository you will need to make use of an [Authentication Resource Locator](../../../8-reference/authentication-resource-locator.md). +To use a lookup from a private GitHub repository, you need an [Authentication Resource Locator](../../../8-reference/authentication-resource-locator.md). -**Step 1: Create a token in GitHub** -In GitHub go to *Settings* and click *Developer settings* in the left hand side bar. +**Step 1: Create a token in GitHub.** Do these steps: -Next click *Personal access token* followed by *Generate new token*. Select repo permissions and finally *Generate token*. +1. In GitHub, go to *Settings*. +2. Click *Developer settings* in the left side bar. +3. Click *Personal access token*. +4. Click *Generate new token*. +5. Select the repo permissions. +6. Click *Generate token*. -**Step 2: Connect LimaCharlie to your GitHub Repository** -Inside of LimaCharlie, click on *Lookup Manager* in the left hand menu. Then click *Add New Lookup Configuration*. +**Step 2: Connect LimaCharlie to your GitHub Repository.** Do these steps: -Give your lookup a name and then use the token you generated with the following format linked to your repository. +1. In LimaCharlie, click *Lookup Manager* in the left menu. +2. Click *Add New Lookup Configuration*. +3. Give your lookup a name. +4. Use the token that you generated in the format below, with the link to your repository. `[github,my-org/my-repo-name/path/to/lookup,token,bfuihferhf8erh7ubhfey7g3y4bfurbfhrb]` diff --git a/docs/5-integrations/extensions/limacharlie/payload-manager.md b/docs/5-integrations/extensions/limacharlie/payload-manager.md index d566cbf64..2733f1170 100644 --- a/docs/5-integrations/extensions/limacharlie/payload-manager.md +++ b/docs/5-integrations/extensions/limacharlie/payload-manager.md @@ -1,13 +1,13 @@ # Payload Manager -[Payloads](../../../2-sensors-deployment/endpoint-agent/payloads.md), such as scripts, pre-built binaries, or other files, can be deployed to LimaCharlie sensors for any reason necessary. +You can deploy [Payloads](../../../2-sensors-deployment/endpoint-agent/payloads.md) to LimaCharlie sensors for any purpose. A payload is a script, a pre-built binary, or another file. -One method of adding payloads to an Organization is via the web UI on the payloads screen. This is suitable for ad-hoc payload needs, however does not scale past a handful of payloads, or for multiple organizations requiring access the same payload(s). +One method to add payloads to an Organization is the payloads screen in the web app. This method is suitable for ad-hoc payloads. It does not scale past a few payloads, or to many organizations that need the same payload(s). -The payload manager allows you to create, maintain, and automatically create/update payloads within your organization(s). Furthermore, payload configurations can be saved and utilized across multiple organizations using LimaCharlie's Infrastructure as Code capabilities. +The payload manager lets you create and maintain payloads in your organization(s). It also creates and updates payloads automatically. You can save payload configurations and use them across many organizations with the Infrastructure as Code capabilities of LimaCharlie. -Payloads added in the payload manager will be synced once every 24 hours per org. +LimaCharlie syncs the payloads that you add in the payload manager one time every 24 hours for each org. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs. This structure gives you full control of security operations. It also supports multi-tenant setups for managed security providers, or for enterprises that manage many departments or clients. -Infrastructure as Code (IaC) automates the management and provisioning of IT infrastructure using code, making it easier to scale, maintain, and deploy resources consistently. In LimaCharlie, IaC allows security teams to deploy and manage sensors, rules, and other security infrastructure programmatically, ensuring streamlined, repeatable configurations and faster response times, while maintaining infrastructure-as-code best practices in cybersecurity operations. +Infrastructure as Code (IaC) uses code to automate the management and provisioning of IT infrastructure. With IaC, you scale, maintain, and deploy resources consistently. In LimaCharlie, IaC lets security teams deploy and manage sensors, rules, and other security infrastructure programmatically. The result is repeatable configurations and faster response times. IaC also keeps the best practices of infrastructure-as-code in cybersecurity operations. diff --git a/docs/5-integrations/extensions/limacharlie/playbook.md b/docs/5-integrations/extensions/limacharlie/playbook.md index cfaa0688e..2e21a7848 100644 --- a/docs/5-integrations/extensions/limacharlie/playbook.md +++ b/docs/5-integrations/extensions/limacharlie/playbook.md @@ -4,35 +4,35 @@ !!! warning "Python SDK v4 only" The Playbook execution environment runs on the LimaCharlie **Python SDK v4**. - The recently released [Python SDK v5](../../../6-developer-guide/sdks/python-sdk.md) - is **not yet supported** in playbooks — write playbook code against v4 APIs. - See the [Python SDK v4 documentation](../../../6-developer-guide/sdks/python-sdk-v4.md) - for the supported `Manager` interface and module layout. + The new [Python SDK v5](../../../6-developer-guide/sdks/python-sdk.md) + is **not yet supported** in playbooks. Write playbook code against the v4 APIs. + For the supported `Manager` interface and module layout, see the + [Python SDK v4 documentation](../../../6-developer-guide/sdks/python-sdk-v4.md). -The Playbook Extension allows you to execute Python playbooks within the context of your Organization in order to automate tasks and customize more complex detections. +The Playbook Extension lets you run Python playbooks in the context of your Organization. Use playbooks to automate tasks and to customize more complex detections. -The playbooks themselves are managed in the playbook Hive Configurations and can be managed across tenants using the Infrastructure as Code extension. +You manage the playbooks in the playbook Hive Configurations. You can also manage them across tenants with the Infrastructure as Code extension. -The execution of a playbook can be triggered through the following means: +You can trigger the execution of a playbook in these ways: -1. Interactively in the web app by going to the Extensions section for the Playbook extension. -2. By issuing an `extension request` action through a [D&R rule](../../../3-detection-response/examples.md). -3. By issuing an extension request on the API directly: -4. By issuing an extension request through the Python CLI/SDK or Golang SDK. +1. Interactively in the web app. Go to the Extensions section for the Playbook extension. +2. With an `extension request` action in a [D&R rule](../../../3-detection-response/examples.md). +3. With an extension request on the API directly: +4. With an extension request through the Python CLI/SDK or Golang SDK. -This means playbooks can be issued in a fully automated fashion based on events, detections, audit messages or any other [target](../../../3-detection-response/alternate-targets.md) of D&R rules. But it can also be used in an ad-hoc fashion triggered manually. +You can therefore start a playbook automatically from events, detections, audit messages, or any other [target](../../../3-detection-response/alternate-targets.md) of D&R rules. You can also start a playbook manually for ad-hoc work. ## Enabling Extension -The Playbook extension can be enabled by subscribing your organization to the ext-playbook add-on. +To enable the Playbook extension, subscribe your organization to the ext-playbook add-on. ![Enabling Extension The Playbook extension can be enabled by subscribing your organization to the ext-playbook add-on](../../../assets/images/image(317).png) ## Accessing Playbooks -Playbooks are created, modified, and deleted via the Playbooks option located within the Automation menu. +You create, change, and delete playbooks with the Playbooks option in the Automation menu. -> Note: If you are unable to see the Playbooks option, ensure your user account has the appropriate permissions enabled. +> Note: If you cannot see the Playbooks option, make sure that your user account has the necessary permissions enabled. > > ![Playbooks are created, modified, and deleted via the Playbooks option located within the Automation menu](../../../assets/images/image(319).png) @@ -40,11 +40,11 @@ Playbooks are created, modified, and deleted via the Playbooks option located wi ## Usage -When invoking a playbook, all you need is the playbook name as defined in Hive. Optionally, a playbook can also receive a JSON dictionary object as parameters, this is useful when triggering a playbook from a D&R rule and you want to pass some context, or when passing context interactively. +To invoke a playbook, you need only the playbook name as defined in Hive. A playbook can also receive a JSON dictionary object as parameters. Use these parameters when you trigger a playbook from a D&R rule and you want to pass some context, or when you pass context interactively. ### D&R rule example -Here is an example D&R rule starting a new invocation of a playbook. +This example D&R rule starts a new invocation of a playbook. ```yaml - action: extension request @@ -82,10 +82,10 @@ print(response) ## Playbook structure -A playbook is a normal python script. The only required component is a top level function called `playbook` which takes 2 arguments: +A playbook is a normal python script. The only necessary component is a top level function called `playbook`. This function takes 2 arguments: -- `sdk`: an instance of the LC Python SDK v4 `limacharlie.Manager`, pre-authenticated to the relevant Organization based on the credentials provided, if any, `None` otherwise. -- `data`: the optional JSON dictionary provided as context to your playbook. +- `sdk`: an instance of the LC Python SDK v4 `limacharlie.Manager`. If you supply credentials, this instance is pre-authenticated to the relevant Organization. If you do not supply credentials, the value is `None`. +- `data`: the optional JSON dictionary that you supply as context to your playbook. The function must return a dictionary with the following optional keys: @@ -94,11 +94,11 @@ The function must return a dictionary with the following optional keys: 3. `detection`: a dictionary to use as detection 4. `cat`: a string to use as the category of the detection, if `detection` is specified. -This allows your playbook to return information about its execution, return data, errors or generate a detection. The python `print()` statement is not currently being returned to the caller or otherwise accessible, so you will want to use the `data` in order to return information about the execution of your playbook. +Your playbook can therefore return information about its execution, return data or errors, or generate a detection. The python `print()` statement does not go back to the caller, and you cannot access it. Use the `data` key to return information about the execution of your playbook. ### Example playbook -The following is a sample playbook that sends a webhook to an external product with a secret stored in LimaCharlie, and it returns the data as the response from the playbook. +This sample playbook sends a webhook to an external product with a secret that LimaCharlie stores. It returns the data as the response from the playbook. ```python import json @@ -134,9 +134,9 @@ def playbook(sdk, data): #### Example playbook with custom detection category -When a playbook generates a detection, you can customize the detection category name that appears in the UI by setting the `cat` field at the top level of the return dictionary. This is particularly useful when you want detections from different playbooks to have descriptive names instead of the generic "playbook-detection". +When a playbook generates a detection, you can customize the detection category name that shows in the web app. To do this, set the `cat` field at the top level of the return dictionary. Use this field to give the detections from different playbooks descriptive names, instead of the generic "playbook-detection". -The following example checks if a server sensor has missed a check-in and creates a detection with a custom category name: +This example checks if a server sensor missed a check-in. It then creates a detection with a custom category name: ```python def playbook(sdk, data): @@ -176,7 +176,7 @@ def playbook(sdk, data): } ``` -**Important:** The `cat` field must be placed at the **top level** of the return dictionary, alongside `detection`, not inside it. When this playbook creates a detection, it will appear in the Detections UI with the category name "Server-Sensor-Missing-Check-In" instead of the default "playbook-detection". +**Important:** Put the `cat` field at the **top level** of the return dictionary, next to `detection`, not inside it. When this playbook creates a detection, the detection shows in the Detections UI with the category name "Server-Sensor-Missing-Check-In", not the default "playbook-detection". **Without `cat`:** Detection appears as "playbook-detection → ext_playbook" @@ -184,19 +184,19 @@ def playbook(sdk, data): ### Execution environment -Playbooks contents are cached for short periods of time ( on the order of 10 seconds ) in the cloud. +The cloud caches the contents of playbooks for short periods of time (about 10 seconds). -Playbooks are instantiated on demand and the instance is reused for an undefined amount of time. +The cloud creates a playbook instance on demand, and it reuses the instance for an undefined amount of time. -Playbook code only executes during the main call to the `playbook` function, background on-going running is not supported. +Playbook code runs only during the main call to the `playbook` function. Background execution is not supported. -The execution environment is provisioned on a per-Organization basis, meaning all your playbooks may execute within the same container, but NEVER on a container used by another Organization. +The cloud provisions the execution environment for each Organization. All of your playbooks can run in the same container, but NEVER in a container that another Organization uses. -Although you have access to the local environment, this environment is ephemeral and can be wiped at any moment in between executions so you should take care that your playbook is self contained and doesn't assume pre-existing conditions. +Make your playbook self contained, and do not let it assume conditions that exist before it runs. You have access to the local environment, but this environment is ephemeral. The cloud can erase it at any moment between executions. A single execution of a playbook is limited to 10 minutes. -The current execution environment is based on the default libraries provided by the `python:slim` Dockerhub official container plus the following packages: +The current execution environment uses the default libraries of the official `python:slim` Dockerhub container, plus these packages: - Python - `weasyprint` @@ -215,7 +215,7 @@ The current execution environment is based on the default libraries provided by - Codex (`codex`) CLI tool - Gemini CLI (`gemini`) CLI tool -Custom packages and execution environment tweaks are not available in self-serve mode, but they *may* be available on demand, get in touch with us at . +Custom packages and changes to the execution environment are not available in self-serve mode. They *can* be available on demand. For these, contact . ## Infrastructure as Code @@ -244,4 +244,4 @@ hives: ## Billing -Playbooks are billed per seconds of total execution time. +LimaCharlie bills playbooks for each second of total execution time. diff --git a/docs/5-integrations/extensions/limacharlie/reliable-tasking.md b/docs/5-integrations/extensions/limacharlie/reliable-tasking.md index 4c0460b6c..376cfed36 100644 --- a/docs/5-integrations/extensions/limacharlie/reliable-tasking.md +++ b/docs/5-integrations/extensions/limacharlie/reliable-tasking.md @@ -1,34 +1,36 @@ # Reliable Tasking -The Reliable Tasking Extension enables you to task Sensor(s) that are currently offline. The extension queues the task in the cloud and automatically delivers it when the Sensor(s) come online. +The Reliable Tasking Extension lets you task Sensor(s) that are offline. The extension queues the task in the cloud. It delivers the task automatically when the Sensor(s) come online. ## How It Works When you create a reliable task, the extension: -1. Resolves the targeting criteria (`sid`, `tag`, or `selector`) to a list of sensors and records one queued task per sensor, with an expiry of `now + ttl`. -2. Immediately attempts delivery to the sensors that are currently online. -3. Retries delivery every time a targeted sensor reconnects to the cloud (on its `CONNECTED` event). -4. Removes the queued task for a sensor once that sensor confirms receipt of the command. +1. Resolves the targeting criteria (`sid`, `tag`, or `selector`) to a list of sensors. It records one queued task for each sensor, with an expiry of `now + ttl`. +2. Tries delivery immediately to the sensors that are online. +3. Tries delivery again each time a targeted sensor reconnects to the cloud (on its `CONNECTED` event). +4. Removes the queued task for a sensor after that sensor confirms receipt of the command. -Two properties follow from this design that are worth understanding: +This design has two results: -- **Delivery only happens while a sensor is connected.** Tasks are never pre-staged on an offline sensor; a task queued for an offline sensor exists only in the extension's queue until the sensor reconnects. -- **The TTL is evaluated at delivery time.** At every delivery attempt, expired tasks are skipped. If a sensor is offline for the entire TTL and reconnects afterwards, the task is *not* delivered — the extension has given up on it. +- **Delivery only happens when a sensor is connected.** The extension never pre-stages a task on an offline sensor. A task for an offline sensor stays only in the queue of the extension until the sensor reconnects. +- **The extension checks the TTL at delivery time.** At each delivery attempt, the extension skips expired tasks. If a sensor is offline for the full TTL and reconnects after it, the extension does *not* deliver the task. -> **Note:** The sensor commands `restart` and `upgrade_core` do not produce a receipt from the sensor, so they are considered confirmed (and removed from the queue) as soon as they are successfully sent to a connected sensor. +> **Note:** The sensor commands `restart` and `upgrade_core` do not give a receipt from the sensor. The extension marks them as confirmed, and removes them from the queue, when it sends them to a connected sensor. ## Enabling the Reliable Tasking Extension -To enable the Reliable Tasking extension, navigate to the [Reliable Tasking extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-reliable-tasking) in the marketplace. Select the Organization you wish to enable the extension for, and select **Subscribe**. +1. Open the [Reliable Tasking extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-reliable-tasking) in the marketplace. +2. Select the Organization for which you want to enable the extension. +3. Select **Subscribe**. -After clicking **Subscribe**, the Reliable Tasking extension should be available almost immediately. +After you select **Subscribe**, the Reliable Tasking extension becomes available almost immediately. ## Using the Reliable Tasking Extension -Once enabled, you will see a **Reliable Tasking** option under **Automation** within the LimaCharlie web UI. You can also interact with the extension via REST API. +After you enable the extension, a **Reliable Tasking** option shows under **Automation** in the LimaCharlie web app. You can also use the extension through the REST API. -Within the Reliable Tasking module, you can: +In the Reliable Tasking module, you can: - Task Sensor(s) - Untask Sensor(s) @@ -36,7 +38,7 @@ Within the Reliable Tasking module, you can: ## Actions via REST API -The following REST API actions can be sent to interact with the Reliable Tasking extension: +You can send these REST API actions to the Reliable Tasking extension: ### Create a Task @@ -47,27 +49,27 @@ curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-ta --data 'oid=$YOUR_OID&action=task&data={"context":"version","selector":"plat==windows","task":"run --shell-command whoami","ttl":3600}' ``` -All parameters are provided in the request body as URL-encoded form data. The `data` parameter should contain a JSON object with the following fields: +Give all parameters in the request body as URL-encoded form data. The `data` parameter must contain a JSON object with these fields: **Required Parameters:** -- `task`: The command to execute, similar to a command-line `task` (e.g., `"run --shell-command whoami"`, `"mem_map --pid 4"`) +- `task`: The command to run, similar to a command-line `task` (e.g., `"run --shell-command whoami"`, `"mem_map --pid 4"`) - One of `sid`, `tag`, or `selector` (targeting criteria): - `sid`: Target a single sensor by Sensor ID - `tag`: Target all sensors that have this tag - - `selector`: A [Sensor Selector Expression](../../../8-reference/sensor-selector-expressions.md) specifying which sensors should receive the task. Use `"*"` to target all sensors in the organization. + - `selector`: A [Sensor Selector Expression](../../../8-reference/sensor-selector-expressions.md) that specifies which sensors get the task. Use `"*"` to target all sensors in the organization. - Examples: - `"selector":"plat==windows"` - All Windows sensors - `"selector":"sid=='abc-123-def'"` - A specific sensor by ID - `"selector":"production in tags"` - All sensors with the "production" tag - - `"selector":"plat==linux and int_ip matches '^10\\.3\\..*'"` - Complex expressions using AND/OR logic + - `"selector":"plat==linux and int_ip matches '^10\\.3\\..*'"` - Complex expressions that use AND/OR logic **Optional Parameters:** -- `context`: An identifier that will be reflected in the `investigation_id` of the corresponding `RECEIPT` or `_REP` event, allowing you to craft D&R rules based on the response -- `ttl`: Time-to-live in seconds - how long the extension should keep trying to deliver the task to sensors that haven't acknowledged it. Defaults to 1 week (604800 seconds). There is no minimum value; short TTLs (even a few seconds) are valid and are a supported way to bound how late a task may be delivered. See [TTL and Delivery Guarantees](#ttl-and-delivery-guarantees). +- `context`: An identifier that shows in the `investigation_id` of the matching `RECEIPT` or `_REP` event. Use it to write D&R rules on the response. +- `ttl`: Time-to-live in seconds - how long the extension continues to try delivery to sensors that did not acknowledge the task. The default is 1 week (604800 seconds). There is no minimum value. Short TTLs, even a few seconds, are valid and are a supported way to bound how late a task can be delivered. See [TTL and Delivery Guarantees](#ttl-and-delivery-guarantees). -For more details on sensor selector syntax and available fields (`sid`, `plat`, `tags`, `hostname`, `int_ip`, etc.), see the [Sensor Selector Expressions reference](../../../8-reference/sensor-selector-expressions.md). +For more about the syntax of sensor selectors and the available fields (`sid`, `plat`, `tags`, `hostname`, `int_ip`, etc.), see the [Sensor Selector Expressions reference](../../../8-reference/sensor-selector-expressions.md). **Response:** @@ -80,10 +82,10 @@ For more details on sensor selector syntax and available fields (`sid`, `plat`, } ``` -- `task_id`: The unique ID for this tasking request across all targeted sensors. Keep it if you may need to [untask](#untask) later or correlate feedback events. -- `total_sensors`: Number of sensors matched by the targeting criteria. -- `tasked_sensors`: Sensors that were online and were sent the task immediately. -- `queued_sensors`: Sensors that were offline; the task remains queued for them until they reconnect or the TTL expires. +- `task_id`: The unique ID for this tasking request across all targeted sensors. Keep it to [untask](#untask) later or to correlate feedback events. +- `total_sensors`: The number of sensors that match the targeting criteria. +- `tasked_sensors`: The sensors that were online and got the task immediately. +- `queued_sensors`: The sensors that were offline. The task stays in the queue for them until they reconnect or the TTL expires. **Additional Examples:** @@ -123,13 +125,13 @@ curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-ta --data 'oid=$YOUR_OID&action=list&data={}' ``` -This returns the pending reliable tasks, organized per sensor and then per `task_id`, including the command, context, and expiry time of each queued task. +This action returns the pending reliable tasks, grouped by sensor and then by `task_id`. Each queued task includes the command, the context, and the expiry time. -Like `task` and `untask`, the `list` action accepts `sid`, `tag`, or `selector` to scope which sensors' queues are returned; the selector defaults to `*` (all sensors), which is why an empty `data` object works. Note that the scoping applies to *sensors*, not to the selector a task was originally created with. Tasks that have expired or have been confirmed received by the sensor are not listed. +Like `task` and `untask`, the `list` action accepts `sid`, `tag`, or `selector` to scope which queues of sensors it returns. The selector defaults to `*` (all sensors), so an empty `data` object works. The scope applies to *sensors*, not to the selector that created the task. The action does not list tasks that expired or that the sensor confirmed. ### Untask -The `untask` action deletes queued tasks, aborting delivery of ALL tasks that fit the given criteria. Use it to cancel tasks that have not yet been delivered (e.g., to sensors that are still offline). +The `untask` action deletes queued tasks. It stops delivery of ALL tasks that match the given criteria. Use it to cancel tasks that the extension did not yet deliver, for example tasks for sensors that are still offline. ```bash curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-tasking' \ @@ -140,8 +142,8 @@ curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-ta **Parameters:** -- One of `sid`, `tag`, or `selector` is required and scopes which sensors to untask (same semantics as `task`; use `"*"` to cover all sensors). -- `task_id` (optional): Only remove tasks with this task ID (as returned by the `task` action). If omitted, ALL queued tasks on the matching sensors are removed. +- One of `sid`, `tag`, or `selector` is necessary. It scopes which sensors to untask, with the same meaning as in `task`. Use `"*"` to cover all sensors. +- `task_id` (optional): Remove only the tasks with this task ID, as returned by the `task` action. If you omit it, the action removes ALL queued tasks on the matching sensors. **Response:** @@ -151,11 +153,11 @@ curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-ta } ``` -`deleted` is the number of queued task records that were actually removed. +`deleted` is the number of queued task records that the action removed. **Examples:** -Cancel a specific tasking request everywhere it is still queued: +Cancel one tasking request on every sensor where it is still in the queue: ```bash curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-tasking' \ @@ -173,34 +175,34 @@ curl --location 'https://api.limacharlie.io/v1/extension/request/ext-reliable-ta --data 'oid=$YOUR_OID&action=untask&data={"sid":"sensor-123-abc"}' ``` -Untasking removes tasks from the delivery queue, which is the only place a not-yet-delivered task exists — so once `untask` returns, a queued task can no longer be delivered. A task that has already been delivered to a connected sensor cannot be recalled. +The `untask` action removes tasks from the delivery queue. The queue is the only place where a task that is not yet delivered exists. After `untask` returns, the extension cannot deliver the queued task. You cannot recall a task that the extension already delivered to a connected sensor. ## TTL and Delivery Guarantees -The `ttl` is the authoritative bound on how late a task may be delivered: +The `ttl` is the authoritative bound on how late the extension can deliver a task: -- The expiry (`creation time + ttl`) is checked at every delivery attempt. Once expired, a task is never delivered, including to a sensor that reconnects after the TTL has elapsed. -- There is no minimum TTL. If you need "run this within the next 2 minutes or not at all", `"ttl":120` does exactly that. -- Expired tasks do not appear in `list` results and require no cleanup, though calling `untask` on them is harmless. +- The extension checks the expiry (`creation time + ttl`) at each delivery attempt. After a task expires, the extension never delivers it, even to a sensor that reconnects after the TTL. +- There is no minimum TTL. For "run this in the next 2 minutes or not at all", `"ttl":120` does exactly that. +- Expired tasks do not show in `list` results and need no cleanup. A call to `untask` on them causes no problem. -If you are implementing your own timeout on top of reliable tasking (e.g., marking a task as failed after N seconds), the recommended pattern is: +To build your own timeout on top of reliable tasking, for example to mark a task as failed after N seconds, use this pattern: -1. Create the task with `ttl` set to your timeout. This guarantees the platform will not deliver it after your deadline. -2. Optionally call `untask` with the `task_id` when you declare the timeout, as immediate cleanup. +1. Create the task with `ttl` set to your timeout. The platform then does not deliver the task after your deadline. +2. Call `untask` with the `task_id` when you declare the timeout. This step is optional and cleans up immediately. -One caveat: the TTL bounds when delivery *starts*, not when results arrive. A sensor that reconnects just before expiry can still receive the task, and its `RECEIPT`/`_REP` events may arrive after your deadline. Design your response handling (D&R rules, `context` matching) to tolerate a late receipt for a task delivered near the end of its TTL. +The TTL bounds when delivery *starts*, not when results arrive. A sensor that reconnects just before the expiry can still get the task. Its `RECEIPT` and `_REP` events can arrive after your deadline. Make your response handling (D&R rules, `context` matching) accept a late receipt for a task that the extension delivered near the end of its TTL. ## Monitoring Task Delivery -The extension reports its activity as events in your organization through a webhook Adapter named `ext-reliable-tasking` (installed automatically on subscription). Each event's type reflects the action: +The extension reports its activity as events in your organization. It uses a webhook Adapter named `ext-reliable-tasking`, which LimaCharlie installs automatically when you subscribe. The type of each event shows the action: -- `add_task`: A new tasking request was recorded (includes `task_id`, targeting criteria, and `ttl`) -- `try_task`: A targeted sensor is online and delivery is being attempted -- `task_sent`: The task was sent to the sensor (includes `sid` and `task_id`) -- `task_done`: The sensor confirmed receipt; the task is removed from the queue -- `task_failure`: Sending the task to a sensor failed (includes the error) +- `add_task`: The extension recorded a new tasking request (includes `task_id`, the targeting criteria, and `ttl`) +- `try_task`: A targeted sensor is online, and the extension tries delivery +- `task_sent`: The extension sent the task to the sensor (includes `sid` and `task_id`) +- `task_done`: The sensor confirmed receipt, and the extension removed the task from the queue +- `task_failure`: The extension failed to send the task to a sensor (includes the error) -These events can be used in D&R rules to track fleet-wide completion or alert on failures, for example: +Use these events in D&R rules to track completion across the fleet or to alert on failures. For example: ```yaml detect: @@ -215,11 +217,11 @@ respond: ## Capturing Task Responses -If you're using reliable tasks to issue commands across your sensors, you're probably going to want to view or act on the responses from these commands as well. +If you use reliable tasks to send commands to your sensors, you can also see or act on the responses to these commands. -If you add a value to the `context` parameter in the extension request, this value will be reflected in the `investigation_id` of the corresponding `RECEIPT` or `_REP` event, allowing you to craft a D&R rule based on the response. +If you add a value to the `context` parameter in the extension request, that value shows in the `investigation_id` of the matching `RECEIPT` or `_REP` event. You can then write a D&R rule on the response. -The above example cURL command has a `context` of `version` so the below D&R rule looks for that value. +The example cURL command above has a `context` of `version`. The D&R rule below looks for that value. ### Example detect block @@ -241,15 +243,15 @@ value: version ## Fanning Out at Scale -A single `task` request fans out server-side: the extension resolves the `tag` or `selector` to the full sensor list, queues one task per sensor, and paces the deliveries itself. To send one command to many sensors, make **one** API call with a `tag` or `selector` — do not loop over sensors making one call per `sid`. +One `task` request fans out on the server. The extension resolves the `tag` or the `selector` to the full list of sensors, queues one task for each sensor, and paces the deliveries. To send one command to many sensors, make **one** API call with a `tag` or a `selector`. Do not loop over the sensors and make one call for each `sid`. -Like all LimaCharlie REST API calls, requests to the extension endpoint are subject to per-credential API rate limits, measured over a 60-second window. A client exceeding its quota receives an `HTTP 429` response that includes `X-RateLimit-Quota` (requests allowed per window) and `X-RateLimit-Period` (window length in seconds) headers; back off and retry after the window when you receive one. With server-side fan-out, even very large deployments should only need a handful of API calls, keeping you well below the limits. +Like all LimaCharlie REST API calls, requests to the extension endpoint obey API rate limits for each credential, measured over a 60-second window. A client that exceeds its quota gets an `HTTP 429` response. The response includes the `X-RateLimit-Quota` header (requests allowed for each window) and the `X-RateLimit-Period` header (window length in seconds). After such a response, back off and retry after the window. With fan-out on the server, even large deployments need only a few API calls, which keeps you below the limits. ## Migrating Rule from legacy Service to new Extension -***Note: LimaCharlie has migrated from Services to Extensions. Legacy services are no longer supported.*** +***Note: LimaCharlie migrated from Services to Extensions. Legacy services are no longer supported.*** -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to assess if any rules reference the legacy reliable tasking service and convert them to use the extension. +The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to check if any rules reference the legacy reliable tasking service, and to convert them to use the extension. Command line to preview Reliable Tasking rule conversion: @@ -257,9 +259,9 @@ Command line to preview Reliable Tasking rule conversion: limacharlie extension convert_rules --name ext-reliable-tasking ``` -A dry-run response (default) will display the rule name being changed, a JSON of the service request rule and a JSON of the incoming extension request change. +A dry-run response (the default) shows the name of the rule that changes, a JSON of the service request rule, and a JSON of the new extension request. -To execute the change in the rule, explicitly set `--dry-run` flag to `--no-dry-run` +To apply the change to the rule, set the `--dry-run` flag to `--no-dry-run`. Command line to execute reliable tasking rule conversion: diff --git a/docs/5-integrations/extensions/limacharlie/sensor-cull.md b/docs/5-integrations/extensions/limacharlie/sensor-cull.md index 700289a32..0120c9512 100644 --- a/docs/5-integrations/extensions/limacharlie/sensor-cull.md +++ b/docs/5-integrations/extensions/limacharlie/sensor-cull.md @@ -1,32 +1,32 @@ # Sensor Cull -The Sensor Cull Extension performs continuous cleaning of "old" sensors that have not connected to an Organization within a set period of time. This is useful for environments with cloud deployments or VM/template-based deployments that may enroll sensors repeatedly, and for a short period of time. +The Sensor Cull Extension cleans up "old" sensors continuously. A sensor is old when it did not connect to an Organization in a set period of time. The extension is useful for cloud deployments, and for deployments that use VMs or templates, where sensors can enroll many times and for a short period of time. -The extension works by creating rules that describe when specified sensors should be cleaned up. +The extension uses rules that describe when to clean up the specified sensors. ## Enabling the Sensor Cull Extension -To enable the Sensor Cull extension, navigate to the [Sensor Cull extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-sensor-cull) in the LimaCharlie marketplace. +To enable the Sensor Cull extension, open the [Sensor Cull extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-sensor-cull) in the LimaCharlie marketplace. ![sensor cull 1](../../../assets/images/sensor-cull-1.png) -After clicking **Subscribe**, the Sensor Cull extension should be available almost immediately. +After you select **Subscribe**, the Sensor Cull extension becomes available almost immediately. ## Using the Sensor Cull Extension -Once enabled, you will see a **Sensor Cull** option under **Sensors** within the LimaCharlie web UI. You can also interact with the extension via REST API. +After you enable the extension, a **Sensor Cull** option shows under **Sensors** in the LimaCharlie web app. You can also use the extension through the REST API. ![sensor cull 2](../../../assets/images/sensor-cull-2.png) -Within the Sensor Cull module, you have the ability to create rules. Sensor Cull rules are run automatically once a day, and can be edited as needed. +In the Sensor Cull module, you can create rules. The extension runs Sensor Cull rules automatically one time each day. You can edit the rules when necessary. ![sensor cull 3](../../../assets/images/sensor-cull-3.png) -Each rule specifies a single sensor `tag` used as a selector for the sensors the rule applies to. A rule also has a `name` (simply used for your bookkeeping), and a `ttl` which is the number of days a sensor can remain unconnected to LimaCharlie before it becomes eligible for cleanup. +Each rule specifies one sensor `tag`. The tag selects the sensors that the rule applies to. A rule also has a `name`, which is only for your bookkeeping, and a `ttl`. The `ttl` is the number of days that a sensor can stay unconnected to LimaCharlie before the extension can clean it up. ## Actions via REST API -The following REST API actions can be sent to interact with the Sensor Cull extension: +You can send these REST API actions to the Sensor Cull extension: ### get_rules @@ -40,7 +40,7 @@ Get the list of existing rules ### run -Perform an ad-hoc cleanup. +Do an ad-hoc cleanup. ```json { @@ -50,7 +50,7 @@ Perform an ad-hoc cleanup. ### add_rule -The following example creates a rule name `my new rule` that applies to all sensors with the `vip` Tag, and cleans them up when they have not connected in 30 days. +This example creates a rule named `my new rule`. The rule applies to all sensors with the `vip` Tag, and cleans them up when they did not connect in 30 days. ```json { diff --git a/docs/5-integrations/extensions/limacharlie/usage-alerts.md b/docs/5-integrations/extensions/limacharlie/usage-alerts.md index 711658a15..ea4dc1281 100644 --- a/docs/5-integrations/extensions/limacharlie/usage-alerts.md +++ b/docs/5-integrations/extensions/limacharlie/usage-alerts.md @@ -1,26 +1,34 @@ # Usage Alerts -The usage alerts Extension allows you to create, maintain, & automatically refresh usage alert conditions for an Organization. +The usage alerts Extension lets you create, maintain, and refresh conditions for usage alerts in an Organization automatically. -For example, you can create a usage alert rule that will fire a detection when artifact downloads have reached a 1GB threshold in the last 30 days (43200 minutes). This alert will be saved as a managed rule. When the threshold is reached, a detection will be created with the following `cat`: +For example, you can create a usage alert rule that fires a detection when artifact downloads reach a 1GB threshold in the last 30 days (43200 minutes). LimaCharlie saves this alert as a managed rule. When the usage reaches the threshold, LimaCharlie creates a detection with this `cat`: `Usage alert - Output data over threshold - 1024 MB in 30.00 days` -These alert rules can be managed across tenants using the Infrastructure as Code extension. +You can manage these alert rules across tenants with the Infrastructure as Code extension. -Every hour, LimaCharlie will sync all of the usage alert rules in the configuration. They can also be manually synced by clicking the `Sync Usage Alert Rules` button on the extension page. When a usage alert rule is added, it will **not** be automatically synced immediately, unless you click on `Sync Usage Alert Rules`. +Every hour, LimaCharlie syncs all the usage alert rules in the configuration. To sync them manually, click the `Sync Usage Alert Rules` button on the extension page. When you add a usage alert rule, LimaCharlie does **not** sync it immediately, unless you click `Sync Usage Alert Rules`. -**NOTE**: The maximum timeframe is currently 43200 minutes (30 days). +**NOTE**: The maximum timeframe is 43200 minutes (30 days). ## Usage - GUI -To define a new usage alert, simply click on the `Add New Usage Alert` button in the extension UI. Give it a name, like `Output data over threshold`, select a SKU (in this case, `output_data`), a timeframe, a limit, and click `Save`. ![image(275).png "image(275).png"](../../../assets/images/image(275).png "image(275).png") +To define a new usage alert: -If you want it to be added immediately, click on the `Sync Usage Alert Rules` button. Otherwise, it will get pushed automatically at the next hour interval. +1. Click the `Add New Usage Alert` button on the extension page. +2. Give the alert a name, for example `Output data over threshold`. +3. Select a SKU, in this example `output_data`. +4. Select a timeframe and a limit. +5. Click `Save`. + + ![image(275).png "image(275).png"](../../../assets/images/image(275).png "image(275).png") + +To add the rule immediately, click the `Sync Usage Alert Rules` button. If you do not, LimaCharlie pushes the rule automatically at the next hour interval. ![image(278).png "image(278).png"](../../../assets/images/image(278).png "image(278).png") -This will create a managed D&R rule on the backend in the `dr-managed` hive and will sync automatically every hour. +This creates a managed D&R rule in the `dr-managed` hive in the cloud. The rule syncs automatically every hour. ```yaml hives: @@ -55,7 +63,7 @@ hives: ## Usage - Infrastructure as Code -If you are managing your organizations via infrastructure as code, you can also configure these rules in the `extension_config` hive. +If you manage your organizations with infrastructure as code, you can also configure these rules in the `extension_config` hive. ```yaml hives: diff --git a/docs/5-integrations/extensions/limacharlie/vulnerability-reporting.md b/docs/5-integrations/extensions/limacharlie/vulnerability-reporting.md index b69603947..7f314e9c8 100644 --- a/docs/5-integrations/extensions/limacharlie/vulnerability-reporting.md +++ b/docs/5-integrations/extensions/limacharlie/vulnerability-reporting.md @@ -1,45 +1,47 @@ # Vulnerability Reporting -The Vulnerability Reporting extension (`ext-vulnerability-reporting`) collects per-endpoint software inventories, resolves them against the LimaCharlie CVE database, enriches each finding with CISA KEV and FIRST EPSS data, scores them with environment-aware risk, tracks per-finding resolutions across rescans, and surfaces the results in the LimaCharlie web app and via the extension API. +The Vulnerability Reporting extension (`ext-vulnerability-reporting`) collects the software inventory of each endpoint and resolves it against the LimaCharlie CVE database. It enriches each finding with CISA KEV and FIRST EPSS data and scores the finding with an environment-aware risk score. It tracks the resolution of each finding across rescans. It shows the results in the LimaCharlie web app and through the extension API. -It is the first consumer of the canonical [`lc:asset:*` tag namespace](../../../2-sensors-deployment/asset-tags.md): asset criticality, exposure, environment, owner, and compliance tags are read directly off the sensors and used to prioritize findings and scope filters. +It is the first consumer of the canonical [`lc:asset:*` tag namespace](../../../2-sensors-deployment/asset-tags.md). The extension reads the asset criticality, exposure, environment, owner, and compliance tags directly from the sensors. It uses these tags to prioritize findings and to scope filters. ## What it does -1. **Inventory collection.** A scheduled per-sensor `os_packages` task runs once a day on each Windows, macOS, and Linux EDR sensor and reports the installed software set. The default `scheduled` mode installs both the schedule and an ingest D&R rule that forwards only the tracked responses for analysis. Before each package is looked up, the extension drops inventory entries that can never resolve to a CVE so they don't add noise — see [Inventory collection](#inventory-collection). -2. **CVE resolution.** Inventories are sent to `cve.limacharlie.io`, which maps each `(package_name, package_version)` pair to the set of CVEs that affect it. -3. **Enrichment.** Each CVE is joined against CISA KEV and FIRST EPSS via `cve.limacharlie.io/enrich`. KEV / EPSS / criticality multiplier are folded into a 0-100 [LC Risk](#lc-risk) score that is persisted on every finding row. -4. **Resolutions.** Every finding is implicitly **open** unless an operator records a resolution: `mitigated`, `accepted`, or `false_positive`. Resolutions are keyed by a deterministic [fingerprint](#finding-fingerprint) so they survive rescans. -5. **Daily scans.** A per-org daily tick runs three jobs: KEV-match emission, open-finding snapshot for the burndown tile, and EPSS-percentile snapshot for the per-CVE history sparkline. -6. **Surfacing.** Findings are exposed via the LimaCharlie web app's Vulnerabilities page (KPI strip, trend tiles, filter chip-bar, KEV/EPSS columns, LC Risk score, lifecycle chips, CVE / asset detail pages, exec / compliance / remediation reports) and via the extension API ([API Actions](#api-actions)). +1. **Inventory collection.** A scheduled `os_packages` task runs once a day on each Windows, macOS, and Linux EDR sensor and reports the set of installed software. The default `scheduled` mode installs both the schedule and an ingest D&R rule that forwards only the tracked responses for analysis. Before the extension looks up a package, it drops the inventory entries that can never resolve to a CVE. This keeps out noise. See [Inventory collection](#inventory-collection). +2. **CVE resolution.** The extension sends inventories to `cve.limacharlie.io`, which maps each `(package_name, package_version)` pair to the set of CVEs that affect it. +3. **Enrichment.** The extension joins each CVE against CISA KEV and FIRST EPSS through `cve.limacharlie.io/enrich`. KEV, EPSS, and the criticality multiplier become a 0-100 [LC Risk](#lc-risk) score that the extension keeps on every finding row. +4. **Resolutions.** Every finding is implicitly **open** unless an operator records a resolution: `mitigated`, `accepted`, or `false_positive`. A deterministic [fingerprint](#finding-fingerprint) keys each resolution, so the resolutions survive rescans. +5. **Daily scans.** A daily tick for each org runs three jobs: emission of KEV matches, a snapshot of open findings for the burndown tile, and a snapshot of EPSS percentiles. The EPSS snapshot supplies the sparkline that shows the history of each CVE. +6. **Surfacing.** The Vulnerabilities page of the LimaCharlie web app shows the findings. The page has a KPI strip, trend tiles, a filter chip-bar, KEV/EPSS columns, the LC Risk score, lifecycle chips, CVE and asset detail pages, and exec, compliance, and remediation reports. The extension API also exposes the findings ([API Actions](#api-actions)). -The extension is stateless aside from the per-org Spanner-backed tables (`vuln_reports`, `vuln_finding_state`, `vuln_daily_snapshots`, `vuln_epss_history`, plus rollup tables) and a small `org_value` keyed at `ext_vuln_kev_known_set`. +The extension is stateless, except for two stores. It uses the per-org Spanner-backed tables (`vuln_reports`, `vuln_finding_state`, `vuln_daily_snapshots`, `vuln_epss_history`, and rollup tables) and a small `org_value` keyed at `ext_vuln_kev_known_set`. ## Setup -Navigate to the [Vulnerability Reporting extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-vulnerability-reporting) in the marketplace. Select the organization and click **Subscribe**. +1. Go to the [Vulnerability Reporting extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-vulnerability-reporting) in the marketplace. +2. Select the organization. +3. Click **Subscribe**. -On subscription, the extension reconciles the D&R rules it owns to match the configured `scan_mode`: +When you subscribe, the extension reconciles the D&R rules that it owns to match the configured `scan_mode`: -- **`scheduled` (default):** installs the daily per-sensor `os_packages` schedule (`ext-vuln-mgmt-schedule`) and the ingest rule that forwards tracked responses to `process_packages` (`ext-vuln-mgmt-os-packages`). Right default for almost every customer. -- **`manual`:** installs no D&R rules. The operator drives tasking and forwarding themselves. Useful when scan cadence needs to be coordinated with another scheduler. -- **`all`:** installs only the ingest rule, but it forwards every `os_packages_rep` event regardless of whether the response carries the extension's tracking marker. Useful when `os_packages` is already being collected on a separate cadence. +- **`scheduled` (default):** installs the daily `os_packages` schedule for each sensor (`ext-vuln-mgmt-schedule`) and the ingest rule that forwards tracked responses to `process_packages` (`ext-vuln-mgmt-os-packages`). This is the correct default for almost every customer. +- **`manual`:** installs no D&R rules. The operator drives the tasking and the forwarding. Use this mode when the scan cadence must match another scheduler. +- **`all`:** installs only the ingest rule, but the rule forwards every `os_packages_rep` event, even when the response has no tracking marker from the extension. Use this mode when another cadence already collects `os_packages`. -Reconciliation is idempotent: changing modes on an existing subscription removes any rule the new mode does not own and upserts the rules it does. Unsubscribing removes all extension-owned rules and drops every `vuln_reports` row for the org. +Reconciliation is idempotent. When you change the mode on an existing subscription, the extension removes each rule that the new mode does not own. It then upserts the rules that the new mode owns. When you unsubscribe, the extension removes all rules that it owns and drops every `vuln_reports` row for the org. -A dedicated webhook adapter is provisioned automatically so the [emitted events](#events-emitted) have a destination on the event stream. +The extension provisions a dedicated webhook adapter automatically, so the [emitted events](#events-emitted) have a destination on the event stream. !!! info "Permissions" - The extension uses LimaCharlie's existing RBAC. Reading findings requires `extension.use` on `ext-vulnerability-reporting`. Subscribing and editing the configuration requires the standard extension management permissions. + The extension uses the existing RBAC of LimaCharlie. To read findings, you need `extension.use` on `ext-vulnerability-reporting`. To subscribe and to edit the configuration, you need the standard permissions to manage extensions. ## Configuration -The configuration is edited on the extension page in the LimaCharlie web app. All fields are optional; defaults match the table below. +You edit the configuration on the extension page in the LimaCharlie web app. All fields are optional. The defaults match the table below. | Field | Type | Default | Description | |-------|------|---------|-------------| | `scan_mode` | enum | `scheduled` | One of `scheduled`, `manual`, `all`. See [Setup](#setup). | -| `criticality_tag_overrides` | object | `{}` | Map of `{your-tag → canonical-bucket}` for organizations that already run their own asset-tag taxonomy. See [Asset Metadata](#asset-metadata). | +| `criticality_tag_overrides` | object | `{}` | Map of `{your-tag → canonical-bucket}` for organizations that already use their own taxonomy of asset tags. See [Asset Metadata](#asset-metadata). | ### Example @@ -54,18 +56,18 @@ The configuration is edited on the extension page in the LimaCharlie web app. Al } ``` -`criticality_tag_overrides` is consulted only when a sensor carries no canonical `lc:asset:criticality:*` tag. Explicit canonical tags always win, so an organization can migrate gradually. Override values must be canonical buckets; any other value is rejected at write time. +The extension uses `criticality_tag_overrides` only when a sensor carries no canonical `lc:asset:criticality:*` tag. Explicit canonical tags always win, so an organization can migrate step by step. Override values must be canonical buckets. The extension rejects any other value at write time. ## Asset metadata The extension reads sensor tags in the [`lc:asset:*` namespace](../../../2-sensors-deployment/asset-tags.md) and uses them to: - **Prioritize findings.** `lc:asset:criticality:*` is the multiplier in the LC Risk score. -- **Scope filters.** `lc:asset:env:*` and `lc:asset:exposure:*` populate filter chips on the Vulnerabilities page. -- **Surface compliance views.** `lc:asset:compliance:*` is multi-value; an asset can carry several regimes. -- **Route assignments.** `lc:asset:owner:*` is exposed on the asset detail page so downstream workflows (Cases, Outputs to Slack/Jira/etc.) have the routing target available. +- **Scope filters.** `lc:asset:env:*` and `lc:asset:exposure:*` fill the filter chips on the Vulnerabilities page. +- **Surface compliance views.** `lc:asset:compliance:*` holds more than one value, so an asset can carry several regimes. +- **Route assignments.** The asset detail page shows `lc:asset:owner:*`, so downstream workflows (Cases, Outputs to Slack, Jira, and others) have the routing target available. -When `include_tags=true` is passed to `query_endpoints` or `query_cve_vuln_hosts`, each row carries an `asset_metadata` projection of the parsed tags: +When you pass `include_tags=true` to `query_endpoints` or `query_cve_vuln_hosts`, each row carries an `asset_metadata` projection of the parsed tags: ```json { @@ -81,87 +83,87 @@ When `include_tags=true` is passed to `query_endpoints` or `query_cve_vuln_hosts } ``` -Tags with malformed values for the closed-set fields (`criticality`, `exposure`, `env`) are dropped by the parser. See [Asset Tag Namespace](../../../2-sensors-deployment/asset-tags.md) for the full schema. +The parser drops tags with malformed values for the closed-set fields (`criticality`, `exposure`, `env`). See [Asset Tag Namespace](../../../2-sensors-deployment/asset-tags.md) for the full schema. ## Inventory collection -Each daily `os_packages` scan returns the full installed-software set for a sensor, but not every entry is a meaningful vulnerability target. The extension applies two passes between the raw inventory and the CVE database: it **filters** entries that can't yield a useful CVE, and for Linux it makes matching **distro-aware**. +Each daily `os_packages` scan returns the full set of installed software for a sensor, but not every entry is a useful target for a vulnerability. The extension applies two passes between the raw inventory and the CVE database. It **filters** the entries that cannot give a useful CVE, and for Linux it makes the match **distro-aware**. ### Package filtering -Some inventory entries can never resolve to a CVE — they have no public product identifier, or their reported "version" isn't an upstream version that can be range-compared against a CVE's affected ranges. Querying them only adds noise and slows scans, so the extension skips them before the lookup. This is why the number of findings on a host is usually lower than its raw installed-package count. +Some inventory entries can never resolve to a CVE. They have no public product identifier, or their reported "version" is not an upstream version. Without an upstream version, the extension cannot compare the entry against the affected ranges of a CVE. A query for these entries only adds noise and slows scans, so the extension skips them before the lookup. For this reason, the number of findings on a host is usually lower than its raw count of installed packages. The skip classes are: | Class | Examples | Rationale | |-------|----------|-----------| -| **macOS Apple installer receipts** | `com.apple.pkg.CLTools_SDK_macOS13`, `com.apple.pkg.XProtectPlistConfigData…` (any `pkgutil` entry named `com.apple.*`) | Reverse-DNS bundle IDs for Apple system components. Not real installable products; their version slot is a build timestamp. Third-party `pkgutil` receipts (e.g. `org.wireshark.*`, `com.microsoft.*`) are deliberately **kept**. | -| **Linux distro-internal packages** | `base-files`, `lsb-base`, `ca-certificates`, `apt-utils`, `init-system-helpers`, `filesystem`, `setup`, `redhat-release`, … | Distro "essential/required" configuration packages that have no upstream product entry and never will. | -| **Windows inventory noise** | Tanium software-catalog rows (`tvcappstor-…`, `tvcfixedde-…`), hardware driver INF receipts (`Windows Driver Package - …`), .NET build toolchain / SDK / templates / targeting packs (`Microsoft .NET Toolset …`, `Microsoft.NET.Sdk.…`), Nuance TTS voice packs (`Vocalizer Expressive …`) | Either the name has no product identifier, or the version slot is an installer counter rather than the upstream version, so no CVE range comparison can succeed. | +| **macOS Apple installer receipts** | `com.apple.pkg.CLTools_SDK_macOS13`, `com.apple.pkg.XProtectPlistConfigData…` (any `pkgutil` entry named `com.apple.*`) | Reverse-DNS bundle IDs for Apple system components. These are not real installable products, and their version slot is a build timestamp. The extension **keeps** third-party `pkgutil` receipts (for example `org.wireshark.*`, `com.microsoft.*`) by design. | +| **Linux distro-internal packages** | `base-files`, `lsb-base`, `ca-certificates`, `apt-utils`, `init-system-helpers`, `filesystem`, `setup`, `redhat-release`, … | Configuration packages that the distribution marks as essential or required. They have no upstream product entry and never will. | +| **Windows inventory noise** | Tanium software-catalog rows (`tvcappstor-…`, `tvcfixedde-…`), hardware driver INF receipts (`Windows Driver Package - …`), .NET build toolchain / SDK / templates / targeting packs (`Microsoft .NET Toolset …`, `Microsoft.NET.Sdk.…`), Nuance TTS voice packs (`Vocalizer Expressive …`) | Either the name has no product identifier, or the version slot is an installer counter and not the upstream version. No comparison against a CVE range can succeed. | -Runtime components that *do* ship vulnerable code — e.g. `Microsoft .NET Runtime` and `Microsoft Windows Desktop Runtime` — are deliberately **not** skipped; only build-time artifacts and pure configuration entries are. The per-scan skipped count is logged once per batch (no per-package spam). +The extension does **not** skip the runtime components that do ship vulnerable code — for example `Microsoft .NET Runtime` and `Microsoft Windows Desktop Runtime`. It skips only build-time artifacts and pure configuration entries. The extension logs the skipped count one time for each batch, and not for each package. ### Linux distro-aware matching -Linux distributions routinely **backport** security fixes: a vendor patches a CVE in their packaged build while keeping the upstream version number unchanged. Matching such a package against upstream CVE ranges alone would flag it as vulnerable even though the distro already shipped the fix. To avoid these false positives, the extension identifies the endpoint's distribution and release and forwards them with each Linux package lookup, so distro-specific backport data can correct the verdict. +Linux distributions frequently **backport** security fixes. The vendor patches a CVE in the packaged build but keeps the upstream version number unchanged. A match of such a package against upstream CVE ranges alone flags it as vulnerable, although the distribution already shipped the fix. To stop these false positives, the extension identifies the distribution and the release of the endpoint. It sends them with each lookup of a Linux package. Distro-specific backport data can then correct the verdict. -The distro and release are detected in priority order: +The extension detects the distro and the release in this order of priority: -1. **`lc:asset:os:-` sensor tag** (authoritative). For example `lc:asset:os:debian-11` or `lc:asset:os:redhat-enterprise-9`. The value is split on the **last** `-`, so distro names containing a dash survive intact. Setting this tag explicitly gives the most reliable results. -2. **Marker-package version.** When no tag is present, the release is inferred from a distribution marker package — Debian's `base-files` major version (10 = buster, 11 = bullseye, 12 = bookworm, 13 = trixie), or the RHEL/CentOS/Rocky/AlmaLinux `*-release` / `fedora-release` package version. -3. **Package source, no release.** As a last resort the package source pins the distro family only (`dpkg` → Debian, `rpm` → RHEL). With no release, matching falls back to upstream-only verdicts (fail-open) rather than guessing. +1. **`lc:asset:os:-` sensor tag** (authoritative). For example, `lc:asset:os:debian-11` or `lc:asset:os:redhat-enterprise-9`. The extension splits the value on the **last** `-`, so a distro name that contains a dash stays intact. This tag gives the most reliable results. +2. **Marker-package version.** When there is no tag, the extension infers the release from a marker package of the distribution. For Debian, this is the major version of `base-files` (10 = buster, 11 = bullseye, 12 = bookworm, 13 = trixie). For RHEL, CentOS, Rocky, and AlmaLinux, this is the version of the `*-release` or `fedora-release` package. +3. **Package source, no release.** As a last resort, the package source pins the distro family only (`dpkg` → Debian, `rpm` → RHEL). With no release, the match falls back to upstream-only verdicts (fail-open) and does not guess. -Endpoints the extension can't pin to a release still get upstream CVE matching; they just don't benefit from backport correction. Tagging Linux fleets with `lc:asset:os:*` (for example via `limacharlie tag mass-add` keyed off an installation key or hostname pattern) is the simplest way to get accurate, backport-aware Linux results. +Endpoints that the extension cannot pin to a release still get upstream CVE matching, but they do not get the backport correction. To get accurate, backport-aware results on Linux, tag your Linux fleet with `lc:asset:os:*`. For example, use `limacharlie tag mass-add` keyed on an installation key or a hostname pattern. ## Concepts ### Lifecycle states -A finding has exactly one of two postures: **open** (the default — there is no resolution row) or **resolved** (a row exists in `vuln_finding_state` carrying one of three resolutions). Resolutions are keyed by a [fingerprint](#finding-fingerprint), so they survive rescans. +A finding has exactly one of two postures: **open** (the default, because there is no resolution row) or **resolved** (a row exists in `vuln_finding_state` and carries one of three resolutions). A [fingerprint](#finding-fingerprint) keys each resolution, so resolutions survive rescans. | Posture | `resolution` | Description | |---------|--------------|-------------| -| open | — (no row) | New finding. Implicit; nothing is persisted. | -| resolved | `mitigated` | Compensating control in place; finding is no longer counted as exploitable. Sets `resolved_at` (used by MTTR). | -| resolved | `accepted` | Risk has been formally accepted as an exception, optionally with an `expires_at`. Lapses back into the open count when `expires_at` is in the past. | -| resolved | `false_positive` | Confirmed not applicable (resolver mis-mapped the package, etc.). | +| open | — (no row) | New finding. Implicit; the extension persists nothing. | +| resolved | `mitigated` | A compensating control is in place, and the finding no longer counts as exploitable. Sets `resolved_at`, which MTTR uses. | +| resolved | `accepted` | The business formally accepted the risk as an exception, with an optional `expires_at`. The finding returns to the open count when `expires_at` is in the past. | +| resolved | `false_positive` | Confirmed not applicable. For example, the resolver mapped the package incorrectly. | -The resolution row carries six columns: `resolution`, `expires_at`, `case_number`, `resolved_at`, `resolved_by`, `updated_at`. There is no per-finding audit log — re-running `set_finding_resolution` overwrites in place. To **reopen** a finding, call `set_finding_resolution` with `resolution: null`; this deletes the row. +The resolution row carries six columns: `resolution`, `expires_at`, `case_number`, `resolved_at`, `resolved_by`, `updated_at`. There is no audit log for each finding. A second call to `set_finding_resolution` overwrites the row in place. To **reopen** a finding, call `set_finding_resolution` with `resolution: null`. This deletes the row. -`case_number` is reserved for an upcoming ext-cases linkage. It is plumbed end-to-end but not surfaced in the UI today; an operator opening a case from a finding will eventually have the case number persisted here so the resolution row points at the case carrying the richer metadata. +`case_number` is reserved for an upcoming linkage to ext-cases. It is plumbed end-to-end, but the UI does not show it today. When an operator opens a case from a finding, the extension will keep the case number here. The resolution row then points at the case that carries the richer metadata. #### Lapsed acceptance -`accepted` is the only resolution that supports an `expires_at`. When `expires_at` is in the past at read time the UI derives a **lapsed acceptance** signal — the row is rendered with the same urgency as an open finding and surfaces in the lapsed-exception views. The Spanner row itself is **not** mutated; the lapsed signal is purely a `resolution === 'accepted' && expires_at < now` check at read time, so auditors can still see when and why the exception was originally granted. +`accepted` is the only resolution that supports an `expires_at`. When `expires_at` is in the past at read time, the UI derives a **lapsed acceptance** signal. The UI renders the row with the same urgency as an open finding and shows it in the views for lapsed exceptions. The extension does **not** change the Spanner row. The lapsed signal is only a `resolution === 'accepted' && expires_at < now` check at read time. Auditors can therefore still see when the exception was granted and why. #### Scope (org vs host) -Resolution rows are written at one of two scopes: +The extension writes resolution rows at one of two scopes: -- **`org`** — applies to every host carrying the same `(cve, normalized_package_name)`. Use when the suppression is package-wide ("we accept this CVE for `openssl` everywhere until the next quarterly upgrade"). -- **`host`** — applies to one specific `(cve, normalized_package_name, sid)`. Use when the rationale is host-specific ("this dev workstation is allowed to keep the older `curl` until reimage"). +- **`org`** — applies to every host that carries the same `(cve, normalized_package_name)`. Use this scope when the suppression covers a package everywhere ("we accept this CVE for `openssl` everywhere until the next quarterly upgrade"). +- **`host`** — applies to one `(cve, normalized_package_name, sid)`. Use this scope when the rationale is specific to one host ("this dev workstation is allowed to keep the older `curl` until reimage"). -Read-overlay precedence: a host-scope row beats an org-scope one for the matching row. Both use the same fingerprint algorithm; the host fingerprint mixes in the `sid`. +Precedence in the read overlay: a host-scope row beats an org-scope row for the matching row. Both scopes use the same fingerprint algorithm, but the host fingerprint also mixes in the `sid`. ### Finding fingerprint -A fingerprint is a SHA-256 hex digest that gives a finding a stable identity across rescans, reboots, and partial reinstalls. The inputs are NUL-separated: +A fingerprint is a SHA-256 hex digest that gives a finding a stable identity across rescans, reboots, and partial reinstalls. NUL characters separate the inputs: - **Org scope:** `SHA-256(cve + "\x00" + normalized_package_name)` - **Host scope:** `SHA-256(cve + "\x00" + sid + "\x00" + normalized_package_name)` -`normalized_package_name` is the resolver's canonical product name — e.g. both "Google - Chrome" and "Google Chrome" normalize to `chrome` — so a per-org "accept this risk for chrome" mark applies to both. Clients never compute fingerprints; the backend derives them from the canonical inputs and echoes them on the response. Frontends that already have a fingerprint can pass it back in directly. +`normalized_package_name` is the canonical product name of the resolver. For example, both "Google - Chrome" and "Google Chrome" normalize to `chrome`, so an org-scope mark "accept this risk for chrome" applies to both. Clients never compute fingerprints. The backend derives them from the canonical inputs and echoes them on the response. A frontend that already has a fingerprint can pass it back in directly. ### LC Risk -LC Risk is a 0-100 composite score the extension uses as the canonical prioritization key across the Vulnerabilities surface. It is computed at scan time during `ApplySensorReports` (when a sensor's resolved CVE set is being written to `vuln_reports`) and persisted on the row, so list-view sorts and filters do not have to recompute it on every read. +LC Risk is a composite score from 0 to 100. The extension uses it as the canonical key to prioritize findings across the Vulnerabilities surface. The extension computes the score at scan time during `ApplySensorReports`, when it writes the resolved CVE set of a sensor to `vuln_reports`. It keeps the score on the row, so sorts and filters in the list view do not compute it again on every read. #### Inputs -- The row's CVSS severity (`critical` / `high` / `medium` / `low`). -- The CVE's EPSS percentile, fetched from `/enrich`. -- KEV membership for the CVE, also from `/enrich`. -- The host's `lc:asset:criticality:*` multiplier, parsed from the sensor's tags via the canonical [`lc:asset:*` namespace](../../../2-sensors-deployment/asset-tags.md). +- The CVSS severity of the row (`critical` / `high` / `medium` / `low`). +- The EPSS percentile of the CVE, fetched from `/enrich`. +- The KEV membership of the CVE, also from `/enrich`. +- The `lc:asset:criticality:*` multiplier of the host. The extension parses it from the sensor tags in the canonical [`lc:asset:*` namespace](../../../2-sensors-deployment/asset-tags.md). #### Formula @@ -175,19 +177,19 @@ SEVERITY_RANK: critical=4, high=3, medium=2, low=1, unknown=0 CRITICALITY_MULT (backend): critical=1.6, high=1.3, medium=1.0, low=0.6, unknown=1.0 ``` -A row whose host has no canonical `lc:asset:criticality:*` tag (and whose org has no matching override) uses multiplier `1.0`. +A row whose host has no canonical `lc:asset:criticality:*` tag, and whose org has no matching override, uses the multiplier `1.0`. !!! warning "Frontend / backend `low` multiplier mismatch" - The backend's `low` multiplier is `0.6`; the frontend's hardcoded preview formula in `src/utils/lcRisk.ts` uses `0.8`. The persisted `lc_risk` and `max_lc_risk` columns (what API responses and sorted UI columns read) are authoritative. The frontend constant only matters for client-side previews when the persisted value is missing. + The `low` multiplier of the backend is `0.6`. The hardcoded preview formula of the frontend, in `src/utils/lcRisk.ts`, uses `0.8`. The persisted `lc_risk` and `max_lc_risk` columns are authoritative, and API responses and sorted UI columns read them. The frontend constant is important only for previews on the client when the persisted value is missing. #### Persistence -- **Per-host:** `vuln_reports.lc_risk` (one int per `(sensor, package, CVE)` row). -- **Org rollup:** `vuln_cve_counts.max_lc_risk` (max across all hosts for one CVE in the org). Returned as `max_lc_risk` on `query_cves` rows. +- **Per-host:** `vuln_reports.lc_risk` (one int for each `(sensor, package, CVE)` row). +- **Org rollup:** `vuln_cve_counts.max_lc_risk` (the maximum across all hosts for one CVE in the org). `query_cves` rows return it as `max_lc_risk`. #### Buckets -The web app colour-buckets the score for badges: +The web app gives the score a colour bucket for badges: | Bucket | LC Risk | |--------|---------| @@ -198,77 +200,77 @@ The web app colour-buckets the score for badges: ### KEV (CISA Known Exploited Vulnerabilities) -The extension surfaces the CISA KEV catalogue per CVE. Fields exposed (from `cve.limacharlie.io/enrich`): +The extension shows the CISA KEV catalogue for each CVE. These fields come from `cve.limacharlie.io/enrich`: | Field | Type | Description | |-------|------|-------------| | `in_kev` | bool | True when the CVE is in the catalogue. | -| `added` | string (YYYY-MM-DD) | Date CISA added the CVE. | -| `due` | string (YYYY-MM-DD) | CISA's mandated remediation deadline (federal civilian agencies). | -| `vendor` | string | Vendor as listed by CISA. | -| `product` | string | Product as listed by CISA. | -| `name` | string | Vulnerability name as listed by CISA. | -| `ransomware` | bool | `true` iff CISA flagged "Known" ransomware-campaign use. | +| `added` | string (YYYY-MM-DD) | The date when CISA added the CVE. | +| `due` | string (YYYY-MM-DD) | The remediation deadline that CISA mandates (federal civilian agencies). | +| `vendor` | string | The vendor as CISA lists it. | +| `product` | string | The product as CISA lists it. | +| `name` | string | The name of the vulnerability as CISA lists it. | +| `ransomware` | bool | `true` if and only if CISA flagged "Known" ransomware-campaign use. | -The KEV dataset is refreshed daily by the `vulnerability-db` ingest job. The data lives in Redis under the `kev:*` namespace and a refresh does not bust the resolver result cache — KEV/EPSS are fetched on the side via `/enrich`, not folded into `/cves`. +The `vulnerability-db` ingest job refreshes the KEV dataset daily. The data lives in Redis under the `kev:*` namespace. A refresh does not invalidate the result cache of the resolver. The extension fetches KEV and EPSS on the side through `/enrich` and does not fold them into `/cves`. ### EPSS (FIRST Exploit Prediction Scoring System) -Every CVE is also scored by FIRST.org's EPSS model. Fields exposed: +FIRST.org's EPSS model also scores every CVE. These fields are exposed: | Field | Type | Description | |-------|------|-------------| -| `score` | float [0,1] | Probability of in-the-wild exploitation in the next 30 days. | -| `percentile` | float [0,1] | Rank among all CVEs scored on this date. | +| `score` | float [0,1] | The probability of exploitation in the wild in the next 30 days. | +| `percentile` | float [0,1] | The rank among all CVEs scored on this date. | EPSS is also refreshed daily. ### EPSS history (90-day series) -EPSS percentile drifts as new exploit telemetry lands. The extension captures a daily snapshot for each CVE the org has at least one finding on, persisted to `vuln_epss_history` keyed by `(oid, cve, snapshot_date)`. The capture happens during the daily Update tick (see [Daily Update tick](#daily-update-tick)). +The EPSS percentile drifts as new exploit telemetry arrives. The extension captures a daily snapshot for each CVE that has at least one finding in the org. It persists the snapshot to `vuln_epss_history`, keyed by `(oid, cve, snapshot_date)`. The capture happens during the daily Update tick (see [Daily Update tick](#daily-update-tick)). -The frontend's CVE detail page renders a 90-day sparkline next to the live percentile, backed by `query_epss_history`. The default 90-day window matches the sparkline; pass a larger `days` (up to 365) to backfill a longer view for reports. +The CVE detail page of the frontend renders a 90-day sparkline next to the live percentile, backed by `query_epss_history`. The default window of 90 days matches the sparkline. Pass a larger `days` value (up to 365) to backfill a longer view for reports. -CVEs that the org has never had a finding on are not retained — there is no historical series to query for them. CVEs whose findings have all closed retain the snapshots already captured during their open period. +The extension does not keep CVEs that the org never had a finding on, because there is no historical series to query for them. CVEs whose findings are all closed keep the snapshots that the extension captured while the findings were open. ### Daily snapshots -`vuln_daily_snapshots` is the per-day open-finding count by severity. The daily Update tick streams every `vuln_reports` row for the org, applies the resolution overlay (suppressing any row that has a resolution row that is **not** lapsed-accepted), and writes one row per `(snapshot_date, severity)` carrying: +`vuln_daily_snapshots` holds the count of open findings for each day, by severity. The daily Update tick streams every `vuln_reports` row for the org and applies the resolution overlay. The overlay suppresses each row that has a resolution row that is **not** a lapsed acceptance. The tick then writes one row for each `(snapshot_date, severity)` pair, which carries: -- `open_count` — total open findings in the bucket. -- `kev_count` — subset of `open_count` whose CVE is in KEV at the time of capture. +- `open_count` — the total of open findings in the bucket. +- `kev_count` — the subset of `open_count` whose CVE is in KEV at the time of capture. -A bucket with zero findings is still written on a quiet day so the burndown sparkline has continuity. Resolved findings are excluded by design — the snapshot represents "what the operator still owes," not "every CVE the resolver ever returned." Lapsed acceptances (where `expires_at` is in the past) flip back into the open count. +On a quiet day, the extension still writes a bucket that has zero findings, so the burndown sparkline is continuous. The design excludes resolved findings, because the snapshot shows what the operator still owes, and not every CVE that the resolver ever returned. Lapsed acceptances, where `expires_at` is in the past, flip back into the open count. ### Daily Update tick -The platform scheduler (`legion_extension_manager` / `legion_scheduler`'s `ext-update-event` cron) fires `EventTypes.Update` once per subscribed org per day, spread across 24h via `MultiplexOID`. The handler runs three scans sequentially with an independent 10-minute timeout per scan; one scan's failure does not suppress the others. +The platform scheduler (the `ext-update-event` cron of `legion_extension_manager` / `legion_scheduler`) fires `EventTypes.Update` once a day for each subscribed org. `MultiplexOID` spreads the ticks across 24h. The handler runs three scans in sequence with an independent timeout of 10 minutes for each scan. A failure of one scan does not suppress the others. | Order | Scan | Output | |-------|------|--------| -| 1 | `kev_match` | Emits `vuln_finding.kev_match` for CVEs that just entered KEV AND for which the org still has open findings. Diffed against an `org_value` "previously-known KEV set". | -| 2 | `daily_snapshot` | Writes the per-severity open / KEV counts for today (see [Daily snapshots](#daily-snapshots)). | -| 3 | `epss_history` | Writes one EPSS row per distinct org CVE for today (see [EPSS history](#epss-history-90-day-series)). | +| 1 | `kev_match` | Emits `vuln_finding.kev_match` for each CVE that newly entered KEV AND for which the org still has open findings. The extension diffs against a "previously-known KEV set" in `org_value`. | +| 2 | `daily_snapshot` | Writes the open and KEV counts for each severity for today (see [Daily snapshots](#daily-snapshots)). | +| 3 | `epss_history` | Writes one EPSS row for each distinct org CVE for today (see [EPSS history](#epss-history-90-day-series)). | -The handler also re-reconciles D&R rules (idempotent) so a config change picks up on the next tick without requiring a manual re-subscribe. +The handler also reconciles the D&R rules again. Reconciliation is idempotent, so a change to the configuration takes effect on the next tick and you do not have to subscribe again. -The 24h spread means events and snapshots are **not** real-time. A KEV addition published by CISA at 09:00 UTC will surface to org A around 14:00 UTC and org B around 03:00 UTC the next day; this is by design — orgs are sharded across the day to keep the cron's load steady. Customers needing sub-day KEV matching should subscribe to the upstream CISA RSS feed directly. +The 24h spread means that events and snapshots are **not** real-time. When CISA publishes a KEV addition at 09:00 UTC, it surfaces to org A at about 14:00 UTC. It surfaces to org B at about 03:00 UTC the next day. This is by design: the shard across the day keeps the load of the cron steady. Customers that need KEV matching in less than a day must subscribe to the upstream CISA RSS feed directly. ### KEV / EPSS enrichment at read time -The extension augments every CVE with KEV and EPSS data at read time via `cve.limacharlie.io/enrich` (POST `{"cves": [...]}`, returns `{"results": {"": {kev?, epss?, exploit_refs?}, ...}}`, capped at 200 CVEs per call). +The extension augments every CVE with KEV and EPSS data at read time through `cve.limacharlie.io/enrich` (POST `{"cves": [...]}`, returns `{"results": {"": {kev?, epss?, exploit_refs?}, ...}}`, capped at 200 CVEs for each call). -Enrichment is opt-in per request via `include_enrichment` (defaults to `true` for user-facing actions). Set it to `false` for cheap admin queries that don't need the merged view. +Enrichment is opt-in for each request through `include_enrichment`, which defaults to `true` for actions that face the user. Set it to `false` for cheap admin queries that do not need the merged view. When enrichment is included: - **KEV match:** each affected CVE in the response carries a `kev` block. - **EPSS score:** each CVE carries an `epss` block. -- **Exploit references:** `query_cve` (single-CVE detail) returns an `exploit_refs` array (`source` ∈ `exploit-db` / `metasploit` / `packetstorm` / `github-poc` / `vendor-or-other`; `tier` ∈ `weaponized` / `poc`). The list-view actions deliberately omit exploit refs to keep page payloads small. +- **Exploit references:** `query_cve` (the detail of a single CVE) returns an `exploit_refs` array (`source` ∈ `exploit-db` / `metasploit` / `packetstorm` / `github-poc` / `vendor-or-other`; `tier` ∈ `weaponized` / `poc`). The list-view actions omit exploit refs by design, to keep the page payloads small. ## API actions -All actions are invoked via the standard extension request endpoint: +Invoke all actions through the standard request endpoint for extensions: ```bash curl -s -X POST \ @@ -279,37 +281,37 @@ curl -s -X POST \ -d data='' ``` -The full request and response schemas live in the extension's `requestSchema()` declaration in [`refractionPOINT/ext-vulnerability-reporting`](https://github.com/refractionPOINT/ext-vulnerability-reporting). The web app's Vulnerabilities page is a reference consumer for every action listed below. +The full schemas for requests and responses live in the `requestSchema()` declaration of the extension in [`refractionPOINT/ext-vulnerability-reporting`](https://github.com/refractionPOINT/ext-vulnerability-reporting). The Vulnerabilities page of the web app is a reference consumer for every action listed below. ### Read actions | Action | Purpose | |--------|---------| -| `query_cves` | Paginated CVE rollup across the org. Sort by `cve` / `count` / `severity` / `lc_risk`. Returns `max_lc_risk` per row plus optional KEV/EPSS. | -| `query_endpoints` | Paginated endpoint rollup with vulnerability counts. Returns `asset_metadata` when `include_tags=true`. | -| `query_dashboard` | Index-based counts (severity, platform_string) powering the donut + bar charts. | -| `query_host_vuln_packages` | All vulnerable packages and their CVEs for one sensor. Sort by `cve` / `score` / `severity` / `lc_risk` / `package_name` / `package_name_package_version_cve`. Returns `lc_risk` and `fix_version` per row. | -| `query_cve_vuln_hosts` | All endpoints affected by one CVE. | -| `query_cve_vuln_packages` | All `(package_name, package_version)` pairs in the org affected by one CVE, with the count of distinct sensors per pair. | -| `query_cve` | Single-CVE detail blob. With `include_enrichment=true` returns the merged KEV / EPSS / exploit-refs view. | -| `query_epss_history` | EPSS percentile + score time series for one CVE. | -| `query_daily_snapshots` | Per-day open-finding counts (and KEV subset) for the burndown tile. | -| `list_finding_resolutions` | Page through `vuln_finding_state` for the org with optional scope / resolution filters. | +| `query_cves` | Paginated CVE rollup across the org. Sort by `cve` / `count` / `severity` / `lc_risk`. Returns `max_lc_risk` for each row, plus optional KEV and EPSS data. | +| `query_endpoints` | Paginated endpoint rollup with counts of vulnerabilities. Returns `asset_metadata` when `include_tags=true`. | +| `query_dashboard` | Counts based on indexes (severity, platform_string) that drive the donut chart and the bar chart. | +| `query_host_vuln_packages` | All vulnerable packages and their CVEs for one sensor. Sort by `cve` / `score` / `severity` / `lc_risk` / `package_name` / `package_name_package_version_cve`. Returns `lc_risk` and `fix_version` for each row. | +| `query_cve_vuln_hosts` | All endpoints that one CVE affects. | +| `query_cve_vuln_packages` | All `(package_name, package_version)` pairs in the org that one CVE affects, with the count of distinct sensors for each pair. | +| `query_cve` | Detail blob for a single CVE. With `include_enrichment=true`, returns the merged view of KEV, EPSS, and exploit refs. | +| `query_epss_history` | Time series of EPSS percentile and score for one CVE. | +| `query_daily_snapshots` | Counts of open findings for each day (and the KEV subset) for the burndown tile. | +| `list_finding_resolutions` | Page through `vuln_finding_state` for the org, with optional filters for scope and resolution. | ### Write actions | Action | Purpose | |--------|---------| -| `scan_packages` | Trigger an out-of-band `os_packages` scan against a specific sensor. | -| `set_finding_resolution` | Set or clear a finding's resolution. Pass `resolution: null` to reopen (delete the row). | -| `bulk_set_finding_resolution` | Apply a resolution change across up to 100 findings in one call. | -| `reset_asset_findings` | Wipe every stored finding for one sensor (for reformat / reimage / decommission). Org-scope fingerprints that were only on this sensor fire `vuln_finding.closed`. | +| `scan_packages` | Start an out-of-band `os_packages` scan against one sensor. | +| `set_finding_resolution` | Set or clear the resolution of a finding. Pass `resolution: null` to reopen the finding and delete the row. | +| `bulk_set_finding_resolution` | Apply a resolution change to a maximum of 100 findings in one call. | +| `reset_asset_findings` | Wipe every stored finding for one sensor (for a reformat, reimage, or decommission). Org-scope fingerprints that were only on this sensor fire `vuln_finding.closed`. | ### Internal action | Action | Purpose | |--------|---------| -| `process_packages` | Internal callback fired by the ingest D&R rule. Not user-facing. | +| `process_packages` | Internal callback that the ingest D&R rule fires. Not user-facing. | ### Action reference @@ -351,7 +353,7 @@ Response: } ``` -Filters supported: `severity`, `kev_only`, `epss_min`, `resolution`, `criticality`, `env`, `exposure`. `kev_only` and `epss_min` force-enable `include_enrichment`. `filter_via_state` (default `true`) suppresses CVEs whose org-scope rollup is fully resolved. +Supported filters: `severity`, `kev_only`, `epss_min`, `resolution`, `criticality`, `env`, `exposure`. `kev_only` and `epss_min` force-enable `include_enrichment`. `filter_via_state` (default `true`) suppresses each CVE whose org-scope rollup is fully resolved. #### `query_endpoints` @@ -438,7 +440,7 @@ Request: } ``` -Pass `normalized_package_name` so the resolution overlay can compute host-scope fingerprints; without it, only org-scope resolution hits land. Filters supported: `platform`, `platform_string`, `criticality`, `env`, `exposure`, `resolution`. +Pass `normalized_package_name` so the resolution overlay can compute host-scope fingerprints. Without it, only org-scope resolution hits land. Supported filters: `platform`, `platform_string`, `criticality`, `env`, `exposure`, `resolution`. #### `query_cve` @@ -461,7 +463,7 @@ Response: } ``` -`exploit_refs` is the only place exploit references are returned. List-view actions deliberately omit them. +`exploit_refs` is the only place that returns exploit references. The list-view actions omit them by design. #### `query_epss_history` @@ -471,7 +473,7 @@ Request: { "cve": "CVE-2024-12345", "days": 90 } ``` -`days` defaults to `90`, capped at `365`. CVE must start with `CVE-`. Response is ordered `snapshot_date ASC` so it can be plotted directly: +`days` defaults to `90` and is capped at `365`. The CVE must start with `CVE-`. The response is ordered `snapshot_date ASC`, so you can plot it directly: ```json { @@ -492,7 +494,7 @@ Request: { "days": 30, "severities": ["critical"] } ``` -`days` defaults to `30`, capped at `365`. `severities` defaults to all four canonical buckets. Response is ordered `(snapshot_date ASC, severity ASC)`: +`days` defaults to `30` and is capped at `365`. `severities` defaults to all four canonical buckets. The response is ordered `(snapshot_date ASC, severity ASC)`: ```json { @@ -522,10 +524,10 @@ Request: Field rules: - `scope` (`org` | `host`) is required. -- Either `fingerprint` OR `(cve, normalized_package_name)` must be supplied. `sid` is required when `scope=host`. -- `resolution` is one of `mitigated` / `accepted` / `false_positive`, or `null` to **reopen** the finding (deletes the row). -- `expires_at` (RFC3339) is only valid when `resolution=accepted`. It is optional; an accepted resolution without an `expires_at` never lapses. -- `case_number` is optional. It is reserved for upcoming ext-cases linkage; the field is plumbed through end-to-end but unused by the UI today. +- Supply either `fingerprint` OR `(cve, normalized_package_name)`. `sid` is required when `scope=host`. +- `resolution` is one of `mitigated` / `accepted` / `false_positive`, or `null` to **reopen** the finding (this deletes the row). +- `expires_at` (RFC3339) is valid only when `resolution=accepted`. It is optional. An accepted resolution with no `expires_at` never lapses. +- `case_number` is optional. It is reserved for an upcoming linkage to ext-cases. The field is plumbed end-to-end, but the UI does not use it today. Response: @@ -544,11 +546,11 @@ Response: } ``` -When `resolution=null` is passed the row is deleted and the response carries `resolution: null` with the now-cleared metadata fields. `resolved_at` is set to wall-clock time when the resolution becomes `mitigated`, so MTTR is derived from `(resolved_at - first_seen_at)` where `first_seen_at` comes from the matching `vuln_reports` row. +When you pass `resolution=null`, the extension deletes the row. The response carries `resolution: null` and the metadata fields that are now cleared. The extension sets `resolved_at` to the wall-clock time when the resolution becomes `mitigated`. MTTR therefore comes from `(resolved_at - first_seen_at)`. `first_seen_at` comes from the matching `vuln_reports` row. #### `bulk_set_finding_resolution` -Apply **one** resolution (with optional `expires_at` and `case_number`) to up to 100 targets in a single call. The resolution / expires_at / case_number are top-level fields; each target identifies a finding (scope + either `fingerprint` OR `cve` + `normalized_package_name` [+ `sid` for host scope]). Items are committed independently; partial successes are reported per-item. +Apply **one** resolution (with an optional `expires_at` and `case_number`) to a maximum of 100 targets in one call. `resolution`, `expires_at`, and `case_number` are top-level fields. Each target identifies a finding: a scope plus either a `fingerprint` OR a `cve` and a `normalized_package_name` (plus `sid` for host scope). The extension commits each item independently and reports a partial success for each item. ```json { @@ -560,7 +562,7 @@ Apply **one** resolution (with optional `expires_at` and `case_number`) to up to } ``` -To reopen a batch of findings, pass `"resolution": null` with the same targets shape. +To reopen a batch of findings, pass `"resolution": null` with the same shape of targets. Response: @@ -577,11 +579,11 @@ Response: } ``` -Each entry in `results` carries the original `index` plus the materialized `row` (same shape as the `set_finding_resolution` response). Per-target failures land in `errors` as `{ index, error }` instead. Calls with more than 100 targets are rejected outright. +Each entry in `results` carries the original `index` plus the materialized `row`, which has the same shape as the response of `set_finding_resolution`. A failure for one target lands in `errors` as `{ index, error }` instead. The extension rejects a call with more than 100 targets. #### `list_finding_resolutions` -Page through resolution rows in the org. The list returns **only resolved rows** — open findings have no row to enumerate. All filters are optional and stack as AND. +Page through the resolution rows in the org. The list returns **only resolved rows**, because open findings have no row to enumerate. All filters are optional and stack as AND. ```json { @@ -614,50 +616,50 @@ Response: } ``` -`limit` defaults to 100; the response is ordered `(scope ASC, fingerprint ASC)`. Lapsed acceptances are returned with `resolution=accepted` and an `expires_at` in the past — the lapsed signal is a derived UI check (`resolution === 'accepted' && expires_at < now`), not a separate enum value. +`limit` defaults to 100, and the response is ordered `(scope ASC, fingerprint ASC)`. Lapsed acceptances come back with `resolution=accepted` and an `expires_at` in the past. The lapsed signal is a derived check in the UI (`resolution === 'accepted' && expires_at < now`), and not a separate enum value. #### `scan_packages` -Trigger an out-of-band scan for one sensor: +Start an out-of-band scan for one sensor: ```json { "sid": "550e8400-..." } ``` -Returns immediately; the scan completes asynchronously when the sensor reports back via the ingest D&R rule. +The call returns immediately. The scan completes asynchronously when the sensor reports back through the ingest D&R rule. #### `reset_asset_findings` -Wipe every stored finding for one sensor. Use when the host has been reformatted, reimaged, or decommissioned and the existing findings no longer reflect reality. The next legitimate package scan repopulates findings from scratch. +Wipe every stored finding for one sensor. Use this action when the host was reformatted, reimaged, or decommissioned and the existing findings no longer reflect reality. The next legitimate package scan repopulates the findings from scratch. ```json { "sid": "550e8400-..." } ``` -Response carries the number of org-scope fingerprints that the reset cleared from the org entirely (one `vuln_finding.closed` event fires per cleared fingerprint): +The response carries the number of org-scope fingerprints that the reset cleared from the org entirely. One `vuln_finding.closed` event fires for each cleared fingerprint: ```json { "data": { "sid": "550e8400-...", "closed": 17 } } ``` -Side effect: `vuln_endpoint_scans.last_scan_at` is stamped to the reset time, matching the semantic "operator declared this asset clean at this time". The next real package scan overwrites it. +Side effect: the extension stamps `vuln_endpoint_scans.last_scan_at` with the time of the reset, which matches the semantic "operator declared this asset clean at this time". The next real package scan overwrites it. ## Events emitted -The extension emits the following events through LimaCharlie's standard webhook adapter. Customers route them via Outputs to Jira, Slack, Cases, PagerDuty, etc. +The extension emits the following events through the standard webhook adapter of LimaCharlie. Customers route them with Outputs to Jira, Slack, Cases, PagerDuty, and other systems. | Event | When fired | Notable fields | |-------|-----------|----------------| -| `vuln_finding.created` | A new finding lands for an asset (rescan write path detected a new `(oid, fingerprint)` tuple). | `cve`, `severity`, `score`, `sid`, `hostname`, `kev`, `epss`, `first_seen` | -| `vuln_finding.closed` | The last sensor holding `(cve, normalized_package_name)` cleared it on a rescan, so the org-scope fingerprint is gone. Also fires per cleared fingerprint when `reset_asset_findings` wipes a host. | `cve`, `severity`, `score`, `sid`, `hostname`, `fingerprint` | -| `vuln_finding.kev_match` | A CVE just entered CISA KEV AND the org still has at least one open finding for it. | `cve`, `kev`, `epss` | -| `vuln_finding.state_changed` | `set_finding_resolution` / `bulk_set_finding_resolution` succeeded (including reopens, where the embedded resolution row carries `scope` + `fingerprint` + `updated_at` and the resolution-related fields are nil). | `fingerprint`, embedded `resolution` row (`scope`, `resolution`, `expires_at`, `case_number`, `resolved_at`, `resolved_by`, `updated_at`) | +| `vuln_finding.created` | A new finding lands for an asset. The write path of the rescan detected a new `(oid, fingerprint)` tuple. | `cve`, `severity`, `score`, `sid`, `hostname`, `kev`, `epss`, `first_seen` | +| `vuln_finding.closed` | The last sensor that held `(cve, normalized_package_name)` cleared it on a rescan, so the org-scope fingerprint is gone. This event also fires for each cleared fingerprint when `reset_asset_findings` wipes a host. | `cve`, `severity`, `score`, `sid`, `hostname`, `fingerprint` | +| `vuln_finding.kev_match` | A CVE newly entered CISA KEV AND the org still has at least one open finding for it. | `cve`, `kev`, `epss` | +| `vuln_finding.state_changed` | `set_finding_resolution` or `bulk_set_finding_resolution` succeeded. This includes reopens, where the embedded resolution row carries `scope` + `fingerprint` + `updated_at` and the resolution-related fields are nil. | `fingerprint`, embedded `resolution` row (`scope`, `resolution`, `expires_at`, `case_number`, `resolved_at`, `resolved_by`, `updated_at`) | -Every event carries `event_type`, `oid`, and an optional `fingerprint`. Event delivery is best-effort: a failed webhook is logged at warn level and does not roll back the underlying state mutation. +Every event carries `event_type`, `oid`, and an optional `fingerprint`. Event delivery is best-effort. The extension logs a failed webhook at warn level and does not roll back the underlying state mutation. ### Example output configuration -The same Outputs surface used for detections can route vulnerability events. The events ride the standard event stream, so use `event_white_list` to filter by `event_type`. To send `vuln_finding.kev_match` to Slack: +The same Outputs surface that routes detections can route vulnerability events. The events ride the standard event stream, so use `event_white_list` to filter by `event_type`. To send `vuln_finding.kev_match` to Slack: ```yaml name: vuln-kev-to-slack @@ -669,33 +671,33 @@ event_white_list: | vuln_finding.kev_match ``` -`event_white_list` is the standard newline-separated whitelist documented in [Output stream structures](../../outputs/stream-structures.md#event-type-filtering); list additional event types on their own lines to fan out a single Output to multiple `vuln_finding.*` subtypes. +`event_white_list` is the standard newline-separated whitelist that [Output stream structures](../../outputs/stream-structures.md#event-type-filtering) documents. To fan out one Output to more than one `vuln_finding.*` subtype, list the other event types on their own lines. ## Web UI -Once the extension is subscribed, a new **Vulnerabilities** section appears in the left sidebar of the LimaCharlie web app. +After you subscribe to the extension, a new **Vulnerabilities** section appears in the left sidebar of the LimaCharlie web app. ![vulnerability reporting 1](../../../assets/images/vulnerability-reporting-1.png) -The web app's Vulnerabilities section is the primary surface. It mirrors the API: +The Vulnerabilities section of the web app is the primary surface. It mirrors the API: - **KPI strip** — Total findings, KEV in environment, Open critical, Critical assets. -- **Trend tiles** — MTTR by severity (driven by `resolved_at`), KEV coverage, Exposure score, and a 30-day open-critical burndown sparkline backed by `query_daily_snapshots`. +- **Trend tiles** — MTTR by severity (driven by `resolved_at`), KEV coverage, and Exposure score. There is also a 30-day burndown sparkline of open critical findings, backed by `query_daily_snapshots`. - **Filter chip-bar** — multi-select chips for severity, criticality, exposure, environment, KEV-only, EPSS bucket (`top-1` / `top-5` / `top-10` / `any`), and resolution (`open` / `mitigated` / `accepted` / `false_positive` / lapsed-accepted). -- **Charts** — donut by severity + bar by platform; both reflect the active filter when one is set. -- **Endpoints / CVEs tabs** — sortable columns including `lc_risk`, KEV badge, EPSS badge, resolution chip, asset-metadata cell. Bulk-select on the CVEs tab opens the resolution modal for batch resolution changes. -- **CVE detail page** — affected hosts, affected packages, full CVE description, references, the merged KEV/EPSS view, exploit references, a 90-day EPSS sparkline backed by `query_epss_history`, the current resolution row (if any), and a one-click "Run a hunt" that opens an LCQL hunt deeplinked to the CVE. -- **Asset detail page** — per-sensor view of vulnerable packages, asset metadata projection, top fix-version recommendation with hunt deeplink, and the resolutions currently in effect for the host. +- **Charts** — a donut by severity and a bar chart by platform. Both charts obey the active filter when you set one. +- **Endpoints / CVEs tabs** — sortable columns that include `lc_risk`, a KEV badge, an EPSS badge, a resolution chip, and a cell with asset metadata. On the CVEs tab, bulk-select opens the resolution modal for batch resolution changes. +- **CVE detail page** — affected hosts, affected packages, the full CVE description, references, the merged KEV/EPSS view, exploit references, and a 90-day EPSS sparkline backed by `query_epss_history`. The page also shows the current resolution row, if there is one, and a one-click "Run a hunt" that opens an LCQL hunt deeplinked to the CVE. +- **Asset detail page** — a per-sensor view of vulnerable packages and the asset metadata projection. The page also shows the top recommendation for a fix version with a hunt deeplink, and the resolutions currently in effect for the host. - **Header exports** — PDF (current view), CSV (current view), full-bundle ZIP, Executive PDF, Compliance pack PDF, Remediation plan CSV. ## Workflows -Concrete operator playbooks. Each workflow is a numbered sequence; substitute ``, ``, etc. as appropriate. Examples assume the `limacharlie` CLI or a `curl` against the extension request endpoint. +Concrete playbooks for operators. Each workflow is a numbered sequence. Substitute ``, ``, and the other values as appropriate. The examples use the `limacharlie` CLI or a `curl` call against the request endpoint of the extension. ### 1. First-time setup -1. Subscribe to the extension on the [marketplace page](https://app.limacharlie.io/add-ons/extension-detail/ext-vulnerability-reporting) (default `scan_mode: scheduled`). -2. Tag your sensors. At minimum `lc:asset:criticality:*`; ideally also `exposure`, `env`, `owner`, and `compliance`. Mass-tag by selector: +1. Subscribe to the extension on the [marketplace page](https://app.limacharlie.io/add-ons/extension-detail/ext-vulnerability-reporting). The default is `scan_mode: scheduled`. +2. Tag your sensors. Set `lc:asset:criticality:*` as a minimum, and also `exposure`, `env`, `owner`, and `compliance`. To mass-tag by selector: ```bash limacharlie tag mass-add \ @@ -706,7 +708,7 @@ Concrete operator playbooks. Each workflow is a numbered sequence; substitute `< --tag lc:asset:exposure:internet-facing ``` -3. Wait for the first scheduled scan (within 24h) or trigger an out-of-band one for a representative host: +3. Wait for the first scheduled scan (in less than 24h), or start an out-of-band scan for one representative host: ```bash curl -s -X POST "$LC_API/v1/extension/request/ext-vulnerability-reporting" \ @@ -715,38 +717,38 @@ Concrete operator playbooks. Each workflow is a numbered sequence; substitute `< -d data='{"sid":""}' ``` -4. Open the Vulnerabilities page. The KPI strip and donut populate first; the trend tiles and burndown sparkline populate after the first daily Update tick (within 24h of subscribe). +4. Open the Vulnerabilities page. The KPI strip and the donut chart populate first. The trend tiles and the burndown sparkline populate after the first daily Update tick, in less than 24h after you subscribe. ### 2. Triage a critical finding -1. Vulnerabilities page → CVEs tab → sort by **LC Risk DESC** (default). +1. Open the Vulnerabilities page, select the CVEs tab, and sort by **LC Risk DESC** (the default). 2. Click the row to open the side drawer. Review: - - KEV block — is exploitation observed? - - EPSS percentile — and the 90-day trend on the CVE detail page (`query_epss_history`) — is it climbing? - - Affected hosts (`query_cve_vuln_hosts`) — what asset criticality / exposure mix? -3. From the CVE detail page click **Run a hunt** — the deeplink seeds an LCQL hunt with the CVE context for live investigation. + - The KEV block — check whether exploitation is observed. + - The EPSS percentile, and the 90-day trend on the CVE detail page (`query_epss_history`) — check whether it climbs. + - The affected hosts (`query_cve_vuln_hosts`) — check the mix of asset criticality and exposure. +3. On the CVE detail page, click **Run a hunt**. The deeplink seeds an LCQL hunt with the CVE context for live investigation. 4. Decide: - - If a compensating control is in place → **Set resolution → mitigated**. `resolved_at` is stamped and the finding drops out of the open count. - - If the operator is going to actively patch → leave the finding as `open` (no resolution row); the burndown sparkline tracks remediation by attrition (the rescan removes the row when the patch lands). - - If business has formally accepted the risk → **Set resolution → accepted** with an optional `expires_at`. + - If a compensating control is in place, select **Set resolution → mitigated**. The extension stamps `resolved_at` and the finding drops out of the open count. + - If the operator patches the finding actively, leave it as `open` with no resolution row. The burndown sparkline tracks the remediation by attrition, because the rescan removes the row when the patch lands. + - If the business formally accepted the risk, select **Set resolution → accepted** with an optional `expires_at`. ### 3. Track remediation progress -1. The dashboard's burndown sparkline is the daily total of open critical findings (`query_daily_snapshots`, `severities=["critical"]`, `days=30`). Slope is the operational signal. -2. The MTTR tile reads `resolved_at - first_seen_at` per severity. It populates only after the first finding is set to `mitigated`. -3. Rolling exports for steering committees: header → **Executive PDF** for an exec audience or **Remediation plan (CSV)** for ticket-import-ready output. +1. The burndown sparkline on the dashboard is the daily total of open critical findings (`query_daily_snapshots`, `severities=["critical"]`, `days=30`). The slope is the operational signal. +2. The MTTR tile reads `resolved_at - first_seen_at` for each severity. It populates only after the first finding is set to `mitigated`. +3. For rolling exports for steering committees, open the header. Select **Executive PDF** for an exec audience, or **Remediation plan (CSV)** for output that is ready to import into tickets. ### 4. Risk acceptance -When a finding cannot be patched in time and the business formally accepts the risk: +Use this workflow when a finding cannot be patched in time and the business formally accepts the risk: -1. CVE row → **Set resolution → accepted**. -2. Optionally set `expires_at` (RFC3339, in the future). An accepted resolution without an `expires_at` never lapses. -3. The finding drops out of the open count until `expires_at`. When `expires_at` is in the past the UI derives a **lapsed acceptance** signal at read time — the row renders with the same urgency as an open finding so the operator knows to revisit, and the daily snapshot counts it back as open. -4. To extend, call `set_finding_resolution` again with a new `expires_at` (the row is upserted in place; `resolved_at` and `resolved_by` are refreshed). -5. To formally close, transition to `mitigated` once the patch lands. To reopen, pass `resolution: null` (deletes the row). +1. On the CVE row, select **Set resolution → accepted**. +2. Set `expires_at` (RFC3339, in the future) if necessary. An accepted resolution with no `expires_at` never lapses. +3. The finding drops out of the open count until `expires_at`. When `expires_at` is in the past, the UI derives a **lapsed acceptance** signal at read time. The row renders with the same urgency as an open finding, so the operator knows to revisit it. The daily snapshot counts it back as open. +4. To extend the acceptance, call `set_finding_resolution` again with a new `expires_at`. The extension upserts the row in place and refreshes `resolved_at` and `resolved_by`. +5. To close the finding formally, change the resolution to `mitigated` after the patch lands. To reopen the finding, pass `resolution: null`, which deletes the row. -For richer per-finding context (rationale, evidence, multi-party sign-off, comments), open a case from the finding — the upcoming ext-cases linkage will record the case number on the resolution row. +For richer context on each finding (rationale, evidence, sign-off by several parties, comments), open a case from the finding. The upcoming linkage to ext-cases will record the case number on the resolution row. ```bash curl -s -X POST "$LC_API/v1/extension/request/ext-vulnerability-reporting" \ @@ -763,21 +765,21 @@ curl -s -X POST "$LC_API/v1/extension/request/ext-vulnerability-reporting" \ ### 5. Compliance evidence export -1. From the page header → **Export ▾** → **Compliance pack**. -2. The frontend pre-fetches per-host packages for every host with severity ≥ High (bounded 4-way concurrency), then renders a multi-page evidence pack mapped to SOC 2 / ISO 27001 control vocabulary. -3. Resolution evidence is included per finding: `accepted` rows surface as "Risk accepted" (with `expires_at` if set); `mitigated` rows surface with `resolved_at` + `resolved_by`. -4. The `lc:asset:compliance:*` tag drives the per-framework breakdown — a host tagged `lc:asset:compliance:pci` shows up under PCI; multi-tagged hosts appear in each. +1. In the page header, select **Export ▾** → **Compliance pack**. +2. The frontend pre-fetches the packages of each host with a severity ≥ High (bounded 4-way concurrency). It then renders a multi-page evidence pack that maps to the SOC 2 / ISO 27001 control vocabulary. +3. The pack includes the resolution evidence for each finding. `accepted` rows surface as "Risk accepted", with `expires_at` if it is set. `mitigated` rows surface with `resolved_at` and `resolved_by`. +4. The `lc:asset:compliance:*` tag drives the breakdown for each framework. A host tagged `lc:asset:compliance:pci` shows up under PCI, and a host with several tags appears in each framework. ### 6. Host-centric review -1. Vulnerabilities page → Endpoints tab. Filter by `criticality:critical` or `exposure:internet-facing` to focus. -2. Click a row → side drawer shows asset metadata + per-host findings + top fix-version recommendation with a hunt deeplink. -3. From the asset detail page, bulk-select rows on the host vulnerabilities table → set resolution → `mitigated` (host scope) for findings the host has individually patched. +1. Open the Vulnerabilities page and select the Endpoints tab. Filter by `criticality:critical` or `exposure:internet-facing` to focus. +2. Click a row. The side drawer shows the asset metadata, the findings for the host, and the top recommendation for a fix version with a hunt deeplink. +3. On the asset detail page, bulk-select rows in the table of host vulnerabilities. Set the resolution to `mitigated` at host scope for the findings that the host patched individually. ### 7. EPSS trend monitoring -1. CVE detail page → 90-day EPSS sparkline (top right, next to the live percentile badge). -2. A climbing slope is the early-warning signal that a CVE is becoming dangerous before it lands in KEV. Promote any CVE whose EPSS percentile is rising fast and that has no resolution row yet. +1. Open the CVE detail page. The 90-day EPSS sparkline is at the top right, next to the badge with the live percentile. +2. A climbing slope is the early warning that a CVE becomes dangerous before it lands in KEV. Promote each CVE whose EPSS percentile climbs fast and that has no resolution row yet. 3. For longer reports, raise `days` (capped at 365): ```json @@ -786,10 +788,10 @@ curl -s -X POST "$LC_API/v1/extension/request/ext-vulnerability-reporting" \ ### 8. Bulk operations -1. CVEs tab → multi-select rows. -2. Bulk action → **Set resolution** opens the resolution modal with the selected fingerprints as targets. Up to 100 per call. -3. Each item is committed independently; the response carries per-item `applied` count and per-item errors so a typo on row 7 doesn't roll back rows 1-6. -4. The frontend uses the response's `results[]` directly — no follow-up `list_finding_resolutions` round trip is needed. +1. On the CVEs tab, multi-select rows. +2. Select the bulk action **Set resolution**. The resolution modal opens with the selected fingerprints as targets. The maximum is 100 for each call. +3. The extension commits each item independently. The response carries the `applied` count and the errors for each item, so a typo on row 7 does not roll back rows 1-6. +4. The frontend uses the `results[]` array of the response directly. No second call to `list_finding_resolutions` is needed. ## Best practices @@ -797,18 +799,18 @@ curl -s -X POST "$LC_API/v1/extension/request/ext-vulnerability-reporting" \ | Situation | Resolution | |-----------|------------| -| Detected, no work yet started | (leave implicit `open` — no row) | +| Detected, no work yet started | (leave the implicit `open` posture — no row) | | Patching is in flight | (leave as `open`; the rescan removes the row when the patch lands) | | Compensating control blocks exploitation; finding no longer counts as exploitable | `mitigated` | | Patch lands, rescan confirms gone | (no action — the row drops out of `vuln_reports` on the next scan) | | Cannot patch in the desired window, business-accepted exception | `accepted` (optional `expires_at`) | | Resolver false positive (wrong product / wrong version) | `false_positive` | -Do not use `mitigated` for "patch in progress" — `resolved_at` is stamped on entry, which would skew MTTR. Leave the finding open until the patch lands or a compensating control is documented. +Do not use `mitigated` for a patch that is in progress. The extension stamps `resolved_at` on entry, which skews MTTR. Leave the finding open until the patch lands or until you document a compensating control. ### Per-finding audit and collaboration -Per-finding audit detail is intentionally minimal — `resolved_at`, `resolved_by`, and `updated_at` are the only timestamps recorded, and updates overwrite in place. For richer collaboration (assignee, comments, evidence, classification, multi-party sign-off), use the upcoming **ext-cases** linkage: the `case_number` field on a finding's resolution row is reserved for this. When that integration ships, opening a case from a finding will populate `case_number` and the case will carry the audit history that the resolution row deliberately does not. +The audit detail for each finding is minimal by design. `resolved_at`, `resolved_by`, and `updated_at` are the only timestamps that the extension records, and an update overwrites the row in place. For richer collaboration (assignee, comments, evidence, classification, sign-off by several parties), use the upcoming **ext-cases** linkage. The `case_number` field on the resolution row of a finding is reserved for this. After that integration ships, a case that you open from a finding populates `case_number`. The case then carries the audit history that the resolution row deliberately does not. ### Tagging sensors meaningfully @@ -819,71 +821,71 @@ Suggested tag combos for common environments: - **Dev workstation:** `lc:asset:criticality:low`, `lc:asset:exposure:internal`, `lc:asset:env:dev`, `lc:asset:owner:it-help`. - **Build runner / CI:** `lc:asset:criticality:medium`, `lc:asset:exposure:internal`, `lc:asset:env:dev`, `lc:asset:owner:platform-team`. -Drive these via `limacharlie tag mass-add` keyed off existing infrastructure tags or installation keys, so newly-enrolled sensors land already classified. See [Asset Tag Namespace](../../../2-sensors-deployment/asset-tags.md#sample-real-world-tagging) for a fuller pattern. +Drive these tags with `limacharlie tag mass-add`, keyed on existing infrastructure tags or installation keys, so a newly-enrolled sensor lands already classified. See [Asset Tag Namespace](../../../2-sensors-deployment/asset-tags.md#sample-real-world-tagging) for a fuller pattern. -For **Linux** sensors, also set `lc:asset:os:-` (e.g. `lc:asset:os:debian-11`). It is the most reliable input for [distro-aware matching](#linux-distro-aware-matching), which suppresses CVEs that the distribution has already fixed via a backport. Without it the extension still infers the distro from a marker package or package source, but an explicit tag is authoritative. +For **Linux** sensors, also set `lc:asset:os:-` (for example `lc:asset:os:debian-11`). It is the most reliable input for [distro-aware matching](#linux-distro-aware-matching), which suppresses the CVEs that the distribution already fixed with a backport. Without the tag, the extension still infers the distro from a marker package or the package source, but an explicit tag is authoritative. ### LC Risk vs raw CVSS -CVSS severity is environment-blind: a CVSS 9.8 critical scores the same on a dev laptop and on the customer-facing API gateway. LC Risk corrects for that by multiplying in the asset-criticality bucket — a `low` host caps roughly half the score, and a `critical` host inflates it by 60%. Always sort by LC Risk first; fall back to CVSS only when explaining the score externally. +CVSS severity is blind to the environment: a CVSS 9.8 critical scores the same on a dev laptop and on the customer-facing API gateway. LC Risk corrects for that. It multiplies in the bucket of asset criticality — a `low` host caps about half the score, and a `critical` host inflates it by 60%. Sort by LC Risk first, and fall back to CVSS only when you explain the score externally. ### Tracking remediation deadlines -The extension does not enforce a built-in remediation SLA — there is no SLA-window configuration, no per-criticality deadline persisted on findings, and no SLA-breach event. The signals that **are** available for cadence-tracking are: +The extension does not enforce a built-in remediation SLA. There is no configuration for an SLA window, no deadline for each criticality on a finding, and no event for an SLA breach. These signals **are** available to track the cadence: -- `vuln_finding.created` — for stamping a target deadline at ingest in your ticketing system. -- `first_seen_at` (returned on every finding row) — the basis any external SLA calculation should key off. -- `vuln_finding.closed` and `mitigated`-resolution `vuln_finding.state_changed` events — for closing the loop and computing MTTR externally. +- `vuln_finding.created` — to stamp a target deadline at ingest in your ticketing system. +- `first_seen_at` (returned on every finding row) — the basis that any external SLA calculation must key off. +- `vuln_finding.closed` and `vuln_finding.state_changed` events with a `mitigated` resolution — to close the loop and to compute MTTR externally. -If you need deadline alerts, wire the per-criticality clock in your downstream system (Jira / Linear / PagerDuty) using `first_seen_at` + `criticality` from the event payload. +If you need deadline alerts, wire the clock for each criticality in your downstream system (Jira / Linear / PagerDuty). Use `first_seen_at` and `criticality` from the event payload. ### "Near-real-time" expectations -The daily Update tick is per-org, spread across 24h. KEV-match alerts and snapshot writes can lag by up to a full day for any one org. This is deliberate — the cron's load is steady rather than spiking. If you need sub-hour KEV detection, subscribe to the upstream CISA RSS feed in addition to this extension. +The daily Update tick runs for each org and is spread across 24h. KEV-match alerts and snapshot writes can lag by a full day for one org. This is deliberate, because it keeps the load of the cron steady rather than spiking. If you need KEV detection in less than an hour, subscribe to the upstream CISA RSS feed in addition to this extension. ### Integrating with downstream Outputs Route the `vuln_finding.*` events to your existing alerting pipeline. A typical wiring: -- `vuln_finding.kev_match` → Slack `#vuln-priority` + page on-call. -- `vuln_finding.created` → ticketing system (Jira, Linear) so each new finding gets a tracked owner. High-volume on first scan; often filtered to `severity=critical` only. -- `vuln_finding.state_changed` → SIEM. Each event carries the full resolution row, so a downstream consumer can rebuild the change feed without a follow-up read. -- `vuln_finding.closed` → ticketing system (auto-resolve the matching ticket) and SIEM. +- `vuln_finding.kev_match` → Slack `#vuln-priority`, and page the on-call operator. +- `vuln_finding.created` → ticketing system (Jira, Linear), so each new finding gets a tracked owner. The volume is high on the first scan, and this event is often filtered to `severity=critical` only. +- `vuln_finding.state_changed` → SIEM. Each event carries the full resolution row, so a downstream consumer can rebuild the change feed without a second read. +- `vuln_finding.closed` → ticketing system (to auto-resolve the matching ticket) and SIEM. ## Glossary | Term | Meaning | |------|---------| | **CVE** | Common Vulnerabilities and Exposures — public catalogue of disclosed vulnerabilities (`CVE-YYYY-NNNN`). Maintained by MITRE. | -| **NVD** | National Vulnerability Database — NIST's CVE feed with CVSS scores, CPEs, references. The resolver's primary data source. | -| **CVSS** | Common Vulnerability Scoring System — 0-10 numeric severity score plus `low`/`medium`/`high`/`critical` bucket. | -| **CPE** | Common Platform Enumeration — structured product identifier used by NVD configurations to express which software a CVE applies to. | -| **KEV** | CISA's Known Exploited Vulnerabilities catalogue. ~1500 entries; refreshed daily. | -| **EPSS** | FIRST.org's Exploit Prediction Scoring System. Per-CVE probability + percentile of in-the-wild exploitation in the next 30 days. | -| **LC Risk** | LimaCharlie's 0-100 environment-aware risk score. Persisted per-finding; see [LC Risk](#lc-risk). | -| **MTTR** | Mean Time To Remediation. Computed from `(resolved_at - first_seen_at)` per severity bucket. | +| **NVD** | National Vulnerability Database — NIST's CVE feed with CVSS scores, CPEs, and references. The primary data source of the resolver. | +| **CVSS** | Common Vulnerability Scoring System — 0-10 numeric severity score plus a `low`/`medium`/`high`/`critical` bucket. | +| **CPE** | Common Platform Enumeration — structured product identifier that NVD configurations use to express which software a CVE applies to. | +| **KEV** | The Known Exploited Vulnerabilities catalogue of CISA. About 1500 entries; refreshed daily. | +| **EPSS** | FIRST.org's Exploit Prediction Scoring System. Per-CVE probability and percentile of exploitation in the wild in the next 30 days. | +| **LC Risk** | The environment-aware risk score of LimaCharlie, from 0 to 100. Persisted for each finding; see [LC Risk](#lc-risk). | +| **MTTR** | Mean Time To Remediation. Computed from `(resolved_at - first_seen_at)` for each severity bucket. | | **Criticality** | Asset importance bucket (`critical`/`high`/`medium`/`low`). Source: `lc:asset:criticality:*` or the configured override map. | | **Exposure** | Network reachability bucket (`internet-facing`/`dmz`/`internal`). Source: `lc:asset:exposure:*`. | | **Env** | Environment bucket (`prod`/`staging`/`dev`/`test`). Source: `lc:asset:env:*`. | | **Distro / release** | The Linux distribution and version of an endpoint, used for backport-aware CVE matching. Source: `lc:asset:os:*` tag, a marker package, or the package source. See [Linux distro-aware matching](#linux-distro-aware-matching). | -| **Backport** | A distribution shipping a security fix into a packaged build without changing its upstream version number. Distro-aware matching prevents these from being flagged as still-vulnerable. | +| **Backport** | A distribution ships a security fix in a packaged build but does not change the upstream version number. Distro-aware matching stops these packages from being flagged as still-vulnerable. | | **Fingerprint** | SHA-256 hex of the canonical inputs that identify a finding across rescans. See [Finding fingerprint](#finding-fingerprint). | | **Scope** | `org` (per-package, applies to every host) or `host` (per-package-per-sensor). Resolution precedence: host beats org. | | **Resolution** | Replaces the older `state` term. A finding is either implicitly **open** (no row) or **resolved** with `resolution ∈ { mitigated, accepted, false_positive }`. See [Lifecycle states](#lifecycle-states). | -| **Lapsed acceptance** | An `accepted` resolution whose `expires_at` is in the past. Derived in the UI as `resolution === 'accepted' && expires_at < now`; the row is **not** mutated. | -| **Daily Update tick** | Per-org per-day cron firing the three daily scans. Spread across 24h. See [Daily Update tick](#daily-update-tick). | -| **KEV match** | The event fired when a CVE just entered KEV AND the org still has an open finding for it. | -| **Case number** | Optional integer on a resolution row reserved for upcoming ext-cases linkage. Plumbed through the API today; not surfaced in the UI yet. | +| **Lapsed acceptance** | An `accepted` resolution whose `expires_at` is in the past. The UI derives it as `resolution === 'accepted' && expires_at < now`; the row is **not** mutated. | +| **Daily Update tick** | The cron that fires the three daily scans, one time each day for each org. Spread across 24h. See [Daily Update tick](#daily-update-tick). | +| **KEV match** | The event that fires when a CVE newly entered KEV AND the org still has an open finding for it. | +| **Case number** | Optional integer on a resolution row, reserved for an upcoming linkage to ext-cases. Plumbed through the API today; the UI does not show it yet. | ## Reachability (deferred) -"Reachability" — in the sense Wiz, CrowdStrike, and similar tools use it: determining whether the vulnerable code path in a flagged package is actually loaded into a running process — is **deferred**. It requires sensor-side telemetry the EDR does not expose today (live module-load tracking, symbol-level call-graph coverage, etc.). +"Reachability" is **deferred**. Wiz, CrowdStrike, and similar tools use the term for a check of the vulnerable code path in a flagged package. The check finds whether that code path is loaded into a running process. It needs sensor-side telemetry that the EDR does not expose today, such as live tracking of module loads and call-graph coverage at symbol level. -Until reachability is available, LC Risk's `lc:asset:criticality:*` multiplier is the closest in-product proxy for triage prioritization: it lets the score reflect "this CVE on a crown-jewel host" versus "this CVE on a development box" without requiring the underlying loaded-code-path signal. +Until reachability is available, the `lc:asset:criticality:*` multiplier of LC Risk is the closest proxy in the product for triage prioritization. It lets the score reflect "this CVE on a high-value host" against "this CVE on a development box". The score does not need the signal about the loaded code path. ## See Also -- [`lc:asset:*` Tag Namespace](../../../2-sensors-deployment/asset-tags.md) — Asset metadata convention consumed by this extension +- [`lc:asset:*` Tag Namespace](../../../2-sensors-deployment/asset-tags.md) — Asset metadata convention that this extension consumes - [Sensor Tags](../../../2-sensors-deployment/sensor-tags.md) — General tagging mechanism, API, and CLI - [Outputs](../../outputs/index.md) — Routing the `vuln_finding.*` events to external systems - [Cases](cases.md) — Optional consumer of `vuln_finding.kev_match` for triage diff --git a/docs/5-integrations/extensions/limacharlie/yara-manager.md b/docs/5-integrations/extensions/limacharlie/yara-manager.md index 9c1d08b2a..be59daf76 100644 --- a/docs/5-integrations/extensions/limacharlie/yara-manager.md +++ b/docs/5-integrations/extensions/limacharlie/yara-manager.md @@ -1,46 +1,56 @@ # YARA Manager -The [YARA](https://github.com/Yara-Rules/rules) manager Extension allows you to reference external YARA rules (rules maintained in GitHub, for example) to use in your YARA scans within LimaCharlie. +The [YARA](https://github.com/Yara-Rules/rules) manager Extension lets you reference external YARA rules, for example rules that you keep in GitHub. You then use these rules in your YARA scans in LimaCharlie. -YARA rule sources defined in the YARA manager configuration will be synced every 24 hours, and can be manually synced by clicking the `Manual Sync` button on the extension page. +The YARA manager syncs the rule sources in its configuration every 24 hours. To sync them manually, click the `Manual Sync` button on the extension page. -If you add rule sources and want them to become available immediately, you will need to click the `Manual Sync` button to trigger the initial sync of the rules. +If you add rule sources and want them available immediately, click the `Manual Sync` button. This starts the first sync of the rules. -Rule sources can be either direct links (URLs) to a given YARA rule or [ARLs](../../../8-reference/authentication-resource-locator.md). +A rule source is a direct link (URL) to one YARA rule, or an [ARL](../../../8-reference/authentication-resource-locator.md). ## Option 1: Predefined YARA rules -LimaCharlie provides a list of YARA rule repositories, available in the configuration menu. To leverage these rules select "Predefined" and a list of LimaCharlie and Community rules will populate. By selecting one or more of these repositories, the respective rules will be automatically imported and will appear in your YARA rules under Automation → YARA Rules. +LimaCharlie supplies a list of repositories with YARA rules in the configuration menu. To use these rules, select "Predefined". A list of LimaCharlie rules and Community rules appears. Select one or more of these repositories. LimaCharlie imports the rules from them and shows them in your YARA rules under Automation → YARA Rules. ![Option 1: Predefined YARA rules LimaCharlie provides a list of YARA rule repositories, available in the configuration me](../../../assets/images/image(322).png) ## Option 2: Publicly available YARA rules -An example of setting up a rule using this repo: [Yara-Rules](https://github.com/Yara-Rules/rules) +This example sets up a rule with the [Yara-Rules](https://github.com/Yara-Rules/rules) repository. -For an `Email and General Phishing Exploit` rule we could use the following URL, which is a link to a single YARA rule. +For an `Email and General Phishing Exploit` rule, use the URL below. It is a link to one YARA rule. -For creating a rule out of multiple YARA rules, we could use the following ARL, which is a link to a directory of YARA rules. +To make a rule from more than one YARA rule, use the ARL below. It is a link to a directory of YARA rules. `[github,Yara-Rules/rules/email]` -Giving the rule configuration a name, the URL or ARL, and clicking the Save button will create the new rule source to sync to your YARA rules. +1. Give the rule configuration a name. +2. Give the URL or the ARL. +3. Click the Save button. + +LimaCharlie creates the new rule source and syncs it to your YARA rules. ## Option 3: Private YARA Repository -To use a YARA rule from a private Gihub repository you will need to make use of an [Authentication Resource Locator](../../../8-reference/authentication-resource-locator.md). +To use a YARA rule from a private GitHub repository, you need an [Authentication Resource Locator](../../../8-reference/authentication-resource-locator.md). -**Step 1: Create a token in GitHub** -In GitHub go to *Settings* and click *Developer settings* in the left hand side bar. +**Step 1: Create a token in GitHub.** Do these steps: -Next click *Personal access token* followed by *Generate new token*. Select repo permissions and finally *Generate token*. +1. In GitHub, go to *Settings*. +2. Click *Developer settings* in the left side bar. +3. Click *Personal access token*. +4. Click *Generate new token*. +5. Select the repo permissions. +6. Click *Generate token*. -**Step 2: Connect LimaCharlie to your GitHub repository** -Inside of LimaCharlie, click on *Yara Manager* in the left hand menu. Then click *Add New Yara Configuration*. +**Step 2: Connect LimaCharlie to your GitHub repository.** Do these steps: -Give your rule a name and then use the token you generated with the following format linked to your repo. +1. In LimaCharlie, click *Yara Manager* in the left menu. +2. Click *Add New Yara Configuration*. +3. Give your rule a name. +4. Use the token that you generated in one of the formats below, linked to your repository. `[github,my-org/my-repo-name/path/to/rule.yar,token,bfuihferhf8erh7ubhfey7g3y4bfurbfhrb]` @@ -48,4 +58,4 @@ or `[github,my-org/my-repo-name/path/to/rules_directory,token,bfuihferhf8erh7ubhfey7g3y4bfurbfhrb]` -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. Extensions integrate third-party tools, automate workflows, and add new capabilities. An organization subscribes to Extensions and gives them specific permissions to interact with its infrastructure. An Extension can be private or public. A private Extension gives tailored use, and a public Extension is shared with the community. This framework supports scale, flexibility, and secure, repeatable deployments. diff --git a/docs/5-integrations/extensions/third-party/atomic-red-team.md b/docs/5-integrations/extensions/third-party/atomic-red-team.md index 9ed0816af..9cd3e14e6 100644 --- a/docs/5-integrations/extensions/third-party/atomic-red-team.md +++ b/docs/5-integrations/extensions/third-party/atomic-red-team.md @@ -1,60 +1,63 @@ # Atomic Red Team -**Atomic Red Team** is a library of tests mapped to the MITRE ATT&CK framework, provided by Red Canary. With this Extension, LimaCharlie users can use Atomic Red Team to quickly, portably, and reproducibly test their environments. +**Atomic Red Team** is a library of tests from Red Canary. The tests map to the MITRE ATT&CK framework. This Extension lets LimaCharlie users test their environments with Atomic Red Team. The tests are fast, portable, and repeatable. See [the Atomic Red Team project site](https://atomicredteam.io/) for more information. ## Enabling the Atomic Red Team Extension -Enabling Atomic Red Team can be done within the LimaCharlie **Marketplace**, or at [this link](https://beta.app.limacharlie.io/add-ons/extension-detail/ext-atomic-red-team). +Enable Atomic Red Team in the LimaCharlie **Marketplace**, or on the [Atomic Red Team extension page](https://beta.app.limacharlie.io/add-ons/extension-detail/ext-atomic-red-team). -Under the Organization dropdown, select a tenant (organization) you want to subscribe to Atomic Red Team and click subscribe. +Under the Organization dropdown, select the organization that you want to subscribe to Atomic Red Team, then click subscribe. -Please note that Extensions are applied on a per-tenant basis. If you have multiple organizations you want to subscribe to Atomic Red Team, you will need to subscribe each organization to the extension separately. +Extensions apply to one organization at a time. To use Atomic Red Team in more than one organization, subscribe each organization to the extension separately. ## Supported Platforms The extension supports sensors on **Windows**, **Linux**, and **macOS**. Sensors must be online for tests to run. -On Linux and macOS, the extension installs PowerShell Core (`pwsh`) automatically during the Prepare step if it is not already present. +If PowerShell Core (`pwsh`) is not present on Linux or macOS, the extension installs it in the Prepare step. ## Three-Step Workflow -The extension uses a three-step workflow: **Prepare Host** → **Run Tests** → **Cleanup Host**. This matches how the upstream Atomic Red Team project is intended to be used. +The extension uses a workflow of three steps: **Prepare Host** → **Run Tests** → **Cleanup Host**. This is the intended use of the upstream Atomic Red Team project. ### Step 1: Prepare Host -Before running any tests, you must prepare the target sensor. This installs the Atomic Red Team framework and its dependencies. +Prepare the target sensor before you run tests. This step installs the Atomic Red Team framework and its dependencies. **What it does:** -- **Windows**: adds a Windows Defender exclusion for `C:\AtomicRedTeam` (best-effort — Tamper Protection may block it), installs NuGet, the `powershell-yaml` module, and the Invoke-AtomicRedTeam framework with atomics. -- **Linux**: installs PowerShell Core via the system package manager (apt/dnf), then installs the framework to `/opt/AtomicRedTeam`. -- **macOS**: installs PowerShell Core via the official `.pkg` installer, then installs the framework to `/opt/AtomicRedTeam`. +- **Windows**: tries to add a Windows Defender exclusion for `C:\AtomicRedTeam` (Tamper Protection can block this), then installs NuGet, the `powershell-yaml` module, and the Invoke-AtomicRedTeam framework with atomics. +- **Linux**: installs PowerShell Core with the system package manager (apt/dnf), then installs the framework to `/opt/AtomicRedTeam`. +- **macOS**: installs PowerShell Core with the official `.pkg` installer, then installs the framework to `/opt/AtomicRedTeam`. -You only need to prepare a host once. After that, you can run as many tests as you want. +You prepare a host one time only. After that, you can run as many tests as you want. ### Step 2: Run Tests -Select one or more MITRE ATT&CK technique IDs from the dropdown and click Run. Tests execute sequentially — each test checks prerequisites, installs them if needed, executes the technique, and optionally runs the atomic cleanup step. +1. Select one or more MITRE ATT&CK technique IDs from the dropdown. +2. Click Run. -The **Clean** option controls whether each test's atomic cleanup runs after execution (reverting technique-specific changes). This is separate from the host-level Cleanup step. +The tests run in sequence. Each test checks the prerequisites and installs them if they are absent. The test then runs the technique. The test can also run the atomic cleanup step. -If multiple tests are selected, they are chained automatically. Each test completion triggers the next via a callback. A single `job_id` tracks the entire run. +The **Clean** option controls the atomic cleanup after each test. The atomic cleanup reverses the changes of that technique. It is separate from the Cleanup step for the host. + +If you select more than one test, the extension chains the tests. When a test ends, a callback starts the next test. One `job_id` tracks the full run. ### Step 3: Cleanup Host -When you are done testing, run Cleanup to reverse the changes made by Prepare: +After you finish your tests, run Cleanup to reverse the changes from Prepare: - **Windows**: removes the Defender exclusion and deletes `C:\AtomicRedTeam`. - **Linux/macOS**: deletes `/opt/AtomicRedTeam`. - All platforms: uninstalls the `powershell-yaml` PowerShell module. -Cleanup is best-effort — if some components can't be removed (e.g., files locked), it reports partial success with details. +Cleanup does what it can. If it cannot remove some components, for example locked files, it reports partial success with the details. ## Checking Results -When the extension is enabled, you will see an Adapter named `ext-atomic-red-team`. This adapter receives all extension activity as webhook events: +When you enable the extension, an Adapter with the name `ext-atomic-red-team` appears. This adapter receives all extension activity as webhook events: | Event | When | |-------|------| @@ -62,14 +65,14 @@ When the extension is enabled, you will see an Adapter named `ext-atomic-red-tea | `run_started` / `test_result` / `run_success` / `run_failed` | Test execution (one `test_result` per technique) | | `cleanup_started` / `cleanup_success` / `cleanup_failed` | Cleanup Host lifecycle | -Each event includes a `job_id` for correlation and the sensor ID. The `test_result` event includes the technique ID, execution status, and a base64-encoded log of the test output. +Each event includes a `job_id` for correlation and the sensor ID. The `test_result` event includes the technique ID, the status of the run, and a base64-encoded log of the test output. -Within the **Timeline** of the sensor you ran a test on, you will also find `RECEIPT` events that contain the raw execution output (STDOUT, STDERR, exit code). +The **Timeline** of the sensor that ran the test also contains `RECEIPT` events. These events hold the raw output of the run (STDOUT, STDERR, exit code). -Between webhook events in the `ext-atomic-red-team` adapter and `RECEIPT` events on the sensor, you can correlate and identify successful and failed tests. +Use the webhook events in the `ext-atomic-red-team` adapter with the `RECEIPT` events on the sensor. Together they show which tests passed and which tests failed. ## Notes -- The Defender exclusion on Windows is best-effort. If Tamper Protection blocks it, the extension still installs the framework and reports a warning. Defender may quarantine some atomic test files. -- Some techniques include many sub-tests (e.g., T1082 on Windows has 17+). Individual sub-tests may time out after 120 seconds — this is an upstream `Invoke-AtomicTest` default, not a limitation of the extension. -- The list of available techniques is loaded from the upstream Atomic Red Team index at extension startup. +- The extension tries to add the Defender exclusion on Windows. If Tamper Protection blocks the exclusion, the extension still installs the framework and reports a warning. Defender can quarantine some atomic test files. +- Some techniques include many sub-tests. For example, T1082 on Windows has 17 or more. A sub-test can time out after 120 seconds. This is a default of the upstream `Invoke-AtomicTest`, not a limit of the extension. +- The extension loads the list of available techniques from the upstream Atomic Red Team index when it starts. diff --git a/docs/5-integrations/extensions/third-party/cloudflare.md b/docs/5-integrations/extensions/third-party/cloudflare.md index e9692a7bd..4264c735d 100644 --- a/docs/5-integrations/extensions/third-party/cloudflare.md +++ b/docs/5-integrations/extensions/third-party/cloudflare.md @@ -1,19 +1,19 @@ # Cloudflare -The Cloudflare LimaCharlie Extension exposes the incident-response and investigation surface of a Cloudflare account/zone (the Cloudflare v4 API) to D&R rules and AI agents. It enables automated edge and Zero Trust containment directly from detections — block a malicious source at the WAF, revoke a Zero Trust Access user's sessions, push IOCs onto a Gateway block list, purge cache, or fix a hijacked DNS record — without bouncing through a separate SOAR. +The Cloudflare LimaCharlie Extension gives D&R rules and AI agents access to the Cloudflare v4 API. This API is the incident-response and investigation surface of a Cloudflare account or zone. The extension automates containment at the edge and in Zero Trust directly from detections, with no separate SOAR. You can block a malicious source at the WAF or revoke the sessions of a Zero Trust Access user. You can also add IOCs to a Gateway block list, purge the cache, or correct a hijacked DNS record. -The extension provides two layers: +The extension has two layers: -- **Typed actions** for the common containment, triage, and investigation workflows, with friendly parameter names and built-in safety rails. -- A generic **`api_call`** passthrough for any Cloudflare v4 endpoint not covered by a typed action, including non-enveloped surfaces like the GraphQL Analytics API. +- **Typed actions** for the common containment, triage, and investigation workflows. They use clear parameter names and include safety checks. +- A generic **`api_call`** passthrough for each Cloudflare v4 endpoint without a typed action. This includes non-enveloped endpoints such as the GraphQL Analytics API. -Authentication is a scoped **API Token** (Bearer) or the legacy **Global API Key** — both static, no user interaction. +Authentication uses a scoped **API Token** (Bearer) or the legacy **Global API Key**. Both are static and need no user interaction. ## Setup ### 1. Create an API Token -In the Cloudflare dashboard (**My Profile → API Tokens**, or **Account Home → Manage Account → API Tokens**), create a token and grant only the permission groups for the actions you will use, scoped to the specific account and/or zone rather than "all accounts / all zones". The least-privilege set per capability: +In the Cloudflare dashboard (**My Profile → API Tokens**, or **Account Home → Manage Account → API Tokens**), create a token. Grant only the permission groups for the actions that you use. Scope the token to the specific account and/or zone, not to "all accounts / all zones". The least-privilege set for each capability: | Capability | Permission group (Read/Edit) | Scope | | --- | --- | --- | @@ -28,9 +28,9 @@ In the Cloudflare dashboard (**My Profile → API Tokens**, or **Account Home | Firewall events (GraphQL) | Account Analytics — Read | Account | | Account members | Account Membership — Edit | Account | -Only add what you will use — a valid token missing a permission group returns `403` on that endpoint (that is a scope problem, not a bad token). Resolve current permission-group names/IDs at setup via `GET /accounts/{account_id}/tokens/permission_groups`. +Add only the permission groups that you use. If a valid token does not have a permission group, that endpoint returns `403`. This is a scope problem, not a bad token. To get the current names and IDs of the permission groups at setup, call `GET /accounts/{account_id}/tokens/permission_groups`. -A legacy **Global API Key** works too (your account email plus the key), but it has full account access and **cannot be scoped** — prefer a token. +A legacy **Global API Key** also works (your account email plus the key). The key has full account access and you **cannot scope** it, so use a token instead. ### 2. Subscribe to the extension @@ -52,21 +52,21 @@ In **Extensions → ext-cloudflare → Configuration**, fill in: | `account_id` | no | Default account id for account-scoped actions. Any action can override it. | | `zone_id` | no | Default zone id for zone-scoped actions. Any action can override it. | -Provide **either** `api_token` **or** `email` + `api_key`, not both. +Give **either** `api_token` **or** `email` + `api_key`, but not both. ## Scoping: account vs zone -Cloudflare resources are either **account-scoped** or **zone-scoped**. Set default `account_id` / `zone_id` in the config; any action can override them per-request. +Cloudflare resources are **account-scoped** or **zone-scoped**. Set the default `account_id` and `zone_id` in the configuration. Any action can override them in each request. - **Account-scoped:** Zero Trust Access, Gateway, account members, the audit log. - **Zone-scoped:** DNS records, cache purge. -- **Either:** IP Access Rules and WAF custom rules accept `account_id` **or** `zone_id` — account scope applies across *all* the account's zones, zone scope to one zone. Pass exactly one; passing both is rejected as ambiguous, and with neither set the config defaults are used, **preferring the zone** (the narrower blast radius). +- **Either:** IP Access Rules and WAF custom rules accept `account_id` **or** `zone_id`. Account scope applies to *all* the zones in the account, and zone scope applies to one zone. Pass exactly one. If you pass both, the extension rejects the request as ambiguous. If you pass neither, the extension uses the defaults from the configuration and **prefers the zone**, because the zone has the smaller effect. ## Actions -Every action that targets an entity requires an explicit selector (an `ip` / `asn` / `country`, a `rule_id`, an `email`, a `list_id` + `values`, a `dns_record_id`, a `member_id`, …) — the extension refuses to run without one, preventing an accidental account-wide response. `purge_cache` additionally refuses unless exactly one purge mode is chosen. +Every action that targets an entity needs an explicit selector. A selector is an `ip`, `asn`, or `country`, a `rule_id`, an `email`, a `list_id` with `values`, a `dns_record_id`, a `member_id`, and so on. The extension refuses to run without a selector. This stops an accidental response across the full account. `purge_cache` also refuses to run unless you choose exactly one purge mode. -Typed list actions return `{data: [...], pagination: {...}}`, where `pagination` carries Cloudflare's `result_info` verbatim — offset fields (`page`, `per_page`, `total_pages`, …) or a `cursor`. Page by incrementing `page` until `page == total_pages`, or by passing the `cursor` back. `per_page` is clamped to 100. +Typed list actions return `{data: [...], pagination: {...}}`. The `pagination` field holds Cloudflare's `result_info` without change: the offset fields (`page`, `per_page`, `total_pages`, …) or a `cursor`. To page, increase `page` until `page == total_pages`, or send the `cursor` back. The maximum value of `per_page` is 100. ### Generic @@ -82,65 +82,65 @@ Generic passthrough to any Cloudflare v4 endpoint. | `headers` | object | Extra request headers. | | `body` | object | JSON body for `POST`/`PUT`/`PATCH`. | -Returns the whole response body verbatim — the `{success, errors, result, result_info}` envelope, or the raw shape for non-enveloped endpoints like GraphQL. +Returns the full response body without change: the `{success, errors, result, result_info}` envelope, or the raw structure for non-enveloped endpoints such as GraphQL. ### Investigation (reads) | Action | Parameters | What it does | | --- | --- | --- | -| `verify_token` | — | Verify the configured API token (health check); returns the token status. | -| `list_accounts` | `name`, `page`, `per_page`, `extra_query` | List accounts the credential can see — find an `account_id`. | -| `list_zones` | `name`, `account_id`, `status`, `page`, `per_page`, `extra_query` | List/search zones — find a `zone_id`. | -| `list_ip_access_rules` | `account_id`/`zone_id`, `target`, `value`, `mode`, `page`, `per_page` | List IP Access Rules; use a returned rule id with `remove_ip_access_rule`. | -| `list_dns_records` | `zone_id`, `type`, `name`, `content`, `page`, `per_page` | List a zone's DNS records; use a returned id with `edit_dns_record` / `delete_dns_record`. | +| `verify_token` | — | Check the configured API token (health check). Returns the status of the token. | +| `list_accounts` | `name`, `page`, `per_page`, `extra_query` | List the accounts that the credential can see. Use it to find an `account_id`. | +| `list_zones` | `name`, `account_id`, `status`, `page`, `per_page`, `extra_query` | List or search zones. Use it to find a `zone_id`. | +| `list_ip_access_rules` | `account_id`/`zone_id`, `target`, `value`, `mode`, `page`, `per_page` | List IP Access Rules. Use a returned rule id with `remove_ip_access_rule`. | +| `list_dns_records` | `zone_id`, `type`, `name`, `content`, `page`, `per_page` | List the DNS records of a zone. Use a returned id with `edit_dns_record` or `delete_dns_record`. | | `list_access_users` | `account_id`, `email`, `name`, `search`, `page`, `per_page` | List Zero Trust Access users. | -| `get_access_user_activity` | `account_id`, `user_id`, `kind` | An Access user's `active_sessions`, `last_seen_identity`, or `failed_logins`. | -| `list_gateway_lists` | `account_id`, `page`, `per_page` | List Zero Trust Gateway lists — find a `list_id`. | -| `list_members` | `account_id`, `status`, `page`, `per_page` | List account members — use a returned membership id (`result[].id`, **not** `user.id`) with `remove_member`. | -| `get_audit_logs` | `account_id`, `since`, `before`, `action_type`, `actor_email`, `limit`, `cursor`, `direction` | Query the account audit log (v2, cursor-paginated). The v2 API requires a `since`+`before` window; if omitted it defaults to the last 7 days. Pass the same explicit window across pages for stable pagination. | -| `search_firewall_events` | `zone_id`, `since`, `until`, `client_ip`, `action`, `limit` | Search a zone's WAF/firewall events via the GraphQL Analytics API (`firewallEventsAdaptive`). Counts are sampled; the window is plan-dependent (~31 days). | -| `get_waf_custom_ruleset` | `account_id`/`zone_id` | Fetch the `http_request_firewall_custom` phase ruleset — its id is the `ruleset_id` for `add_waf_custom_rule`. | +| `get_access_user_activity` | `account_id`, `user_id`, `kind` | Get the `active_sessions`, `last_seen_identity`, or `failed_logins` of an Access user. | +| `list_gateway_lists` | `account_id`, `page`, `per_page` | List Zero Trust Gateway lists. Use it to find a `list_id`. | +| `list_members` | `account_id`, `status`, `page`, `per_page` | List the members of the account. Use a returned membership id (`result[].id`, **not** `user.id`) with `remove_member`. | +| `get_audit_logs` | `account_id`, `since`, `before`, `action_type`, `actor_email`, `limit`, `cursor`, `direction` | Query the audit log of the account (v2, cursor-paginated). The v2 API needs a `since`+`before` window. If you omit the window, the default is the last 7 days. Pass the same explicit window for each page to keep pagination stable. | +| `search_firewall_events` | `zone_id`, `since`, `until`, `client_ip`, `action`, `limit` | Search the WAF and firewall events of a zone with the GraphQL Analytics API (`firewallEventsAdaptive`). The counts are sampled. The window depends on the plan (~31 days). | +| `get_waf_custom_ruleset` | `account_id`/`zone_id` | Get the `http_request_firewall_custom` phase ruleset. Its id is the `ruleset_id` for `add_waf_custom_rule`. | ### Edge / WAF containment | Action | Parameters | What it does | | --- | --- | --- | -| `block_ip` | `ip`, `account_id`/`zone_id`, `mode`, `notes` | Block a single IP (v4/v6) via an IP Access Rule. | +| `block_ip` | `ip`, `account_id`/`zone_id`, `mode`, `notes` | Block one IP (v4/v6) with an IP Access Rule. | | `block_ip_range` | `range`, `account_id`/`zone_id`, `mode`, `notes` | Block a CIDR range (IPv4 /16 or /24; IPv6 /32, /48, /64). | | `block_asn` | `asn`, `account_id`/`zone_id`, `mode`, `notes` | Block an ASN (bare AS number, no `AS` prefix). | | `block_country` | `country`, `account_id`/`zone_id`, `mode`, `notes` | Block a country (ISO-3166-1 alpha-2). | -| `remove_ip_access_rule` | `rule_id`, `account_id`/`zone_id` | Delete an IP Access Rule (undo a block) at the scope it was created. | -| `add_waf_custom_rule` | `expression`, `account_id`/`zone_id`, `action`, `description`, `ruleset_id` | Add a WAF custom rule (wirefilter `expression`, e.g. `(ip.src eq 198.51.100.4)`); resolves the custom-phase ruleset for you if `ruleset_id` is omitted. | +| `remove_ip_access_rule` | `rule_id`, `account_id`/`zone_id` | Delete an IP Access Rule (undo a block) at the scope where it was created. | +| `add_waf_custom_rule` | `expression`, `account_id`/`zone_id`, `action`, `description`, `ruleset_id` | Add a WAF custom rule (wirefilter `expression`, e.g. `(ip.src eq 198.51.100.4)`). If you omit `ruleset_id`, the extension finds the custom-phase ruleset. | -`mode` on the block actions defaults to `block`; override with `challenge`, `managed_challenge`, `js_challenge`, or `whitelist` (an allow-list entry). An account-scoped rule applies across *all* the account's zones. +The default `mode` for the block actions is `block`. To change it, use `challenge`, `managed_challenge`, `js_challenge`, or `whitelist` (an allow-list entry). An account-scoped rule applies to *all* the zones in the account. ### Zero Trust containment | Action | Parameters | What it does | | --- | --- | --- | -| `revoke_access_user` | `email`, `account_id`, `revoke_devices` (default `true`), `warp_session_reauth` | Revoke a Cloudflare Access user's sessions (by email); `revoke_devices` also drops device/WARP sessions. | -| `gateway_add_to_blocklist` | `list_id`, `values`, `account_id` | Append IOCs (domains, IPs, URLs, … per the list type) to a Zero Trust Gateway list. | +| `revoke_access_user` | `email`, `account_id`, `revoke_devices` (default `true`), `warp_session_reauth` | Revoke the sessions of a Cloudflare Access user (by email). `revoke_devices` also ends the device and WARP sessions. | +| `gateway_add_to_blocklist` | `list_id`, `values`, `account_id` | Add IOCs (domains, IPs, URLs, … as the list type allows) to a Zero Trust Gateway list. | | `gateway_remove_from_blocklist` | `list_id`, `values`, `account_id` | Remove IOCs from a Gateway list (undo). | -`revoke_access_user` propagates in ~1 minute and does **not** disable the upstream IdP identity — pair it with an IdP-side disable or a `deny` Access policy (via `api_call`) for a durable block. Wire a Gateway list into a Gateway block rule for it to enforce. +`revoke_access_user` propagates in about 1 minute and does **not** disable the upstream IdP identity. For a durable block, also disable the identity in the IdP or add a `deny` Access policy with `api_call`. A Gateway list enforces nothing until you add it to a Gateway block rule. ### DNS / cache response | Action | Parameters | What it does | | --- | --- | --- | -| `edit_dns_record` | `dns_record_id`, `zone_id`, `content`, `name`, `type`, `ttl`, `proxied`, `comment` | Partially update a DNS record (only set fields change) — e.g. re-point a hijacked record to a sinkhole. | -| `delete_dns_record` | `dns_record_id`, `zone_id` | Delete a DNS record — e.g. remove an attacker-created record. | +| `edit_dns_record` | `dns_record_id`, `zone_id`, `content`, `name`, `type`, `ttl`, `proxied`, `comment` | Update part of a DNS record (only the fields that you set change). For example, point a hijacked record to a sinkhole. | +| `delete_dns_record` | `dns_record_id`, `zone_id` | Delete a DNS record. For example, remove a record that an attacker created. | | `purge_cache` | `zone_id`, `purge_everything`, `files`, `hosts`, `tags`, `prefixes` | Purge cache. Choose **exactly one** mode: `purge_everything=true`, or one of `files` / `hosts` / `tags` / `prefixes` (`hosts`/`tags`/`prefixes` are Enterprise-only). | ### Account containment | Action | Parameters | What it does | | --- | --- | --- | -| `remove_member` | `member_id`, `account_id` | Remove a member from the account. Use the membership id (`result[].id` from `list_members`, **not** `user.id`). To downgrade instead of remove, `api_call` a `PUT` with a read-only role. | +| `remove_member` | `member_id`, `account_id` | Remove a member from the account. Use the membership id (`result[].id` from `list_members`, **not** `user.id`). To downgrade a member instead of removing the member, use `api_call` to send a `PUT` with a read-only role. | ## Detection & Response -Example response action that blocks the source IP named in a detection at the Cloudflare edge: +This example response action blocks the source IP from a detection at the Cloudflare edge: ```yaml - action: extension request @@ -153,16 +153,16 @@ Example response action that blocks the source IP named in a detection at the Cl ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> The extension evaluates the values under `extension request` as templates. A bare string without `{{ }}` is a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the extension drops the key from the payload without a message. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context. Workflows that chain (look up the zone, block the IP, then confirm) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold ids between calls. +`extension request` actions do not return a result. The rule engine does not put the response into the evaluation context of the rule. Put chained workflows in a [Playbook](../limacharlie/playbook.md) or an AI agent, because these can keep ids between calls. A chained workflow is, for example: find the zone, block the IP, then confirm the block. ## Notes -- **`success: false` is an error.** Cloudflare frequently answers `200` with `success: false` on a logical error; the extension treats that as a failure and surfaces the Cloudflare error code/message, so a typed action never reports a no-op as success. -- **IP Access Rule scope matters.** An account-scoped rule applies across *all* the account's zones; a zone-scoped rule to one zone. `remove_ip_access_rule` must delete at the same scope the rule was created. -- **`revoke_access_user` is not a durable block.** It kills current sessions but does not disable the IdP identity; pair with an IdP disable or a `deny` policy. -- **Purge is explicit.** `purge_cache` requires exactly one mode; `purge_everything` must be set to `true` deliberately. `tags`/`hosts`/`prefixes` are Enterprise-only. -- **User API tokens can't be revoked cross-member.** Cloudflare's token-revocation endpoint is user-scoped; to contain another member, `remove_member` (or downgrade them via `api_call`). -- **Secret rotation recovers automatically.** A `401` (or a `403`/`400` carrying Cloudflare's authentication error code `10000`) evicts the cached client and re-reads the secret from Secrets Manager on the next call; a `403` permission gap is *not* treated as an auth failure. Error messages are formatted `cloudflare api error on : ` (`cloudflare auth error …` for auth failures), with query strings redacted. -- Unsubscribing from the extension preserves its saved configuration; re-subscribing restores it without reconfiguration. +- **`success: false` is an error.** On a logical error, Cloudflare often answers `200` with `success: false`. The extension treats this as a failure and shows the Cloudflare error code and message. A typed action never reports a no-op as a success. +- **IP Access Rule scope matters.** An account-scoped rule applies to *all* the zones in the account, and a zone-scoped rule applies to one zone. `remove_ip_access_rule` must delete the rule at the scope where you created it. +- **`revoke_access_user` is not a durable block.** It ends the current sessions, but it does not disable the IdP identity. Also disable the identity in the IdP or add a `deny` policy. +- **Purge is explicit.** `purge_cache` needs exactly one mode. You must set `purge_everything` to `true` yourself. `tags`/`hosts`/`prefixes` are Enterprise-only. +- **User API tokens can't be revoked cross-member.** The token-revocation endpoint of Cloudflare is user-scoped. To contain a different member, use `remove_member`, or downgrade the member with `api_call`. +- **Secret rotation recovers automatically.** A `401`, or a `403`/`400` with the Cloudflare authentication error code `10000`, removes the cached client. The extension then re-reads the secret from Secrets Manager on the next call. A `403` from a missing permission is *not* an authentication failure. Error messages have the format `cloudflare api error on : ` (`cloudflare auth error …` for authentication failures), with query strings redacted. +- If you unsubscribe from the extension, the saved configuration stays. If you subscribe again, the extension restores the configuration and you do not configure it again. diff --git a/docs/5-integrations/extensions/third-party/govee.md b/docs/5-integrations/extensions/third-party/govee.md index 12a3df2a1..b303cdc61 100644 --- a/docs/5-integrations/extensions/third-party/govee.md +++ b/docs/5-integrations/extensions/third-party/govee.md @@ -1,23 +1,23 @@ # Govee -The Govee Extension allows you to trigger color changes on your [supported Govee lights](https://developer.govee.com/docs/support-product-model) via a rule response action. It requires you to configure a Govee API key in the extension. +The Govee Extension lets you change the color of your [supported Govee lights](https://developer.govee.com/docs/support-product-model) with a response action in a rule. You must configure a Govee API key in the extension. ## Setup -1. Request an API key from Govee by following their [Apply for a Govee API key instructions](https://developer.govee.com/reference/apply-you-govee-api-key) -2. Get the Device ID (device) and model (sku) of the device you'd like to target by requesting a list of your supported devices from the Govee API: +1. Request an API key from Govee. Obey the [Apply for a Govee API key instructions](https://developer.govee.com/reference/apply-you-govee-api-key). +2. Get the Device ID (device) and the model (sku) of the device that you want to target. Request the list of your supported devices from the Govee API: -```bash -curl --location 'https://openapi.api.govee.com/router/api/v1/user/devices' --header 'Govee-API-Key: YOUR_GOVEE_API_KEY' -``` + ```bash + curl --location 'https://openapi.api.govee.com/router/api/v1/user/devices' --header 'Govee-API-Key: YOUR_GOVEE_API_KEY' + ``` -1. Decide what RGB color(s) you want to use. By default, the extension will alert with red (`255,0,0`), and revert back to white (`255,255,255`) when the alert `duration` has ended. -2. Add your Govee API key to the extension configuration: +3. Decide which RGB colors you want to use. By default, the extension alerts with red (`255,0,0`). It then returns to white (`255,255,255`) when the alert `duration` ends. +4. Add your Govee API key to the extension configuration: ![govee](../../../assets/images/govee.png) ### Usage -When enabled, you may configure the response of a D&R rule to trigger a Govee event. Consider the following example response rule: +When the extension is enabled, you can configure the response of a D&R rule to trigger a Govee event. This example shows a response rule: ```yaml - action: extension request @@ -39,22 +39,22 @@ When enabled, you may configure the response of a D&R rule to trigger a Govee ev period: 1m ``` -Note that the only required fields here are the `device_id` and `device_model`. Values supplied in the example are the defaults. +The only required fields are `device_id` and `device_model`. The values in the example are the defaults. #### Parameters **Required parameters:** -- `device_id`: returned via the Govee API, see example response below -- `device_model`: returned via the Govee API, see example response below +- `device_id`: the Govee API returns this value, see the example response below +- `device_model`: the Govee API returns this value, see the example response below **Optional parameters:** -- `alert_color`: color of the light when alert fires, in [RGB format](https://htmlcolorcodes.com/color-picker/), default `255,0,0` (red) -- `revert_color`: color of the light to return to, after alert fires, in [RGB format](https://htmlcolorcodes.com/color-picker/), default `255,255,255` (white) +- `alert_color`: color of the light when the alert starts, in [RGB format](https://htmlcolorcodes.com/color-picker/), default `255,0,0` (red) +- `revert_color`: color that the light returns to after the alert, in [RGB format](https://htmlcolorcodes.com/color-picker/), default `255,255,255` (white) - `alert_brightness`: brightness of the light, default `100` -- `revert_brightness`: brightness of the light to return to, after alert fires, default `10` -- `duration`: duration of the alert in seconds, how long the light will remain at `alert_color` before returning to `revert_color`, default `30` +- `revert_brightness`: brightness that the light returns to after the alert, default `10` +- `duration`: length of the alert in seconds. The light keeps `alert_color` for this time, then changes to `revert_color`, default `30` **Govee API sample request and response:** diff --git a/docs/5-integrations/extensions/third-party/halopsa.md b/docs/5-integrations/extensions/third-party/halopsa.md index 4990cf5ef..dca6ce92b 100644 --- a/docs/5-integrations/extensions/third-party/halopsa.md +++ b/docs/5-integrations/extensions/third-party/halopsa.md @@ -1,28 +1,28 @@ # HaloPSA -[HaloPSA](https://halopsa.com/) is a professional services automation platform used by MSPs for ticketing, asset management, and time tracking. +MSPs use [HaloPSA](https://halopsa.com/) for ticketing, asset management, and time tracking. It is a professional services automation platform. -The HaloPSA LimaCharlie Extension exposes outbound HaloPSA actions to D&R rules and AI agents: ticket lifecycle (create/update/search), notes and billable time entries, asset linkage from LC sensor telemetry to the MSP CMDB, and client/site lookup. +The HaloPSA LimaCharlie Extension gives outbound HaloPSA actions to D&R rules and AI agents. These actions cover the ticket lifecycle (create, update, and search), notes, and billable time entries. They also link LC sensor telemetry to assets in the MSP CMDB, and look up clients and sites. ## Setup ### 1. Create a HaloPSA API application -In HaloPSA, create an API application (under **Configuration → Integrations → HaloPSA API**) and configure it for the OAuth2 `client_credentials` flow: +In HaloPSA, create an API application under **Configuration → Integrations → HaloPSA API**. Configure it for the OAuth2 `client_credentials` flow: - **Authentication Method:** Client ID and Secret (Services) -- **Login Type:** Log on as **Agent** — pick the HaloPSA agent that should own the tickets, actions, and assets this extension creates. -- **Permissions:** grant `edit:tickets`, `edit:assets`, `read:customers` +- **Login Type:** Log on as **Agent**. Select the HaloPSA agent that owns the tickets, actions, and assets that this extension creates. +- **Permissions:** grant `edit:tickets`, `edit:assets`, and `read:customers` These three scopes are the verified least-privilege set for the six actions below: -- `edit:tickets` covers `create_ticket`, `update_ticket`, `search_tickets`, and `add_action`. Actions are a HaloPSA ticket sub-resource — there is no separate `read:actions` or `edit:actions` scope (the HaloPSA token endpoint rejects them as `invalid_scope`). +- `edit:tickets` covers `create_ticket`, `update_ticket`, `search_tickets`, and `add_action`. An action is a sub-resource of a HaloPSA ticket. There is no separate `read:actions` or `edit:actions` scope; the HaloPSA token endpoint rejects them as `invalid_scope`. - `edit:assets` covers asset lookup and the create-if-missing path in `link_asset_to_ticket`. -- `read:customers` covers `lookup_client_site` for both clients *and* sites (sites are a customer sub-resource). The extension never writes clients or sites, so `edit:customers` is not required. +- `read:customers` covers `lookup_client_site` for both clients *and* sites (a site is a sub-resource of a customer). The extension never writes clients or sites, so you do not need `edit:customers`. -If you'd rather not enumerate scopes, the extension's default of `all` also works. +If you do not want to list the scopes, the default of `all` in the extension also works. -Copy the **Client ID** and **Client Secret** — you will need them in the next step. Refer to HaloPSA's own product documentation for the current UI path; the labels above may differ slightly across HaloPSA versions. +Copy the **Client ID** and the **Client Secret**. You need them in the next step. For the current path in the UI, see the HaloPSA product documentation. The labels above can differ between HaloPSA versions. ### 2. Subscribe to the extension @@ -30,7 +30,7 @@ Subscribe to `ext-halopsa` from the LimaCharlie **Marketplace** (Extensions → ### 3. Store the client secret -In **Secrets Manager**, create a new secret (for example `halopsa-client-secret`) and paste the HaloPSA Client Secret as its value. +In **Secrets Manager**, create a new secret, for example `halopsa-client-secret`. Paste the HaloPSA Client Secret as its value. ### 4. Configure the extension @@ -38,17 +38,17 @@ In **Extensions → ext-halopsa → Configuration**, fill in: | Field | Value | | --- | --- | -| `instance_url` | Your HaloPSA tenant URL, e.g. `https://acme.halopsa.com` | +| `instance_url` | The URL of your HaloPSA tenant, for example `https://acme.halopsa.com` | | `client_id` | The Client ID from step 1 | -| `client_secret` | A reference to the secret created in step 3, e.g. `hive://secret/halopsa-client-secret` | -| `tenant` | (optional) Tenant identifier — only needed on shared-auth hosted deployments | -| `scope` | (optional) OAuth2 scopes (space-separated). Defaults to `all`. | +| `client_secret` | A reference to the secret from step 3, for example `hive://secret/halopsa-client-secret` | +| `tenant` | (optional) Tenant identifier. Needed only on hosted deployments with shared authentication | +| `scope` | (optional) OAuth2 scopes, separated by spaces. Defaults to `all`. | -The configuration is validated at save time against `instance_url`, `client_id`, and `client_secret`. If the OAuth2 token cannot be obtained, requests will surface a `401` from the upstream HaloPSA API. +At save time, the configuration is validated against `instance_url`, `client_id`, and `client_secret`. If the OAuth2 token cannot be obtained, requests show a `401` from the upstream HaloPSA API. ## Actions -The extension exposes six actions, all accepting a JSON request body when invoked from a D&R rule via `extension request`. +The extension gives six actions. Each action accepts a JSON request body when a D&R rule calls it with `extension request`. ### `create_ticket` @@ -72,13 +72,13 @@ Open a new ticket. Only `summary` is required. | `parent_id` | int | Parent ticket id (for sub-tickets). | | `asset_ids` | list of int | Asset ids to attach. | | `customfields` | list of object | Each entry `{name\|id, value}`. | -| `extra` | object | Raw HaloPSA ticket fields to merge into the request — escape hatch for fields not modeled above. | +| `extra` | object | Raw HaloPSA ticket fields to merge into the request. Use it for fields that the list above does not model. | -Returns the created ticket, including its assigned `id`. +Returns the new ticket and its assigned `id`. ### `update_ticket` -Update an existing ticket. Use to change status (which drives HaloPSA status → outcome → workflow transitions), reassign, set priority, or set the linked assets. +Update an existing ticket. Use this action to change the status, to reassign the ticket, to set the priority, or to set the linked assets. A status change drives the HaloPSA status → outcome → workflow transitions. | Field | Type | Notes | | --- | --- | --- | @@ -88,62 +88,62 @@ Update an existing ticket. Use to change status (which drives HaloPSA status → | `status_id` | int | New status id. | | `agent_id` | int | New assignee. | | `priority_id` | int | New priority. | -| `asset_ids` | list of int | **Replaces** the ticket's asset list. Use `link_asset_to_ticket` to merge a new asset into the existing list. | +| `asset_ids` | list of int | **Replaces** the asset list of the ticket. Use `link_asset_to_ticket` to merge a new asset into the existing list. | | `customfields` | list of object | Custom fields to set. | | `extra` | object | Raw HaloPSA ticket fields to merge. | ### `search_tickets` -Search/list tickets. Useful to deduplicate before creating, or to look up existing work for an asset. +Search tickets or list them. Use this action to avoid duplicates before you create a ticket, or to find existing work for an asset. | Field | Type | Notes | | --- | --- | --- | -| `search` | string | Free-text search across ticket summary/details. | +| `search` | string | Free-text search across the summary and the details of a ticket. | | `client_id` | int | Restrict to a client. | | `agent_id` | int | Restrict to an assignee. | -| `status_ids` | string | Comma-separated status ids. | +| `status_ids` | string | Status ids, separated by commas. | | `tickettype_id` | int | Restrict to a ticket type. | | `page_size` | int | Default `50`. | | `page_no` | int | Default `1` (1-based). | -| `order` | string | Order-by field (e.g. `id`). | +| `order` | string | Order-by field (for example `id`). | | `orderdesc` | bool | Descending order. | Returns `{ "record_count": N, "tickets": [...] }`. ### `add_action` -Append a HaloPSA Action to a ticket: a private note (agents only) or a public reply (visible to the end-user), optionally with billable time. Useful for AI agents to record triage findings and log work time. +Append a HaloPSA Action to a ticket. The Action is a private note (agents only) or a public reply that the end-user sees. It can also carry billable time. AI agents can use this action to record triage findings and work time. | Field | Type | Notes | | --- | --- | --- | | `ticket_id` | int | **Required.** Ticket id to append to. | -| `note` | string | **Required.** Note/reply content. | +| `note` | string | **Required.** Content of the note or the reply. | | `hiddenfromuser` | bool | `true` (default) = private; `false` = public reply. | -| `timetaken` | int | Time taken on this action (whole hours only). For fractional hours, pass via `extra.timetaken`. | -| `actionchargehours` | int | Billable hours (whole hours only). For fractional hours, pass via `extra.actionchargehours`. | +| `timetaken` | int | Time taken on this action (whole hours only). For fractional hours, use `extra.timetaken`. | +| `actionchargehours` | int | Billable hours (whole hours only). For fractional hours, use `extra.actionchargehours`. | | `outcome` | string | Outcome label (drives HaloPSA workflow transitions). Defaults to `Note`. | | `extra` | object | Raw HaloPSA action fields to merge. | -> Defaults to **private** (`hiddenfromuser=true`) to avoid accidentally pushing security notes to end-users. Set `hiddenfromuser: false` explicitly for a public reply. +> The default is **private** (`hiddenfromuser=true`), so that security notes do not go to end-users by accident. For a public reply, set `hiddenfromuser: false`. ### `link_asset_to_ticket` -Resolve a hostname to a HaloPSA asset under the given client/site, optionally creating the asset if missing, and attach it to the ticket. Bridges LC sensor telemetry to the MSP CMDB. +Resolve a hostname to a HaloPSA asset under the given client or site, then attach the asset to the ticket. The action can also create the asset if it does not exist. This action links LC sensor telemetry to the MSP CMDB. | Field | Type | Notes | | --- | --- | --- | | `ticket_id` | int | **Required.** Ticket id to link the asset to. | -| `hostname` | string | **Required.** Hostname to resolve (matched via `inventory_number` / `key_field`). | +| `hostname` | string | **Required.** Hostname to resolve. The match uses `inventory_number` or `key_field`. | | `client_id` | int | Required when the asset must be created. | | `site_id` | int | Used on asset create. | | `asset_type_id` | int | Required when the asset must be created (HaloPSA rejects asset creates without an asset type). | -| `create_if_missing` | bool | If `true` (default), create the asset when no match is found. | +| `create_if_missing` | bool | If `true` (default), create the asset when there is no match. | -Returns `{ "asset_id": N, "asset_created": bool, "asset": {...}, "ticket": {...} }`. The link is idempotent — re-running against an already-linked asset will not produce duplicates. +Returns `{ "asset_id": N, "asset_created": bool, "asset": {...}, "ticket": {...} }`. The link is idempotent. If you run the action again on an asset that is already linked, it makes no duplicates. ### `lookup_client_site` -Resolve a HaloPSA client or site id from a name. Useful as plumbing for AI agents that need to map an LC org to a Halo client. +Resolve a HaloPSA client id or site id from a name. AI agents use this action to map an LC org to a Halo client. | Field | Type | Notes | | --- | --- | --- | @@ -153,11 +153,11 @@ Resolve a HaloPSA client or site id from a name. Useful as plumbing for AI agent | `page_size` | int | Default `50`. | | `page_no` | int | Default `1`. | -Returns `{ "record_count": N, "clients": [...] }` or `{ "record_count": N, "sites": [...] }` depending on `type`. +Returns `{ "record_count": N, "clients": [...] }` or `{ "record_count": N, "sites": [...] }`, based on `type`. ## Detection & Response -Example response action that opens a HaloPSA ticket for a detection: +This example response action opens a HaloPSA ticket for a detection: ```yaml - action: extension request @@ -173,11 +173,11 @@ Example response action that opens a HaloPSA ticket for a detection: ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> The values under `extension request` are evaluated as templates. A bare string without `{{ }}` is read as a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the key is dropped from the payload without a message. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context, so the freshly-created ticket id is not available to a subsequent action in the same rule. Workflows that need to chain (open a ticket, then link an asset, then add a note) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold the ticket id between calls. +`extension request` actions do not return a result. The rule engine does not put the response into the evaluation context of the rule. The id of the new ticket is therefore not available to a later action in the same rule. A workflow that must chain steps (open a ticket, link an asset, then add a note) belongs in a [Playbook](../limacharlie/playbook.md) or in an AI agent. A Playbook or an AI agent can hold the ticket id between calls. -To append triage findings on an existing ticket (for example from a Playbook or AI agent that already knows the ticket id), use `add_action`: +Use `add_action` to append triage findings to an existing ticket. For example, a Playbook or an AI agent that already knows the ticket id can call it: ```yaml - action: extension request @@ -193,6 +193,6 @@ To append triage findings on an existing ticket (for example from a Playbook or ## Notes -- The OAuth2 access token returned by HaloPSA is cached per `(org, instance_url, client_id, secret)` for the lifetime of a client. Rotating the secret in the Secrets Manager evicts the cached client on the next surfaced `401`. -- `actionchargehours` will only result in a billable charge if the tenant has a charge rate configured for the agent posting the action; otherwise HaloPSA accepts the value but reports `Charge Rate: No Charge`. -- HaloPSA represents a ticket's main body as the first entry in its action timeline — `update_ticket.details` replaces that first entry rather than mutating a separate body field. +- HaloPSA returns an OAuth2 access token. The token is cached for each `(org, instance_url, client_id, secret)` for the lifetime of a client. If you rotate the secret in the Secrets Manager, the next `401` evicts the cached client. +- `actionchargehours` results in a billable charge only if the tenant has a charge rate for the agent that posts the action. If there is no charge rate, HaloPSA accepts the value but reports `Charge Rate: No Charge`. +- HaloPSA keeps the main body of a ticket as the first entry in its action timeline. `update_ticket.details` replaces that first entry. It does not change a separate body field. diff --git a/docs/5-integrations/extensions/third-party/hayabusa.md b/docs/5-integrations/extensions/third-party/hayabusa.md index 026025c8d..2fc8594fb 100644 --- a/docs/5-integrations/extensions/third-party/hayabusa.md +++ b/docs/5-integrations/extensions/third-party/hayabusa.md @@ -2,17 +2,17 @@ Hayabusa Extension Pricing -While it is free to enable the Hayabusa extension, pricing is applied to downloaded and processed artifacts -- $0.02/GB for the original artifact, and $0.5/GB for the generation of the Hayabusa artifact. +The Hayabusa extension is free to enable, but downloaded and processed artifacts have a price: $0.02/GB for the original artifact, and $0.5/GB to generate the Hayabusa artifact. -The [Hayabusa](https://github.com/Yamato-Security/hayabusa) extension allows you to run Hayabusa against a specified event log (.evtx) or a collection of event logs (.zip). +The [Hayabusa](https://github.com/Yamato-Security/hayabusa) extension lets you run Hayabusa against one event log (.evtx) or a collection of event logs (.zip). -Hayabusa is a Windows event log fast forensics timeline generator and threat hunting tool created by the Yamato Security group in Japan. +Hayabusa is a fast forensics tool for Windows event logs. It generates timelines and helps you hunt for threats. The Yamato Security group in Japan created it. -LimaCharlie will automatically kick off the analysis based off of the artifact ID provided in a rule action, or you can run it manually via the extension. +LimaCharlie starts the analysis automatically from the artifact ID in a rule action. You can also run the analysis by hand from the extension. ## Configuration -When enabled, you may configure the response of a D&R rule to run a Hayabusa analysis against an artifact event. Consider the following example D&R rule: +After you enable the extension, you can configure the response of a D&R rule to run a Hayabusa analysis against an artifact event. See this example D&R rule: **Detect:** @@ -37,7 +37,7 @@ artifact type: wel min_rule_level: '{{ "informational" }}' ``` -Note that the only required field here is the `artifact_id`. The other values supplied in the example are the defaults. +The only required field is `artifact_id`. The other values in the example are the defaults. ## Results @@ -47,17 +47,17 @@ hayabusa update-rules hayabusa csv-timeline -f /path/to/your/artifact --RFC-3339 -p timesketch-$profile --min-level $min_rule_level --no-wizard --quiet -o $artifact_id.csv -U ``` -Upon running Hayabusa, a CSV file is generated. The CSV file will be uploaded as a LimaCharlie artifact. +Hayabusa generates a CSV file when it runs. The CSV file is uploaded as a LimaCharlie artifact. -The resulting CSV is compatible with Timesketch, and can be imported [as a timeline](https://timesketch.org/guides/user/upload-data/). +The CSV is compatible with Timesketch, and you can import it [as a timeline](https://timesketch.org/guides/user/upload-data/). -Outputting your data to Google BigQuery is another option, and is [outlined here](../../tutorials/hayabusa-bigquery.md) +You can also output your data to Google BigQuery. For the steps, see [Hayabusa to BigQuery](../../tutorials/hayabusa-bigquery.md). -Several events will be pushed to the `ext-hayabusa` Sensor timeline: +These events are sent to the `ext-hayabusa` Sensor timeline: -- `hayabusa_results`: contains the results summary from the Hayabusa output +- `hayabusa_results`: contains the summary of the results from the Hayabusa output - `hayabusa_artifact`: contains the `artifact_id` of the CSV file that was uploaded to LimaCharlie -- `hayabusa_event`: many of these will be sent to the timeline if you check the checkbox or parameter for `Send to timeline`, and it contains the raw contents of the Hayabusa CSV output in JSON format +- `hayabusa_event`: contains the raw contents of the Hayabusa CSV output in JSON format. If you set the checkbox or the parameter for `Send to timeline`, many of these events go to the timeline ## Arguments @@ -65,29 +65,29 @@ Several events will be pushed to the `ext-hayabusa` Sensor timeline: - `profile`: either `minimal`, `standard`, `verbose`, `all-field-info`, `all-field-info-verbose`, `super-verbose`, `timesketch-minimal`, or `timesketch-verbose` - Default: `timesketch-verbose` - - [More details](https://github.com/Yamato-Security/hayabusa?tab=readme-ov-file#7-timesketch-minimal-profile-output) -- `min_rule_level`: `informational`, `low`, `medium`, `high`, or `critical`, [more details](https://github.com/Yamato-Security/hayabusa?tab=readme-ov-file#dfir-timeline-commands-1) + - [Hayabusa timesketch-minimal profile output](https://github.com/Yamato-Security/hayabusa?tab=readme-ov-file#7-timesketch-minimal-profile-output) +- `min_rule_level`: `informational`, `low`, `medium`, `high`, or `critical`, see [Hayabusa DFIR timeline commands](https://github.com/Yamato-Security/hayabusa?tab=readme-ov-file#dfir-timeline-commands-1) - Default: `informational` -- `send_to_timeline`: whether or not to ingest the Hayabusa results into the sensor timeline as events, boolean, default `true` +- `send_to_timeline`: boolean that controls if the Hayabusa results are ingested into the sensor timeline as events, default `true` ## Usage -If you use the LimaCharlie Velociraptor extension, a good use case of this extension would be to trigger Hayabusa analysis upon ingestion of a Velociraptor KAPE files artifact. +If you use the LimaCharlie Velociraptor extension, you can trigger a Hayabusa analysis when LimaCharlie ingests a Velociraptor KAPE files artifact. -Go to Extensions / Velociraptor, and run Collect Artifact request. +Go to Extensions / Velociraptor. Run the Collect Artifact request. ![hayabusa 1](../../../assets/images/hayabusa-1.png) -Kick off a `Windows.KapeFiles.Targets` artifact collection in the LimaCharlie Velociraptor extension +Start a `Windows.KapeFiles.Targets` artifact collection in the LimaCharlie Velociraptor extension **Argument options:** - `EventLogs=Y` ![hayabusa 2](../../../assets/images/hayabusa-2.png) -- `KapeTriage=Y` - this is an option, however the extension will first take all .evtx files out of the triage collection and send them through Hayabusa, and ignore the rest, so there is more overhead involved, versus just using `EventLogs=Y`. +- `KapeTriage=Y` - this is also an option. The extension takes all .evtx files out of the triage collection, sends them through Hayabusa, and ignores the rest. This adds more overhead than `EventLogs=Y`. -Configure a D&R rule to look for these events upon ingestion, and then trigger the Hayabusa extension: +Configure a D&R rule to look for these events at ingestion, and then trigger the Hayabusa extension: **Detect:** @@ -119,9 +119,9 @@ rules: Note -This capability depends on setting the parameter to send Hayabusa output to the sensor timeline with `send_to_timeline: true` +This capability needs the parameter that sends the Hayabusa output to the sensor timeline: `send_to_timeline: true` -Assuming you want Hayabusa detections of a certain `Level` or severity sent directly to your LimaCharlie detections stream, you can use the following D&R rule to accomplish this: +To send Hayabusa detections of a given `Level` or severity directly to your LimaCharlie detections stream, use this D&R rule: **Detect:** @@ -145,7 +145,7 @@ rules: Hayabusa - {{ .event.results.Level }} - {{ .event.results.message }} ``` -The resulting detection would look something like this: +The detection looks like this: ```json { diff --git a/docs/5-integrations/extensions/third-party/index.md b/docs/5-integrations/extensions/third-party/index.md index e2472a0ed..995b8cbc8 100644 --- a/docs/5-integrations/extensions/third-party/index.md +++ b/docs/5-integrations/extensions/third-party/index.md @@ -1,6 +1,6 @@ # Third-Party Extensions -Extensions built by third-party developers that integrate external tools and services with LimaCharlie. +Third-party developers build these extensions. The extensions integrate external tools and services with LimaCharlie. ## Available Extensions diff --git a/docs/5-integrations/extensions/third-party/microsoft-response.md b/docs/5-integrations/extensions/third-party/microsoft-response.md index ac126af3b..54d097f0f 100644 --- a/docs/5-integrations/extensions/third-party/microsoft-response.md +++ b/docs/5-integrations/extensions/third-party/microsoft-response.md @@ -1,23 +1,23 @@ # Microsoft Response -The Microsoft Response LimaCharlie Extension exposes the incident-response and investigation surface of Microsoft's cloud security platforms — **Microsoft Graph** (Entra ID identities, Identity Protection, groups, Intune devices, audit logs, and the Defender XDR security API for cross-product alerts, incidents, and advanced hunting) and **Microsoft Defender for Endpoint** (machine isolation, scans, forensics, file quarantine, alerts, file intelligence, custom indicators) — to D&R rules and AI agents. It enables automated investigation and containment of account and endpoint compromise directly from detections. +The Microsoft Response LimaCharlie Extension gives D&R rules and AI agents the incident-response and investigation surface of two Microsoft cloud security platforms. **Microsoft Graph** supplies Entra ID identities, Identity Protection, groups, Intune devices, and audit logs. It also supplies the Defender XDR security API for cross-product alerts, incidents, and advanced hunting. **Microsoft Defender for Endpoint** supplies machine isolation, scans, forensics, file quarantine, alerts, file intelligence, and custom indicators. With the extension, you can investigate and contain a compromised account or endpoint directly from a detection. The extension provides two layers: -- **Typed actions** for the common containment, triage, and investigation workflows, with friendly parameter names and built-in safety rails. -- A generic **`api_call`** passthrough for any Graph or Defender endpoint not covered by a typed action. +- **Typed actions** for the common containment, triage, and investigation workflows. They use clear parameter names and have built-in safety limits. +- A generic **`api_call`** passthrough for any Graph or Defender endpoint that no typed action covers. -Authentication is OAuth2 **client credentials** against an Entra app registration — no user interaction, no delegated tokens. +Authentication uses OAuth2 **client credentials** against an Entra app registration. There is no user interaction and there are no delegated tokens. ## Setup ### 1. Create an Entra app registration -In the Azure portal (**Entra ID → App registrations → New registration**), create an app registration and note its **Application (client) ID** and your **Directory (tenant) ID**. Create a **client secret** under *Certificates & secrets*. +In the Azure portal, go to **Entra ID → App registrations → New registration** and create an app registration. Record its **Application (client) ID** and your **Directory (tenant) ID**. Create a **client secret** under *Certificates & secrets*. ### 2. Grant application permissions -Under *API permissions*, add **application** permissions (not delegated) and grant **admin consent**. The least-privilege set per capability: +Under *API permissions*, add **application** permissions, not delegated permissions, and grant **admin consent**. The least-privilege set for each capability: | Capability | Permission | API | | --- | --- | --- | @@ -27,9 +27,9 @@ Under *API permissions*, add **application** permissions (not delegated) and gra | Reset password | `User-PasswordProfile.ReadWrite.All` | Microsoft Graph | | List authentication methods | `UserAuthenticationMethod.Read.All` | Microsoft Graph | | User group/role memberships (`list_user_groups`) | `Directory.Read.All` | Microsoft Graph | -| Risky users (read / confirm / dismiss) | `IdentityRiskyUser.ReadWrite.All` (`IdentityRiskyUser.Read.All` suffices for reads) | Microsoft Graph | +| Risky users (read / confirm / dismiss) | `IdentityRiskyUser.ReadWrite.All` (`IdentityRiskyUser.Read.All` is enough for reads) | Microsoft Graph | | Risk detections (`list_risk_detections`) | `IdentityRiskEvent.Read.All` | Microsoft Graph | -| Groups read / membership change | `GroupMember.ReadWrite.All` (`GroupMember.Read.All` suffices for reads) | Microsoft Graph | +| Groups read / membership change | `GroupMember.ReadWrite.All` (`GroupMember.Read.All` is enough for reads) | Microsoft Graph | | Sign-in & directory audit logs | `AuditLog.Read.All` | Microsoft Graph | | Defender XDR alerts (read / update + comment) | `SecurityAlert.Read.All` / `SecurityAlert.ReadWrite.All` | Microsoft Graph | | Defender XDR incidents (read / update) | `SecurityIncident.Read.All` / `SecurityIncident.ReadWrite.All` | Microsoft Graph | @@ -47,11 +47,11 @@ Under *API permissions*, add **application** permissions (not delegated) and gra | Advanced hunting (`run_advanced_query`) | `AdvancedQuery.Read.All` | WindowsDefenderATP | | Custom indicators (IoCs) | `Ti.ReadWrite.All` | WindowsDefenderATP | -Only add what you will use — every action degrades independently with a `403` if its permission is missing. +Add only the permissions that you use. If a permission is missing, only the action that needs it fails, with a `403`. -> **Privileged user writes need a directory role too.** For `disable_user`, `enable_user`, and `reset_user_password`, Graph permissions alone are not sufficient: the app's service principal must also hold an Entra **directory role** (e.g. *User Administrator*) covering the target user. A `403` on these actions is a consent/role problem, not a bug. +> **Privileged user writes need a directory role too.** Graph permissions alone are not enough for `disable_user`, `enable_user`, and `reset_user_password`. The service principal of the app must also hold an Entra **directory role** (for example *User Administrator*) that covers the target user. A `403` on these actions is a problem with consent or roles, not a bug. > -> **Identity Protection requires Entra ID P2.** `list_risky_users`, `get_user_risk`, `confirm_user_compromised`, and `dismiss_user_risk` return `403` on tenants without a P2 license. `list_risk_detections` and the sign-in log (`list_sign_ins`, `get_signin_history`) require P1 or P2. +> **Identity Protection needs Entra ID P2.** `list_risky_users`, `get_user_risk`, `confirm_user_compromised`, and `dismiss_user_risk` return `403` on a tenant without a P2 license. `list_risk_detections` and the sign-in log (`list_sign_ins`, `get_signin_history`) need P1 or P2. ### 3. Subscribe to the extension @@ -59,7 +59,7 @@ Subscribe to `ext-microsoft-response` from the LimaCharlie **Marketplace** (Exte ### 4. Store the client secret -In **Secrets Manager**, create a new secret (for example `msft-response-client-secret`) and paste the client secret as its value. +In **Secrets Manager**, create a new secret, for example `msft-response-client-secret`. Paste the client secret as its value. ### 5. Configure the extension @@ -69,16 +69,16 @@ In **Extensions → ext-microsoft-response → Configuration**, fill in: | --- | --- | --- | | `tenant_id` | yes | Entra (Azure AD) tenant ID (GUID) or a verified domain name. | | `client_id` | yes | App registration Application (client) ID. | -| `client_secret` | yes | Reference to the secret created in step 4, e.g. `hive://secret/msft-response-client-secret`. | +| `client_secret` | yes | Reference to the secret from step 4, for example `hive://secret/msft-response-client-secret`. | | `login_base_url` | no | OAuth endpoint override for sovereign clouds. Default `https://login.microsoftonline.com`. | | `graph_base_url` | no | Microsoft Graph base override. Default `https://graph.microsoft.com/v1.0`. | | `defender_base_url` | no | Defender for Endpoint base override. Default `https://api.securitycenter.microsoft.com/api`. | -The three base-URL overrides support sovereign clouds (US Government GCC High / DoD, China 21Vianet); leave them empty for the public cloud. +The three base-URL overrides support sovereign clouds (US Government GCC High / DoD, China 21Vianet). Leave them empty for the public cloud. ## Actions -Every action that targets an entity requires an explicit selector (`user_id`, `device_id`, `machine_id`, …) — the extension refuses to run without one, preventing accidental fleet-wide containment. +Every action that targets an entity needs an explicit selector (`user_id`, `device_id`, `machine_id`, …). The extension does not run without one. This stops accidental containment of the full fleet. ### Common list parameters @@ -86,14 +86,14 @@ The `list_*` actions share an OData query schema and return `{data: [...], pagin | Field | Type | Notes | | --- | --- | --- | -| `filter` | string | OData `$filter`, e.g. `accountEnabled eq false`. | -| `select` | string | OData `$select` — comma-separated fields. | -| `search` | string | Free-text `$search`, e.g. `displayName:alex` (Graph sets `ConsistencyLevel: eventual` automatically). | -| `order_by` | string | OData `$orderby`, e.g. `createdDateTime desc`. | +| `filter` | string | OData `$filter`, for example `accountEnabled eq false`. | +| `select` | string | OData `$select`. Fields are separated by commas. | +| `search` | string | Free-text `$search`, for example `displayName:alex` (Graph sets `ConsistencyLevel: eventual` automatically). | +| `order_by` | string | OData `$orderby`, for example `createdDateTime desc`. | | `top` | int | Page size, default `100`, clamped to `999`. | | `count` | bool | Request a `$count`. | -| `next_link` | string | Opaque `@odata.nextLink` from a previous response — pass it back to fetch the next page. | -| `extra_query` | object | Raw query params merged into the request (escape hatch). | +| `next_link` | string | Opaque `@odata.nextLink` from a previous response. Pass it back to get the next page. | +| `extra_query` | object | Raw query parameters merged into the request, for parameters that the fields above do not cover. | ### Generic @@ -103,72 +103,72 @@ Generic passthrough to Graph or Defender for Endpoint. | Field | Type | Notes | | --- | --- | --- | -| `service` | enum | `graph` (default) or `defender`. Token audience is handled automatically. | +| `service` | enum | `graph` (default) or `defender`. The token audience is handled automatically. | | `method` | enum | `GET` (default), `POST`, `PATCH`, `PUT`, `DELETE`. | -| `path` | string | **Required.** Path relative to the service base (e.g. `users/{id}/revokeSignInSessions`) or a full `@odata.nextLink` URL. | +| `path` | string | **Required.** Path relative to the service base (for example `users/{id}/revokeSignInSessions`) or a full `@odata.nextLink` URL. | | `query` | object | Query-string parameters (`$filter`, `$select`, `$top`, …). | -| `headers` | object | Extra request headers, e.g. `{"ConsistencyLevel": "eventual"}`. | -| `body` | object | JSON body for `POST`/`PATCH`/`PUT`. Note Defender bodies use PascalCase keys (`IsolationType`, `Comment`, …). | +| `headers` | object | Extra request headers, for example `{"ConsistencyLevel": "eventual"}`. | +| `body` | object | JSON body for `POST`/`PATCH`/`PUT`. Defender bodies use PascalCase keys (`IsolationType`, `Comment`, …). | ### Entra ID identities | Action | Parameters | What it does | | --- | --- | --- | -| `list_users` | common list params | List/search users. Add `accountEnabled` to `select` to read it (not returned by default). | +| `list_users` | common list params | List users or search users. To read `accountEnabled`, add it to `select`; it is not returned by default. | | `get_user` | `user_id`, `select` | Get one user. Defaults to an investigation-oriented `$select` (`accountEnabled`, `createdDateTime`, `lastPasswordChangeDateTime`, `signInSessionsValidFromDateTime`, `proxyAddresses`, `otherMails`, ...). | -| `disable_user` | `user_id` | Set `accountEnabled=false` — blocks new sign-ins immediately. Reverse with `enable_user`. | -| `enable_user` | `user_id` | Re-enable a disabled user. | -| `revoke_sign_in_sessions` | `user_id` | Invalidate all refresh tokens / sessions, forcing re-authentication everywhere. Takes a few minutes to fully propagate. | -| `reset_user_password` | `user_id`, `password`, `force_change_password_next_sign_in` (default `true`) | Set a new password via `passwordProfile`. Requires a directory role (see Setup). | -| `list_auth_methods` | `user_id` | List registered authentication methods — spot attacker-registered MFA. | -| `list_user_groups` | `user_id` + common list params | List the groups, directory roles, and administrative units the user is a direct member of — check whether a compromised user holds privileged roles. | +| `disable_user` | `user_id` | Set `accountEnabled=false`. This blocks new sign-ins immediately. To reverse it, use `enable_user`. | +| `enable_user` | `user_id` | Enable a disabled user again. | +| `revoke_sign_in_sessions` | `user_id` | Invalidate all refresh tokens and sessions. The user must authenticate again everywhere. Full propagation takes a few minutes. | +| `reset_user_password` | `user_id`, `password`, `force_change_password_next_sign_in` (default `true`) | Set a new password with `passwordProfile`. Needs a directory role (see Setup). | +| `list_auth_methods` | `user_id` | List the registered authentication methods. Use it to find MFA that an attacker registered. | +| `list_user_groups` | `user_id` + common list params | List the groups, directory roles, and administrative units that the user is a direct member of. Use it to check if a compromised user holds privileged roles. | `user_id` accepts either the user object ID (GUID) or the userPrincipalName (UPN). -For full account containment, combine `disable_user` with `revoke_sign_in_sessions`: disabling blocks new sign-ins, revoking kills existing sessions. +For full account containment, combine `disable_user` with `revoke_sign_in_sessions`. `disable_user` blocks new sign-ins, and `revoke_sign_in_sessions` ends the existing sessions. ### Identity Protection (Entra ID P2) | Action | Parameters | What it does | | --- | --- | --- | | `list_risky_users` | common list params | Users flagged by Identity Protection (`riskLevel`, `riskState`, `riskDetail`). | -| `get_user_risk` | `user_id` | One user's riskyUser record. Accepts a GUID or a UPN (the UPN is resolved with one extra lookup). A `404` means the user has no risk record. | -| `list_risk_detections` | common list params | Individual risk detections (`riskEventType` like `passwordSpray`, `impossibleTravel`, `leakedCredentials`; `ipAddress`, `location`, `detectedDateTime`). P1 tenants see premium detections as `riskEventType=generic`. Page size caps at 500. | -| `confirm_user_compromised` | `user_ids` (list of GUIDs) | Mark users confirmed-compromised, raising risk to high (drives risk-based Conditional Access). | -| `dismiss_user_risk` | `user_ids` (list of GUIDs) | Clear the risk on users. Max 60 per call. | +| `get_user_risk` | `user_id` | The riskyUser record of one user. Accepts a GUID or a UPN; a UPN needs one more lookup. A `404` means that the user has no risk record. | +| `list_risk_detections` | common list params | Individual risk detections (`riskEventType` such as `passwordSpray`, `impossibleTravel`, `leakedCredentials`; `ipAddress`, `location`, `detectedDateTime`). On a P1 tenant, premium detections show as `riskEventType=generic`. The page size caps at 500. | +| `confirm_user_compromised` | `user_ids` (list of GUIDs) | Mark users as confirmed-compromised. This raises the risk to high and drives risk-based Conditional Access. | +| `dismiss_user_risk` | `user_ids` (list of GUIDs) | Clear the risk on users. Maximum 60 for each call. | ### Directory & audit reads | Action | Parameters | What it does | | --- | --- | --- | -| `list_groups` | common list params | List groups (e.g. find a quarantine or privileged group). | +| `list_groups` | common list params | List groups, for example to find a quarantine group or a privileged group. | | `get_group` | `group_id`, `select` | Get one group by object id. | -| `list_group_members` | `group_id` + common list params | List a group's direct members — enumerate who sits in a privileged group. | +| `list_group_members` | `group_id` + common list params | List the direct members of a group. Use it to enumerate the members of a privileged group. | | `list_sign_ins` | common list params | Entra sign-in events. Always scope with a `createdDateTime` filter. | -| `get_signin_history` | `user_id`, `days` (default 7), `filter`, `top`, `next_link` | One user's sign-ins over a trailing window, newest first. Builds the `$filter` for you (GUID → `userId`, otherwise `userPrincipalName`); `filter` is AND-ed on top (e.g. `status/errorCode eq 0`). Key fields: `createdDateTime`, `ipAddress`, `location`, `deviceDetail`, `status.errorCode`, `riskLevelDuringSignIn`. | -| `list_directory_audits` | common list params | Directory audit log — who changed what. | +| `get_signin_history` | `user_id`, `days` (default 7), `filter`, `top`, `next_link` | The sign-ins of one user over a trailing window, newest first. The action builds the `$filter` for you (GUID → `userId`, otherwise `userPrincipalName`). Your `filter` is AND-ed on top, for example `status/errorCode eq 0`. Key fields: `createdDateTime`, `ipAddress`, `location`, `deviceDetail`, `status.errorCode`, `riskLevelDuringSignIn`. | +| `list_directory_audits` | common list params | Directory audit log. It shows who changed what. | ### Microsoft Defender XDR (Graph security API) -Cross-product alerts and incidents from Defender for Endpoint / Office 365 / Identity / Cloud Apps, Entra ID Protection, and Sentinel. Enum values here are **camelCase** (`new`, `inProgress`, `resolved`) — unlike the Defender for Endpoint API below. +Cross-product alerts and incidents from Defender for Endpoint / Office 365 / Identity / Cloud Apps, Entra ID Protection, and Sentinel. The enum values here are **camelCase** (`new`, `inProgress`, `resolved`). The Defender for Endpoint API below uses a different form. | Action | Parameters | What it does | | --- | --- | --- | -| `list_security_alerts` | `filter`, `top`, `next_link`, `extra_query` | List XDR alerts (`security/alerts_v2`). Filterable on `createdDateTime`, `severity`, `status`, `serviceSource`, `classification`, `determination`, `assignedTo`. Evidence is embedded in each alert. | +| `list_security_alerts` | `filter`, `top`, `next_link`, `extra_query` | List XDR alerts (`security/alerts_v2`). You can filter on `createdDateTime`, `severity`, `status`, `serviceSource`, `classification`, `determination`, and `assignedTo`. Each alert contains its evidence. | | `get_security_alert` | `alert_id` | One XDR alert with evidence (devices, files, processes, IPs, users), MITRE techniques, comments. | -| `update_security_alert` | `alert_id`, `status`, `classification`, `determination`, `assigned_to` | Triage an alert; only provided fields change. Returns the updated alert. | -| `add_security_alert_comment` | `alert_id`, `comment` | Append a comment (e.g. record the automated response taken). Returns the alert's full comment list. | -| `list_security_incidents` | `filter`, `top`, `next_link`, `extra_query` | List XDR incidents. Add `extra_query: {"$expand": "alerts"}` to embed each incident's alerts. | -| `get_security_incident` | `incident_id` | One incident (numeric-string id, e.g. `"29"`). | +| `update_security_alert` | `alert_id`, `status`, `classification`, `determination`, `assigned_to` | Triage an alert. Only the fields that you give change. Returns the updated alert. | +| `add_security_alert_comment` | `alert_id`, `comment` | Append a comment, for example to record the automated response. Returns the full comment list of the alert. | +| `list_security_incidents` | `filter`, `top`, `next_link`, `extra_query` | List XDR incidents. Add `extra_query: {"$expand": "alerts"}` to embed the alerts of each incident. | +| `get_security_incident` | `incident_id` | One incident (numeric-string id, for example `"29"`). | | `update_security_incident` | `incident_id`, `status` (`active`/`resolved`/`redirected`), `classification`, `determination`, `assigned_to`, `resolving_comment`, `custom_tags` | Triage an incident. `custom_tags` **replaces** the tag list (an explicit empty list clears it). | -| `run_hunting_query` | `query`, `timespan` | Run a KQL query against the XDR advanced-hunting tables. Returns `{schema, results}`. Default lookback 30 days; max 100,000 rows. | +| `run_hunting_query` | `query`, `timespan` | Run a KQL query against the XDR advanced-hunting tables. Returns `{schema, results}`. The default lookback is 30 days, and the maximum is 100,000 rows. | ### Group containment | Action | Parameters | What it does | | --- | --- | --- | -| `add_group_member` | `group_id`, `user_id` | Add a user to a group — e.g. drop a compromised user into a Conditional-Access block/quarantine group. | -| `remove_group_member` | `group_id`, `user_id` | Remove a user from a group — e.g. strip a compromised user out of a privileged group. | +| `add_group_member` | `group_id`, `user_id` | Add a user to a group, for example to put a compromised user into a Conditional-Access block or quarantine group. | +| `remove_group_member` | `group_id`, `user_id` | Remove a user from a group, for example to take a compromised user out of a privileged group. | ### Intune devices @@ -177,7 +177,7 @@ Cross-product alerts and incidents from Defender for Endpoint / Office 365 / Ide | `list_managed_devices` | common list params | List Intune-managed devices (`deviceName`, `complianceState`, `userPrincipalName`, …). | | `get_managed_device` | `device_id`, `select` | Get one managed device (`osVersion`, `isEncrypted`, `lastSyncDateTime`, `azureADDeviceId`, …). | | `wipe_device` | `device_id`, `keep_enrollment_data`, `keep_user_data`, `data` | Factory-reset a device. **Destructive.** | -| `retire_device` | `device_id` | Remove company data and MDM policies, leave personal data. | +| `retire_device` | `device_id` | Remove the company data and the MDM policies. The personal data stays. | | `remote_lock_device` | `device_id` | Remote-lock the device. | | `reset_device_passcode` | `device_id` | Reset the device passcode. | | `reboot_device` | `device_id` | Immediate reboot. | @@ -186,40 +186,40 @@ Cross-product alerts and incidents from Defender for Endpoint / Office 365 / Ide ### Defender for Endpoint investigation -Read-side actions against the Defender for Endpoint API. Enum values here are **PascalCase** (`New`, `InProgress`, `Resolved`) — unlike the Graph security API above. +Read-side actions against the Defender for Endpoint API. The enum values here are **PascalCase** (`New`, `InProgress`, `Resolved`). The Graph security API above uses a different form. | Action | Parameters | What it does | | --- | --- | --- | | `get_machine` | `machine_id` | One machine (`computerDnsName`, `lastIpAddress`, `lastExternalIpAddress`, `healthStatus`, `riskScore`, `exposureLevel`, `machineTags`). | | `find_machines_by_ip` | `ip`, `timestamp` (default now) | Machines seen with an **internal** IP within ±15 minutes of the timestamp (last 30 days only). | -| `list_alerts` | `filter`, `top`, `next_link`, `extra_query` | List Defender for Endpoint alerts. Filterable on `alertCreationTime`, `status`, `severity`, `category`, `detectionSource`, `machineId`. Add `extra_query: {"$expand": "evidence"}` to embed evidence. | +| `list_alerts` | `filter`, `top`, `next_link`, `extra_query` | List Defender for Endpoint alerts. You can filter on `alertCreationTime`, `status`, `severity`, `category`, `detectionSource`, and `machineId`. Add `extra_query: {"$expand": "evidence"}` to embed evidence. | | `get_alert` | `alert_id` | One alert (`title`, `severity`, `status`, `machineId`, `relatedUser`, `comments`, `mitreTechniques`). | -| `update_alert` | `alert_id`, `status`, `classification`, `determination`, `assigned_to`, `comment` | Triage an alert and/or add a comment; only provided fields change. | +| `update_alert` | `alert_id`, `status`, `classification`, `determination`, `assigned_to`, `comment` | Triage an alert, add a comment, or do both. Only the fields that you give change. | | `list_machine_alerts` | `machine_id` | All alerts related to one machine. | -| `list_machine_logon_users` | `machine_id` | Users Defender saw log on to the machine (`accountName`, `firstSeen`/`lastSeen`, `logonTypes`, `isDomainAdmin`) — who else may be compromised. | -| `get_file_info` | `file_hash` (SHA1 or SHA256) | Defender's file profile: `globalPrevalence`, `signer`/`issuer`, `isValidCertificate`, `determinationType`/`determinationValue`. | -| `list_file_machines` | `sha1` | Machines a file was observed on — scope how far it spread. **SHA1 only**; unknown hash returns an empty list. | +| `list_machine_logon_users` | `machine_id` | The users that Defender saw log on to the machine (`accountName`, `firstSeen`/`lastSeen`, `logonTypes`, `isDomainAdmin`). Use it to find who else can be compromised. | +| `get_file_info` | `file_hash` (SHA1 or SHA256) | The file profile from Defender: `globalPrevalence`, `signer`/`issuer`, `isValidCertificate`, `determinationType`/`determinationValue`. | +| `list_file_machines` | `sha1` | The machines where a file was seen. Use it to find how far the file spread. **SHA1 only**; an unknown hash returns an empty list. | | `list_file_alerts` | `sha1` | Alerts related to a file. **SHA1 only**. | -| `run_advanced_query` | `query` | Run a KQL query against the Defender for Endpoint hunting tables. Returns `{Schema, Results}`. 30-day window, max 100,000 rows. For cross-product tables prefer `run_hunting_query`. | -| `list_indicators` | `filter`, `top`, `next_link`, `extra_query` | The tenant's custom indicators (IoCs); use a returned `id` with `delete_indicator`. | +| `run_advanced_query` | `query` | Run a KQL query against the Defender for Endpoint hunting tables. Returns `{Schema, Results}`. The window is 30 days, and the maximum is 100,000 rows. For cross-product tables, use `run_hunting_query`. | +| `list_indicators` | `filter`, `top`, `next_link`, `extra_query` | The custom indicators (IoCs) of the tenant. Use a returned `id` with `delete_indicator`. | ### Defender for Endpoint machines -Machine actions are **asynchronous**: they return a `machineAction` object with `status: Pending`, and the work completes in the background. Poll with `get_machine_action` until `Succeeded` / `Failed`. All take an optional `comment` recorded in the Defender action audit (default `Automated response via LimaCharlie`) and an optional `data` object merged into the payload. +Machine actions are **asynchronous**. They return a `machineAction` object with `status: Pending`, and the work completes in the background. Poll with `get_machine_action` until the status is `Succeeded` or `Failed`. Each action takes an optional `comment` that goes into the Defender action audit; the default is `Automated response via LimaCharlie`. Each action also takes an optional `data` object that is merged into the payload. | Action | Parameters | What it does | | --- | --- | --- | | `list_machines` | common list params | List Defender machines (`computerDnsName`, `riskScore`, `exposureLevel`, …). | -| `isolate_machine` | `machine_id`, `isolation_type` (`Full` default, or `Selective`) | Network-isolate a machine. `Selective` keeps Teams/Outlook working. | +| `isolate_machine` | `machine_id`, `isolation_type` (`Full` default, or `Selective`) | Isolate a machine from the network. `Selective` keeps Teams and Outlook operational. | | `unisolate_machine` | `machine_id` | Release from isolation. | | `run_antivirus_scan` | `machine_id`, `scan_type` (`Quick` default, or `Full`) | Trigger a Defender AV scan. | -| `restrict_app_execution` | `machine_id` | Only Microsoft-signed binaries may run. | +| `restrict_app_execution` | `machine_id` | Let only Microsoft-signed binaries run. | | `unrestrict_app_execution` | `machine_id` | Remove the execution restriction. | | `collect_investigation_package` | `machine_id` | Collect a forensics package. | -| `stop_and_quarantine_file` | `machine_id`, `sha1` | Stop running instances of a file (by SHA-1) and quarantine it. | -| `list_machine_actions` | common list params | The response-action audit/queue. | -| `get_machine_action` | `action_id` | Poll one machine action's status (`Pending` / `InProgress` / `Succeeded` / `Failed`). | -| `get_investigation_package_uri` | `action_id` | Short-lived SAS download URL for a **succeeded** `collect_investigation_package` action. A `404` usually means the collection hasn't finished. Rate-limited to 2 calls/minute. | +| `stop_and_quarantine_file` | `machine_id`, `sha1` | Stop the running instances of a file (by SHA-1) and quarantine it. | +| `list_machine_actions` | common list params | The audit and queue of response actions. | +| `get_machine_action` | `action_id` | Poll the status of one machine action (`Pending` / `InProgress` / `Succeeded` / `Failed`). | +| `get_investigation_package_uri` | `action_id` | Short-lived SAS download URL for a **succeeded** `collect_investigation_package` action. A `404` usually means that the collection is not complete. The rate limit is 2 calls for each minute. | ### Custom indicators @@ -238,15 +238,15 @@ Create a Defender custom threat indicator to block or alert on an IoC across the | `expiration_time` | string | ISO-8601 UTC expiry; omit for no expiry. | | `recommended_actions` | string | Recommended-actions text shown with the alert. | | `generate_alert` | bool | Generate an alert on match. **Required `true` when `action` is `Audit`.** | -| `data` | object | Extra fields merged into the payload (e.g. `rbacGroupNames`). | +| `data` | object | Extra fields merged into the payload, for example `rbacGroupNames`. | #### `delete_indicator` -Delete one custom indicator by its `indicator_id` (from `list_indicators` or the `create_indicator` response) — e.g. to lift a block. +Delete one custom indicator by its `indicator_id`, for example to remove a block. The `indicator_id` comes from `list_indicators` or from the `create_indicator` response. ## Detection & Response -Example response action that isolates the Defender machine named in a detection: +This example response action isolates the Defender machine that a detection names: ```yaml - action: extension request @@ -259,15 +259,15 @@ Example response action that isolates the Defender machine named in a detection: ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> The values under `extension request` are evaluated as templates. A bare string without `{{ }}` is read as a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the key is dropped from the payload without a message. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context, so a `machineAction` id is not available to a subsequent action in the same rule. Workflows that chain (look up the machine, isolate it, poll the action, collect forensics) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold ids between calls. +`extension request` actions do not return a result. The rule engine does not put the response into the evaluation context of the rule. A `machineAction` id is therefore not available to a later action in the same rule. A workflow that chains steps (look up the machine, isolate it, poll the action, collect forensics) belongs in a [Playbook](../limacharlie/playbook.md) or in an AI agent. A Playbook or an AI agent can hold ids between calls. ## Notes -- Two alert/hunting surfaces are deliberately both exposed: the **Graph security API** actions (`*_security_alert`, `*_security_incident`, `run_hunting_query`) cover all of Defender XDR with camelCase enums, while the **Defender for Endpoint API** actions (`list_alerts`, `get_alert`, `update_alert`, `run_advanced_query`) are endpoint-only with PascalCase enums and machine-centric fields (`machineId`, `computerDnsName`). -- Graph and Defender use **separate token audiences**; the extension caches one token per service and renews it before expiry. A token rejected by the other service surfaces as `403`, not `401`. -- A single `401` is treated as a token-expiry race: the cached token is dropped and the request retried once with a fresh token. Rotating `client_secret` in Secrets Manager recovers the same way — the next auth failure evicts the cached client and re-reads the secret. -- Microsoft Graph throttling (`429`) is **not** retried by the extension; throttled requests surface to the caller. +- The extension gives two surfaces for alerts and hunting on purpose. The **Graph security API** actions (`*_security_alert`, `*_security_incident`, `run_hunting_query`) cover all of Defender XDR and use camelCase enums. The **Defender for Endpoint API** actions (`list_alerts`, `get_alert`, `update_alert`, `run_advanced_query`) cover endpoints only. They use PascalCase enums and machine-centric fields (`machineId`, `computerDnsName`). +- Graph and Defender use **separate token audiences**. The extension caches one token for each service and renews it before it expires. If the other service rejects a token, the result is a `403`, not a `401`. +- One `401` is treated as a race with the token expiry. The cached token is dropped, and the request runs one more time with a new token. A rotation of `client_secret` in Secrets Manager recovers in the same way. The next authentication failure evicts the cached client and reads the secret again. +- The extension does **not** retry Microsoft Graph throttling (`429`). A throttled request goes back to the caller. - Error messages are formatted `microsoft api on : : `, with query strings redacted. -- Unsubscribing from the extension preserves its saved configuration; re-subscribing restores it without reconfiguration. +- If you unsubscribe from the extension, its saved configuration stays. If you subscribe again, the configuration returns and you do not configure it again. diff --git a/docs/5-integrations/extensions/third-party/nims.md b/docs/5-integrations/extensions/third-party/nims.md index ec3a3d6e4..06bd55f70 100644 --- a/docs/5-integrations/extensions/third-party/nims.md +++ b/docs/5-integrations/extensions/third-party/nims.md @@ -1,18 +1,20 @@ # NIMS -Notion Incident Management System (NIMS) helps SOC/IR teams streamline their incident collaboration. While not a replacement for advanced SIEM or SOAR case management systems, it offers a practical alternative for teams that don't have access to these tools. +Notion Incident Management System (NIMS) helps SOC and IR teams collaborate on incidents. It is not a replacement for an advanced SIEM or a SOAR case management system. It is an alternative for teams that do not have these tools. -The Notion template uses interconnected relational databases to enable effective incident tracking and case management. +The Notion template uses connected relational databases to track incidents and manage cases. -The LimaCharlie NIMS extension allows you to send detections from LimaCharlie to NIMS via the Notion API. +The LimaCharlie NIMS extension lets you send detections from LimaCharlie to NIMS through the Notion API. -Once you subscribe an org to the extension, it creates a D&R rule that sends all detections from your org to your NIMS alert database. Because Notion databases do have a limit on the number of records, the extension also has the ability to purge old alerts that are 1) not associated with any incidents, and 2) older than the specified number of days. A D&R rule is also created to perform this cleanup automatically (or not) based on your configuration. +After you subscribe an org to the extension, it creates a D&R rule. The rule sends all detections from your org to your NIMS alert database. -[More information about NIMS, including the template and corresponding docs](https://nims-template.notion.site/), is available on the project's Notion page. +A Notion database has a limit on the number of records. The extension can therefore purge old alerts. It purges an alert that has no link to an incident and is older than the number of days that you specify. The extension also creates a D&R rule for this cleanup. Your configuration controls if the cleanup runs automatically. + +The [NIMS project page on Notion](https://nims-template.notion.site/) gives more information, including the template and its documentation. ## Configuration -In order to use this extension, you will need 3 pieces of data: +To use this extension, you need 3 pieces of data: - Notion authentication token - NIMS Alert database ID @@ -20,43 +22,43 @@ In order to use this extension, you will need 3 pieces of data: ### Find your database IDs -1. Navigate to the Alert database within NIMS under `Databases` +1. Go to the Alert database in NIMS under `Databases` 2. Right click on the database and click `Copy link`[![NIMS database link button screenshot](https://github.com/shortstack/nims-webhook/raw/main/screenshots/link.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/link.png) -3. Locate the database ID in the URL +3. Find the database ID in the URL - - The database ID is the long string of letters and numbers in the URL after the last `/` and before the `?` or `#` if present - - Example: + - The database ID is the long string of letters and numbers in the URL. It comes after the last `/`, and before the `?` or the `#` if one is present + - Example: - - Link: `https://www.notion.so/184cdc5a1ef3710badc2d2b1271aeb81?v=174cdc3a1ef181719981000cab12bf54&pvs=4` - - ID: `184cdc5a1ef3710badc2d2b1271aeb81` + - Link: `https://www.notion.so/184cdc5a1ef3710badc2d2b1271aeb81?v=174cdc3a1ef181719981000cab12bf54&pvs=4` + - ID: `184cdc5a1ef3710badc2d2b1271aeb81` 4. Copy the ID -5. Repeat the above for the Asset database +5. Repeat the steps above for the Asset database ### Generate an auth token -This will walk you through creating a Notion integration, getting the auth token, and adding the integration to the proper NIMS databases. +These steps create a Notion integration, get the auth token, and add the integration to the correct NIMS databases. -While completing the following steps, be sure to add the connection to all 3 databases—Alert, Asset, and Incident. Incident is only necessary in order to perform the alerts cleanup to see whether or not the alert is tied to an incident. +In the steps below, add the connection to all 3 databases: Alert, Asset, and Incident. The Incident database is necessary only for the cleanup of alerts, which checks if an alert has a link to an incident. 1. Go to `Manage connections` in Notion [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/connection.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/connection.png) 2. Click `Develop or manage integrations`[![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/manage.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/manage.png) 3. Click `New integration`[![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/new.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/new.png) 4. Configure the new integration - - Give it a name, ex: `nims_template` - - Choose the workspace - - Type: `Internal` - - Click `Save` [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/integration.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/integration.png) + - Give it a name, for example `nims_template` + - Choose the workspace + - Type: `Internal` + - Click `Save` [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/integration.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/integration.png) 5. Click `Configure integration settings` [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/configure.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/configure.png) -6. Copy the `Internal Integration Secret`-- this is your auth token +6. Copy the `Internal Integration Secret`. This is your auth token - - Click `Save` [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/token.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/token.png) -7. Navigate to your `Alert Database` + - Click `Save` [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/token.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/token.png) +7. Go to your `Alert Database` - - Click the 3-dot menu and find `Connections` - - Click on your newly created integration [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/alerts.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/alerts.png) + - Click the 3-dot menu and find `Connections` + - Click the integration that you created [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/alerts.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/alerts.png) 8. Click `Confirm` - [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/confirm.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/confirm.png) + [![connection](https://github.com/shortstack/nims-webhook/raw/main/screenshots/confirm.png)](https://github.com/shortstack/nims-webhook/blob/main/screenshots/confirm.png) 9. Repeat steps 7 and 8 for the `Asset Database` and the `Incident Database` ## Example D&R rule diff --git a/docs/5-integrations/extensions/third-party/okta.md b/docs/5-integrations/extensions/third-party/okta.md index 122d84524..a0fb30d0d 100644 --- a/docs/5-integrations/extensions/third-party/okta.md +++ b/docs/5-integrations/extensions/third-party/okta.md @@ -1,30 +1,30 @@ # Okta -The Okta LimaCharlie Extension exposes the incident-response and investigation surface of an Okta org (the **Okta management API**) to D&R rules and AI agents. It enables automated investigation and containment of an Okta account compromise directly from detections — suspend a user, reset their MFA, kill their sessions **and** OAuth tokens, revoke their app grants, quarantine them into a group, and pull the System Log for triage. +The Okta LimaCharlie Extension gives D&R rules and AI agents access to the **Okta management API**. This API contains the incident-response and investigation functions of an Okta org. A detection can start an automated investigation or containment of a compromised Okta account. The extension can suspend a user, reset the MFA of the user, and stop the sessions **and** the OAuth tokens of the user. It can also revoke app grants, move the user into a quarantine group, and read the System Log for triage. -The extension provides two layers: +The extension has two layers: -- **Typed actions** for the common containment, credential, MFA, session, and triage workflows, with friendly parameter names and built-in safety rails. -- A generic **`api_call`** passthrough for any Okta management endpoint not covered by a typed action. +- **Typed actions** for the usual workflows for containment, credentials, MFA, sessions, and triage. These actions have clear parameter names and built-in safety controls. +- A generic **`api_call`** passthrough for an Okta management endpoint that no typed action covers. -Authentication is either a user-owned **SSWS API token** or an **OAuth 2.0 "API Services" app** (client credentials) — no user interaction, no delegated tokens. Okta's **DPoP** (sender-constrained token) requirement is handled transparently. +For authentication, use a user-owned **SSWS API token** or an **OAuth 2.0 "API Services" app** (client credentials). Neither mode needs user interaction or delegated tokens. The extension obeys the **DPoP** (sender-constrained token) requirement of Okta automatically. ## Setup -Pick **one** authentication mode. +Select **one** authentication mode. ### Option A — SSWS API token (simplest) -1. In the Okta Admin Console, go to **Security → API → Tokens → Create Token** and copy the token value (shown only once). -2. Create the token from a **dedicated service admin account**, not a person's account: an SSWS token inherits the creator's privilege level, and it is revoked after 30 days of inactivity or if the creating account is deactivated. +1. In the Okta Admin Console, go to **Security → API → Tokens → Create Token**. Copy the token value. Okta shows the value one time only. +2. Create the token from a **dedicated service admin account**, not from the account of a person. An SSWS token gets the privilege level of the account that creates it. Okta revokes the token after 30 days of no activity, or if the account that created it is deactivated. ### Option B — OAuth API Services app (recommended) 1. In the Admin Console, go to **Applications → Create App Integration → API Services**. -2. On the app's **General** tab, switch client authentication to **Public key / Private key** and generate (or add) a key. Save the private key — a PEM or the private JWK Okta hands out. -3. On the app's **Okta API Scopes** tab, grant the `okta.*` scopes for the actions you will use (least-privilege set below), then admin-consent them. +2. On the **General** tab of the app, set client authentication to **Public key / Private key**. Generate a key or add one. Save the private key. The key is a PEM or the private JWK that Okta supplies. +3. On the **Okta API Scopes** tab of the app, grant the `okta.*` scopes for the actions that you use. The table below shows the least-privilege set. Then give admin consent to the scopes. -> **Okta requires `private_key_jwt` for management scopes.** The org authorization server rejects a plain `client_id` + `client_secret` for `okta.*` scopes — use a private key. (A `client_secret` field is accepted by the extension for completeness but expect Okta to reject it for these scopes.) New API Services apps also have **DPoP** locked on; the extension detects and satisfies this automatically. +> **Okta needs `private_key_jwt` for management scopes.** The org authorization server rejects a plain `client_id` with a `client_secret` for `okta.*` scopes. Use a private key. The extension accepts a `client_secret` field, but Okta rejects it for these scopes. New API Services apps also have **DPoP** always enabled. The extension detects this and obeys it automatically. Least-privilege scopes: @@ -37,7 +37,7 @@ Least-privilege scopes: | Group membership changes | `okta.groups.manage` | | System Log | `okta.logs.read` | -> The org authorization server **silently drops** requested-but-ungranted scopes from the minted token; a missing grant then surfaces as that endpoint returning **403** (`insufficient_scope`), not a mint failure. Grant only what you use — every action degrades independently. +> If you request a scope that is not granted, the org authorization server **removes it without a message** from the minted token. The mint does not fail. Instead, the endpoint returns **403** (`insufficient_scope`). Grant only the scopes that you use. Each action fails independently of the other actions. ### Subscribe to the extension @@ -45,33 +45,33 @@ Subscribe to `ext-okta` from the LimaCharlie **Marketplace** (Extensions → Add ### Store the secret -In **Secrets Manager**, create a secret (for example `okta-api-token` or `okta-private-key`) and paste the SSWS token or the private key as its value. +In **Secrets Manager**, create a secret, for example `okta-api-token` or `okta-private-key`. Set its value to the SSWS token or to the private key. ### Configure the extension -In **Extensions → ext-okta → Configuration**, fill in `org_url` plus the fields for your chosen auth mode: +In **Extensions → ext-okta → Configuration**, complete `org_url` and the fields for your authentication mode: | Field | Required | Value | | --- | --- | --- | -| `org_url` | yes | Okta org URL or host, e.g. `https://acme.okta.com` (admin / `-admin` URLs are normalized). | -| `api_token` | Option A | Reference to the SSWS-token secret, e.g. `hive://secret/okta-api-token`. | -| `client_id` | Option B | The API Services app client ID. | -| `private_key` | Option B | Reference to the private-key secret (PEM or private RSA JWK), e.g. `hive://secret/okta-private-key`. | -| `key_id` | no | `kid` for a PEM private key (JWKs carry their own). | -| `client_secret` | no | App client secret (alternative to `private_key`; rejected by Okta for management scopes). | -| `scopes` | no | OAuth scope override; empty uses an IR-oriented default set. | +| `org_url` | yes | Okta org URL or host, for example `https://acme.okta.com`. The extension normalizes admin and `-admin` URLs. | +| `api_token` | Option A | Reference to the secret that holds the SSWS token, for example `hive://secret/okta-api-token`. | +| `client_id` | Option B | The client ID of the API Services app. | +| `private_key` | Option B | Reference to the secret that holds the private key (PEM or private RSA JWK), for example `hive://secret/okta-private-key`. | +| `key_id` | no | The `kid` for a PEM private key. A JWK carries its own. | +| `client_secret` | no | Client secret of the app, as an alternative to `private_key`. Okta rejects it for management scopes. | +| `scopes` | no | Override for the OAuth scopes. If empty, the extension uses a default set for incident response. | -Provide `api_token` **or** the OAuth fields, not both. +Give `api_token` **or** the OAuth fields, not both. ## Actions -Every action that targets an entity requires an explicit selector (`user_id`, `group_id` + `user_id`, `factor_id`) — the extension refuses to run without one, preventing accidental org-wide containment. +Every action that targets an entity needs an explicit selector: `user_id`, `group_id` with `user_id`, or `factor_id`. The extension does not run without a selector. This stops accidental containment of the full org. -`user_id` accepts either the Okta user id (e.g. `00u1a2b3c4...`) or the user's login (e.g. `alex@acme.com`). +`user_id` accepts the Okta user id, for example `00u1a2b3c4...`, or the login of the user, for example `alex@acme.com`. ### Pagination -Okta paginates with the HTTP `Link` header (`rel="next"`), not a body cursor. The `list_*` actions return `{data: [...], pagination: {next_link}}`; pass the opaque `next_link` back as the `next_link` parameter to fetch the next page (it is an absolute, self-contained URL — never hand-build it). `limit` is clamped to 200 for users/groups and 1000 for the System Log. +Okta paginates with the HTTP `Link` header (`rel="next"`), not with a cursor in the body. The `list_*` actions return `{data: [...], pagination: {next_link}}`. To get the next page, send the opaque `next_link` value back as the `next_link` parameter. The value is an absolute, self-contained URL. Do not build it yourself. The extension clamps `limit` to 200 for users and groups, and to 1000 for the System Log. ### Generic @@ -82,74 +82,81 @@ Generic passthrough to the Okta management API. | Field | Type | Notes | | --- | --- | --- | | `method` | enum | `GET` (default), `POST`, `PUT`, `DELETE`. | -| `path` | string | **Required.** Path relative to the org base (e.g. `api/v1/users/{id}/lifecycle/reactivate`) or a full `Link: rel="next"` URL. | +| `path` | string | **Required.** Path relative to the org base, for example `api/v1/users/{id}/lifecycle/reactivate`, or a full `Link: rel="next"` URL. | | `query` | object | Query-string parameters. | -| `headers` | object | Extra request headers. | -| `body` | object | JSON body for `POST`/`PUT`. | +| `headers` | object | More request headers. | +| `body` | object | JSON body for `POST` and `PUT`. | ### User investigation | Action | Parameters | What it does | | --- | --- | --- | -| `list_users` | `q`, `search`, `filter`, `sort_by`, `sort_order`, `limit`, `after`, `next_link`, `extra_query` | List/search users. Use `q` for a starts-with search on name/email, `search` for an expression (e.g. `status eq "ACTIVE"` or `profile.email eq "a@b.com"`), or `filter` for the older syntax. | -| `get_user` | `user_id` | Get one user. Read the returned `status` before a lifecycle action (see below). | -| `list_user_factors` | `user_id` + pagination | List a user's enrolled MFA factors (`id`, `factorType`, `status`) — spot attacker-registered MFA. | -| `list_user_groups` | `user_id` + pagination | List a user's group memberships (find a privileged group to strip, or confirm quarantine). | -| `list_user_grants` | `user_id` + pagination | List a user's OAuth consent grants (which apps/scopes they authorized). | -| `list_user_roles` | `user_id` + pagination | List a user's admin roles — is the account privileged (e.g. `SUPER_ADMIN`)? | -| `list_groups` | `q`, `search`, `filter`, `limit`, `after`, `next_link`, `extra_query` | List/search groups. Only `OKTA_GROUP`-type groups accept membership changes. | -| `list_system_log` | `since`, `until`, `filter`, `q`, `sort_order`, `limit`, `next_link`, `extra_query` | Query the System Log (`/api/v1/logs`). Scope with `since`/`until` (ISO-8601) and a SCIM `filter`, e.g. `eventType eq "user.session.start"`, `actor.id eq "00u..."`, or `target.id eq "00u..."`. | +| `list_users` | `q`, `search`, `filter`, `sort_by`, `sort_order`, `limit`, `after`, `next_link`, `extra_query` | List or search users. Use `q` for a starts-with search on the name or the email. Use `search` for an expression, for example `status eq "ACTIVE"` or `profile.email eq "a@b.com"`. Use `filter` for the older syntax. | +| `get_user` | `user_id` | Get one user. Read the `status` in the result before a lifecycle action (see below). | +| `list_user_factors` | `user_id` + pagination | List the enrolled MFA factors of a user (`id`, `factorType`, `status`). Use it to find MFA that an attacker registered. | +| `list_user_groups` | `user_id` + pagination | List the group memberships of a user. Use it to find a privileged group to remove, or to confirm a quarantine. | +| `list_user_grants` | `user_id` + pagination | List the OAuth consent grants of a user, which show the apps and the scopes that the user authorized. | +| `list_user_roles` | `user_id` + pagination | List the admin roles of a user. Use it to see if the account is privileged, for example `SUPER_ADMIN`. | +| `list_groups` | `q`, `search`, `filter`, `limit`, `after`, `next_link`, `extra_query` | List or search groups. Only groups of type `OKTA_GROUP` accept membership changes. | +| `list_system_log` | `since`, `until`, `filter`, `q`, `sort_order`, `limit`, `next_link`, `extra_query` | Query the System Log (`/api/v1/logs`). Limit the scope with `since` and `until` (ISO-8601) and with a SCIM `filter`, for example `eventType eq "user.session.start"`, `actor.id eq "00u..."`, or `target.id eq "00u..."`. | -Read the user's `status` first: `suspend` needs `ACTIVE`, `unsuspend` needs `SUSPENDED`, `activate` needs `STAGED`/`DEPROVISIONED`, `unlock` needs `LOCKED_OUT`. A `400` on a lifecycle action is a state mismatch; a `403` is a scope/role problem. +Read the `status` of the user first. `suspend` needs `ACTIVE`, `unsuspend` needs `SUSPENDED`, `activate` needs `STAGED` or `DEPROVISIONED`, and `unlock` needs `LOCKED_OUT`. A `400` from a lifecycle action shows a state mismatch. A `403` shows a problem with a scope or with a role. ### User lifecycle | Action | Parameters | What it does | | --- | --- | --- | -| `suspend_user` | `user_id` | Block sign-in while preserving the account and assignments — the recommended **reversible** containment lever. Reverse with `unsuspend_user`. | +| `suspend_user` | `user_id` | Block sign-in but keep the account and its assignments. This is the recommended **reversible** containment action. To reverse it, use `unsuspend_user`. | | `unsuspend_user` | `user_id` | Return a suspended user to `ACTIVE`. | -| `deactivate_user` | `user_id`, `send_email` (default `false`) | Deactivate/deprovision the user. **Destructive** — removes app access and is not a clean inverse of `activate`; prefer `suspend_user`. May complete asynchronously on large orgs. | -| `activate_user` | `user_id`, `send_email` (default `false`) | Activate a `STAGED`/`DEPROVISIONED` user. With `send_email=false` the response includes an activation URL/token. | -| `unlock_user` | `user_id` | Unlock a `LOCKED_OUT` user, returning them to `ACTIVE`. | +| `deactivate_user` | `user_id`, `send_email` (default `false`) | Deactivate or deprovision the user. This action is **destructive**. It removes app access, and it is not a clean inverse of `activate`. Use `suspend_user` instead. On a large org, the action can complete asynchronously. | +| `activate_user` | `user_id`, `send_email` (default `false`) | Activate a user that is `STAGED` or `DEPROVISIONED`. With `send_email=false`, the response includes an activation URL and token. | +| `unlock_user` | `user_id` | Unlock a `LOCKED_OUT` user and return the user to `ACTIVE`. | ### Credentials | Action | Parameters | What it does | | --- | --- | --- | -| `expire_password` | `user_id`, `temp_password` (default `false`) | Force a password change at next sign-in (`PASSWORD_EXPIRED`). With `temp_password=true` the current password is invalidated immediately and a one-time temp password is returned. | -| `reset_password` | `user_id`, `send_email` (default `false`) | Trigger a reset (transitions the user to `RECOVERY`). With `send_email=false` the response carries a one-time `resetPasswordUrl` to deliver out-of-band. | -| `set_user_password` | `user_id`, `password` | Set a specific new password directly — lock an attacker out with a known-only-to-you value. Must satisfy the org password policy. | +| `expire_password` | `user_id`, `temp_password` (default `false`) | Force a password change at the next sign-in (`PASSWORD_EXPIRED`). With `temp_password=true`, Okta invalidates the current password immediately and returns a one-time temporary password. | +| `reset_password` | `user_id`, `send_email` (default `false`) | Start a reset. The user moves to `RECOVERY`. With `send_email=false`, the response carries a one-time `resetPasswordUrl` to deliver out-of-band. | +| `set_user_password` | `user_id`, `password` | Set a specific new password directly. Use it to lock out an attacker with a value that only you know. The password must obey the password policy of the org. | ### MFA | Action | Parameters | What it does | | --- | --- | --- | -| `reset_user_factors` | `user_id`, `remove_recovery_enrollment` (default `false`) | Unenroll **all** of a user's MFA factors, forcing re-enrollment — high-value against attacker-registered MFA. Does not change the password. | -| `reset_user_factor` | `user_id`, `factor_id`, `remove_recovery_enrollment` (default `false`) | Unenroll a **single** factor (from `list_user_factors`). Note: removing a push/signed-nonce factor also removes the user's related Okta Verify factors. | +| `reset_user_factors` | `user_id`, `remove_recovery_enrollment` (default `false`) | Unenroll **all** MFA factors of a user and force re-enrollment. This has high value against MFA that an attacker registered. It does not change the password. | +| `reset_user_factor` | `user_id`, `factor_id`, `remove_recovery_enrollment` (default `false`) | Unenroll a **single** factor, from `list_user_factors`. If you remove a push factor or a signed-nonce factor, Okta also removes the related Okta Verify factors of the user. | ### Sessions & OAuth tokens | Action | Parameters | What it does | | --- | --- | --- | -| `clear_user_sessions` | `user_id`, `oauth_tokens` (default `true`), `forget_devices` (default `false`) | Revoke all of a user's Okta sessions, forcing re-authentication. `oauth_tokens` defaults to **`true`** (the IR-safe choice) so refresh/access tokens are revoked too — Okta's own API default of `false` leaves them valid, the single most common containment mistake. `forget_devices` also clears remembered-device / factor-trust. | -| `revoke_user_grants` | `user_id` | Revoke **all** of a user's OAuth consent grants across all clients — cut off OAuth-based persistence. Inspect first with `list_user_grants`. | +| `clear_user_sessions` | `user_id`, `oauth_tokens` (default `true`), `forget_devices` (default `false`) | Revoke all Okta sessions of a user and force re-authentication. `oauth_tokens` defaults to **`true`**, which is the safe choice for incident response, so Okta also revokes the refresh tokens and the access tokens. The Okta API default of `false` keeps those tokens valid, and this is the most common containment mistake. `forget_devices` also clears remembered devices and factor trust. | +| `revoke_user_grants` | `user_id` | Revoke **all** OAuth consent grants of a user, across all clients, and stop OAuth-based persistence. Inspect the grants first with `list_user_grants`. | -> Clearing Okta sessions does **not** terminate sessions already established inside downstream apps (M365, Salesforce, …); those need the app's own session revocation. +> When you clear Okta sessions, the sessions that are already open in downstream apps (M365, Salesforce, and others) do **not** stop. To stop those sessions, use the session revocation of each app. ### Group containment | Action | Parameters | What it does | | --- | --- | --- | -| `add_user_to_group` | `group_id`, `user_id` | Add a user to an `OKTA_GROUP` — e.g. drop a compromised user into a quarantine / high-friction sign-on-policy group. Find the group id with `list_groups`. | -| `remove_user_from_group` | `group_id`, `user_id` | Remove a user from a group — e.g. strip a compromised user out of a privileged/admin group. | +| `add_user_to_group` | `group_id`, `user_id` | Add a user to an `OKTA_GROUP`. For example, move a compromised user into a quarantine group, or into a group with a high-friction sign-on policy. Find the group id with `list_groups`. | +| `remove_user_from_group` | `group_id`, `user_id` | Remove a user from a group. For example, remove a compromised user from a privileged group or an admin group. | ### Containment sequencing -For a confirmed account takeover, the effective combination is: `reset_user_factors` (drop attacker MFA) → `expire_password` with `temp_password=true` **or** `set_user_password` (invalidate the credential) → `clear_user_sessions` (kill live sessions **and** OAuth tokens) → `revoke_user_grants` (cut OAuth persistence). Revoke sessions/tokens **last** so the attacker's live session can't outlive the other steps. Use `suspend_user` as the single reversible lever to stop everything first. +For a confirmed account takeover, use this sequence of actions: + +1. Run `reset_user_factors` to remove the MFA of the attacker. +2. Run `expire_password` with `temp_password=true`, or run `set_user_password`, to invalidate the credential. +3. Run `clear_user_sessions` to stop the live sessions **and** the OAuth tokens. +4. Run `revoke_user_grants` to stop OAuth persistence. + +Revoke the sessions and the tokens **last**. This stops the live session of the attacker from continuing after the other steps. To stop everything first with one reversible action, use `suspend_user`. ## Detection & Response -Example response action that suspends the Okta user named in a detection: +This example response action suspends the Okta user that a detection names: ```yaml - action: extension request @@ -159,16 +166,16 @@ Example response action that suspends the Okta user named in a detection: user_id: '{{ .event/user_id }}' ``` -> **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> **Put literal strings in `{{ "..." }}`.** +> The extension evaluates the values under `extension request` as templates. A bare string without `{{ }}` is a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the extension removes the key from the payload without a message. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context. Workflows that chain (find the user, reset factors, clear sessions, revoke grants) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold state between calls. +`extension request` actions do not return a result. The rule engine does not put the response into the evaluation context of the rule. Use a [Playbook](../limacharlie/playbook.md) or an AI agent for a chain of actions, such as find the user, reset the factors, clear the sessions, and revoke the grants. A Playbook or an AI agent keeps state between calls. ## Notes -- **Two auth modes.** SSWS is the fastest to set up but is tied to an admin account's privilege and dies after 30 days of inactivity. The OAuth API Services app (private_key_jwt) is decoupled from any person, uses short-lived scoped tokens, and is the direction Okta officially steers integrations. -- **DPoP** (sender-constrained tokens) is forced on for new API Services apps; the extension mints a plain token first and, if Okta answers `invalid_dpop_proof`, transparently flips to DPoP for the token request and every API call. -- A single `401` on a call using an OAuth token is treated as a token-expiry race: the cached token is dropped and the request retried once with a fresh token. Rotating the secret in Secrets Manager recovers the same way — the next auth failure evicts the cached client and re-reads the secret. -- Token-endpoint `429`/`5xx` are backed off and retried; a data-endpoint `429` honors Okta's `Retry-After` for a bounded number of retries. -- Error messages are formatted `okta api on : : `, with query strings redacted. -- Unsubscribing from the extension preserves its saved configuration; re-subscribing restores it without reconfiguration. +- **Two authentication modes.** SSWS is the fastest to set up, but it uses the privilege of an admin account and it stops after 30 days of no activity. The OAuth API Services app (private_key_jwt) is separate from any person and uses short-lived scoped tokens. Okta officially moves integrations to this mode. +- **DPoP** (sender-constrained tokens) is always enabled for new API Services apps. The extension mints a plain token first. If Okta answers `invalid_dpop_proof`, the extension changes to DPoP for the token request and for every API call. +- If one call with an OAuth token returns `401`, the extension treats it as an expired token. It drops the cached token and tries the request one more time with a new token. If you rotate the secret in Secrets Manager, the recovery is the same. The next authentication failure removes the cached client and reads the secret again. +- The extension backs off and retries a `429` or a `5xx` from the token endpoint. For a `429` from a data endpoint, it obeys the `Retry-After` value of Okta for a limited number of retries. +- The extension formats error messages as `okta api on : : `, and it redacts query strings. +- If you unsubscribe from the extension, its saved configuration stays. If you subscribe again, the extension restores the configuration and you do not configure it again. diff --git a/docs/5-integrations/extensions/third-party/otx.md b/docs/5-integrations/extensions/third-party/otx.md index fdcac7ece..226729f30 100644 --- a/docs/5-integrations/extensions/third-party/otx.md +++ b/docs/5-integrations/extensions/third-party/otx.md @@ -1,22 +1,24 @@ # OTX -AlienVault's Open Threat Exchange (OTX) is the "neighborhood watch of the global intelligence community." It enables private companies, independent security researchers, and government agencies to openly collaborate and share the latest information about emerging threats, attack methods, and malicious actors, promoting greater security across the entire community. +AlienVault's Open Threat Exchange (OTX) is the "neighborhood watch of the global intelligence community." Private companies, independent security researchers, and government agencies use OTX to collaborate openly. They share the latest information about new threats, attack methods, and malicious actors. This gives more security to the full community. [More information about OTX](https://otx.alienvault.com/) is available on the AlienVault site. ## Enabling the OTX Extension -Before utilizing the OTX extension, you will need an AlienVault OTX API Key from your [AlienVault OTX account](https://otx.alienvault.com/). +Before you use the OTX extension, you need an AlienVault OTX API Key from your [AlienVault OTX account](https://otx.alienvault.com/). -To enable the OTX extension, navigate to the [OTX extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-otx). Select the Organization you wish to enable the extension for, and select **Subscribe**. +1. Go to the [OTX extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-otx). +2. Select the organization to enable the extension for. +3. Select **Subscribe**. +4. After the extension is enabled, go to Extensions > OTX. +5. Give your OTX API Key. Enter the key in the form, or use the LimaCharlie [Secrets Manager](../../../7-administration/config-hive/secrets.md). -Once the extension is enabled, navigate to Extensions > OTX. You will need to provide your OTX API Key, which can be done directly in the form or via LimaCharlie's [Secrets Manager](../../../7-administration/config-hive/secrets.md). - -Pulses will be synced to rules and lookups automatically every 3 hours. +The extension syncs pulses to rules and lookups automatically every 3 hours. ## Using the OTX Extension -After providing a valid API key, the Extension will automatically create [Detection & Response rules](https://doc.limacharlie.io/docs/detection-and-response) for your organization. The OTX rules make use of the following events: +After you give a valid API key, the extension automatically creates [Detection & Response rules](https://doc.limacharlie.io/docs/detection-and-response) for your organization. The OTX rules use these events: - Process Events - [CODE_IDENTITY](../../../8-reference/edr-events.md#code_identity) @@ -32,4 +34,4 @@ After providing a valid API key, the Extension will automatically create [Detect - [NEW_UDP4_CONNECTION](../../../8-reference/edr-events.md#new_udp4_connection) - [NEW_UDP6_CONNECTION](../../../8-reference/edr-events.md#new_udp6_connection) -Please ensure that the events you are interested in using with OTX lookups are enabled in the **Sensors >** Event Collection menu. +Make sure that the events that you use with OTX lookups are enabled in the **Sensors >** Event Collection menu. diff --git a/docs/5-integrations/extensions/third-party/pagerduty.md b/docs/5-integrations/extensions/third-party/pagerduty.md index a5fbfdd3c..0b5446764 100644 --- a/docs/5-integrations/extensions/third-party/pagerduty.md +++ b/docs/5-integrations/extensions/third-party/pagerduty.md @@ -1,8 +1,8 @@ # PagerDuty -The PagerDuty Extension allows you to trigger events within PagerDuty. It requires you to setup the PagerDuty access token in the Integrations section of your Organization. +The PagerDuty Extension lets you trigger events in PagerDuty. First, set the PagerDuty access token in the Integrations section of your Organization. -See PagerDuty's [Events API v2 trigger reference](https://developer.pagerduty.com/docs/events-api-v2/trigger-events/) for more detail. +For more information, see the PagerDuty [Events API v2 trigger reference](https://developer.pagerduty.com/docs/events-api-v2/trigger-events/). ## REST @@ -21,16 +21,16 @@ See PagerDuty's [Events API v2 trigger reference](https://developer.pagerduty.co ### PagerDuty Configuration -On the PagerDuty side, you need to configure your PagerDuty service to receive the API notifications: +In PagerDuty, configure your PagerDuty service to receive the API notifications: 1. In your Service, go to the "Integrations" tab. 2. Click "Add a new integration". 3. Give it a name, like "LimaCharlie". 4. In the "Integration Type" section, select the radio button "Use our API directly" and select "Events API v2" from the dropdown. 5. Click "Add integration". -6. Back in the "Integrations" page, you should see your new integration in the list. Copy the "Integration Key" to your clipboard and add it in the "Integrations" section of LimaCharlie for PagerDuty. +6. Go back to the "Integrations" page. The new integration is in the list. Copy the "Integration Key". Add the key in the "Integrations" section of LimaCharlie for PagerDuty. -From this point on, you may use a rule to trigger a PagerDuty event. For example the following rule "response": +You can now use a rule to trigger a PagerDuty event. This example shows a rule "response": ```yaml - action: extension request @@ -46,12 +46,12 @@ From this point on, you may use a rule to trigger a PagerDuty event. For example details: '{{ .event }}' ``` -> **Important — wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. That's why every literal above is written as `'{{ "..." }}'`. For required fields (`summary`, `source`, `severity`) this matters most — a dropped key will cause the request to be rejected with `missing one of `. +> **Important — put literal strings in `{{ "..." }}`.** +> The extension evaluates the values under `extension request` as templates. A bare string without `{{ }}` is a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the extension removes the key from the payload without a message. For this reason, each literal above is written as `'{{ "..." }}'`. The required fields (`summary`, `source`, `severity`) are the most important. If one of these keys is removed, PagerDuty rejects the request with `missing one of `. ### Pass-through `parameters` block -For richer PagerDuty incidents you can supply an optional `parameters` block alongside the flat fields. Recognized keys are mapped to their proper place in the [V2 event payload](https://developer.pagerduty.com/docs/events-api-v2/trigger-events/); any key that isn't recognized is merged into `custom_details` so nothing is lost. +To add more detail to a PagerDuty incident, supply an optional `parameters` block with the flat fields. The extension puts each known key in its correct place in the [V2 event payload](https://developer.pagerduty.com/docs/events-api-v2/trigger-events/). It merges each unknown key into `custom_details`, so no data is lost. | Key | Type | Where it goes | | --- | --- | --- | @@ -63,7 +63,7 @@ For richer PagerDuty incidents you can supply an optional `parameters` block alo | `client_url` | string | top-level `client_url` | | `dedup_key` | string | top-level `dedup_key` | -Example with a clickable link back to LimaCharlie and a dedup key tied to the detection: +This example has a link back to LimaCharlie and a dedup key that uses the detection: ```yaml - action: extension request @@ -94,9 +94,9 @@ Example with a clickable link back to LimaCharlie and a dedup key tied to the de ### Migrating D&R Rule from legacy Service to new Extension -***Note: LimaCharlie has migrated from Services to Extensions. Legacy services are no longer supported.*** +***Note: LimaCharlie moved from Services to Extensions. Legacy services are not supported.*** -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to assess if any rules reference legacy PagerDuty service, preview the change and execute the conversion required in the rule "response". +Use the [Python CLI](https://github.com/refractionPOINT/python-limacharlie) to find the rules that reference the legacy PagerDuty service. The CLI also shows a preview of the change and does the conversion in the rule "response". Command line to preview PagerDuty rule conversion: @@ -104,9 +104,9 @@ Command line to preview PagerDuty rule conversion: limacharlie extension convert_rules --name ext-pagerduty ``` -A dry-run response (default) will display the rule name being changed, a JSON of the service request rule and a JSON of the incoming extension request change. +A dry run is the default. It shows the name of the rule that changes, a JSON of the service request rule, and a JSON of the new extension request. -To execute the change in the rule, explicitly set `--dry-run` flag to `--no-dry-run` +To do the change in the rule, set the `--dry-run` flag to `--no-dry-run`. Command line to execute PagerDuty rule conversion: @@ -114,6 +114,6 @@ Command line to execute PagerDuty rule conversion: limacharlie extension convert_rules --name ext-pagerduty --no-dry-run ``` -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. Extensions integrate third-party tools, automate workflows, and add new capabilities. Organizations subscribe to Extensions, and each Extension gets specific permissions to interact with the infrastructure of the organization. An Extension can be private or public, for use in one organization or for the full community. This framework supports scale, flexibility, and secure, repeatable deployments. -In LimaCharlie, an Organization represents a tenant within the SecOps Cloud Platform, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the SecOps Cloud Platform. It gives a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives full control of security operations. This structure supports flexible, multi-tenant setups for managed security providers, and for enterprises that manage many departments or clients. diff --git a/docs/5-integrations/extensions/third-party/plaso.md b/docs/5-integrations/extensions/third-party/plaso.md index d86b10e26..98ea35c03 100644 --- a/docs/5-integrations/extensions/third-party/plaso.md +++ b/docs/5-integrations/extensions/third-party/plaso.md @@ -2,76 +2,76 @@ Plaso Extension Pricing -While it is free to enable the Plaso extension, pricing is applied to both the original downloaded artifact and the processed (Plaso) artifacts -- $0.02/GB for the original downloaded artifact, and $1.0/GB for the generation of the processed artifacts. +The Plaso extension is free to enable, but there is a charge for the original downloaded artifact and for the processed (Plaso) artifacts -- $0.02/GB for the original downloaded artifact, and $1.0/GB to generate the processed artifacts. ## About -[Plaso](https://plaso.readthedocs.io/) is a Python-based suite of tools used for creation of analysis timelines from forensic artifacts acquired from an endpoint. +[Plaso](https://plaso.readthedocs.io/) is a suite of tools in Python. It creates analysis timelines from forensic artifacts that you acquire from an endpoint. -These timelines are invaluable tools for digital forensic investigators and analysts, enabling them to effectively correlate the vast quantities of information encountered in logs and various forensic artifacts encountered in an intrusion investigation. +Digital forensic investigators and analysts use these timelines to correlate the large quantities of information in an intrusion investigation. This information is in logs and in many different forensic artifacts. The primary tools in the Plaso suite used for this process are [log2timeline](https://plaso.readthedocs.io/en/latest/sources/user/Using-log2timeline.html), [psort](https://plaso.readthedocs.io/en/latest/sources/user/Using-psort.html), and [psteal](https://plaso.readthedocs.io/en/latest/sources/user/Using-psteal.html). - `log2timeline` - bulk forensic artifact parser -- `psort` - builds timelines based on output from `log2timeline` -- `psteal` - Simply a wrapper for `log2timeline` and `psort` +- `psort` - builds timelines from the output of `log2timeline` +- `psteal` - a wrapper for `log2timeline` and `psort` -The `ext-plaso` extension within LimaCharlie allows you to run `log2timeline` and `psort` (using the `psteal` wrapper) against artifacts obtained from an endpoint, such as event logs, registry hives, and various other forensic artifacts. When executed, Plaso will parse and extract information from all acquired evidence artifacts that it has support for. See the [Plaso parsers and plugins reference](https://plaso.readthedocs.io/en/latest/sources/user/Parsers-and-plugins.html) for the full list of supported parsers. +The `ext-plaso` extension in LimaCharlie runs `log2timeline` and `psort` (with the `psteal` wrapper) against artifacts from an endpoint, such as event logs, registry hives, and other forensic artifacts. Plaso parses and extracts information from each acquired evidence artifact that it supports. For the full list of supported parsers, see the [Plaso parsers and plugins reference](https://plaso.readthedocs.io/en/latest/sources/user/Parsers-and-plugins.html). ## Extension Configuration Long Execution Times -Note that it can take **several minutes** for the plaso generation to complete for larger triage collections, but once it finishes you will see the results in the `ext-plaso` Sensor timeline, as well as the uploaded artifacts on the Artifacts page. +For a larger triage collection, the plaso generation can take **several minutes**. After it completes, the results are in the `ext-plaso` Sensor timeline, and the uploaded artifacts are on the Artifacts page. -The `ext-plaso` extension runs `psteal` (`log2timeline` + `psort`) against the acquired evidence using the following commands: +The `ext-plaso` extension runs `psteal` (`log2timeline` + `psort`) against the acquired evidence with these commands: 1. ```bash psteal.py --source /path/to/artifact -o dynamic --storage-file $artifact_id.plaso -w $artifact_id.csv ``` -Upon running `psteal.py`, a `.plaso` file and a `.csv` file are generated. They will be uploaded as LimaCharlie artifacts. +`psteal.py` generates a `.plaso` file and a `.csv` file. The extension uploads both as LimaCharlie artifacts. -- Resulting `.plaso` file contains the raw output of `log2timeline.py` -- Resulting `.csv` file contains the CSV formatted version of the `.plaso` file contents +- The `.plaso` file contains the raw output of `log2timeline.py` +- The `.csv` file contains the contents of the `.plaso` file in CSV format 1. ```bash pinfo.py $artifact_id.plaso -w $artifact_id_pinfo.json --output_format json ``` -After `psteal.py` runs, information is gathered from the resulting `.plaso` file using the `pinfo.py` utility and pushed into the `ext-plaso` sensor timeline as a `pinfo` event. This event provides a detailed summary with metrics of the processing that occurred, as well as any relevant errors you should be aware of. +After `psteal.py` runs, the `pinfo.py` utility collects information from the `.plaso` file. The extension sends this information to the `ext-plaso` sensor timeline as a `pinfo` event. The event gives a detailed summary with metrics of the processing, and the related errors. -The following events will be pushed to the `ext-plaso` sensor timeline: +The extension sends these events to the `ext-plaso` sensor timeline: -- `job_queued`: indicates that `ext-plaso` has received and queued a request to process data -- `job_started`: indicates that `ext-plaso` has started processing the data -- `job_failed`: indicates that the processing job failed; the `error` field contains the reason -- `pinfo`: contains the `pinfo.py` output summarizing the results of the plaso file generation -- `plaso`: contains the `artifact_id` of the plaso file that was uploaded to LimaCharlie -- `csv`: contains the `artifact_id` of the CSV file that was uploaded to LimaCharlie; when timeline ingestion is enabled, it also reports `events_sent_to_timeline` and `rows_skipped` -- `plaso_event`: one event per row of the generated timeline, only when timeline ingestion is enabled (see [Timeline Ingestion](#timeline-ingestion)) +- `job_queued`: shows that `ext-plaso` received a request to process data and put it in the queue +- `job_started`: shows that `ext-plaso` started to process the data +- `job_failed`: shows that the processing job failed; the `error` field contains the reason +- `pinfo`: contains the `pinfo.py` output that summarizes the results of the plaso file generation +- `plaso`: contains the `artifact_id` of the plaso file that the extension uploaded to LimaCharlie +- `csv`: contains the `artifact_id` of the CSV file that the extension uploaded to LimaCharlie; if timeline ingestion is enabled, it also reports `events_sent_to_timeline` and `rows_skipped` +- `plaso_event`: one event for each row of the generated timeline, only if timeline ingestion is enabled (see [Timeline Ingestion](#timeline-ingestion)) ## Timeline Ingestion -By default, the generated timeline is only available as downloadable `.plaso` and `.csv` artifacts. Setting the optional `send_to_timeline` parameter to `true` on a `generate` request additionally ingests every row of the generated CSV timeline as an individual `plaso_event` event on the `ext-plaso` sensor timeline. +By default, the generated timeline is available only as downloadable `.plaso` and `.csv` artifacts. Set the optional `send_to_timeline` parameter to `true` on a `generate` request. The extension then also ingests each row of the generated CSV timeline as one `plaso_event` event on the `ext-plaso` sensor timeline. -Each `plaso_event` carries the timeline columns under `results`, including the forensic timestamp (`results/datetime`), the plaso parser that produced the entry, and the event message. Rows are ingested in chronological order (as sorted by `psort`), making the full forensic timeline searchable with LCQL and usable in D&R rules. Combined with the automation below, this enables an end-to-end triage workflow — collection, timeline generation, and detection — entirely within LimaCharlie. +Each `plaso_event` carries the timeline columns under `results`. These columns include the forensic timestamp (`results/datetime`), the plaso parser that made the entry, and the event message. The extension ingests the rows in chronological order, as sorted by `psort`. You can then search the full forensic timeline with LCQL and use it in D&R rules. With the automation below, the full triage workflow stays in LimaCharlie: collection, timeline generation, and detection. Ingestion Volume -A Plaso timeline for a full triage collection can contain hundreds of thousands to millions of rows. Enabling `send_to_timeline` ingests all of them as events, which is billed as regular event ingestion volume. +A Plaso timeline for a full triage collection can contain hundreds of thousands of rows, or millions of rows. If you enable `send_to_timeline`, the extension ingests all of them as events. LimaCharlie bills this as regular event ingestion volume. -Rows of the CSV that cannot be parsed are skipped rather than failing the job; the final `csv` status event reports how many events were ingested (`events_sent_to_timeline`) and how many rows were skipped (`rows_skipped`). +If a row of the CSV cannot be parsed, the extension skips the row and the job continues. The final `csv` status event reports the number of ingested events (`events_sent_to_timeline`) and the number of skipped rows (`rows_skipped`). ## Usage & Automation -LimaCharlie can automatically kick off evidence processing with Plaso based off of the artifact ID provided in a rule action, or you can run it manually via the extension. +LimaCharlie can start evidence processing with Plaso automatically, from the artifact ID in a rule action. You can also run the processing manually from the extension. ### Velociraptor Triage Acquisition Processing -If you use the LimaCharlie [Velociraptor](velociraptor.md) extension, a good use case of `ext-plaso` would be to trigger Plaso evidence processing upon ingestion of a Velociraptor KAPE files artifact collection. +If you use the LimaCharlie [Velociraptor](velociraptor.md) extension, one use of `ext-plaso` is to start Plaso evidence processing when LimaCharlie ingests a Velociraptor KAPE files artifact collection. -1. Configure a D&R rule to watch for Velociraptor collection events upon ingestion, and then trigger the Plaso extension: +1. Configure a D&R rule to watch for Velociraptor collection events at ingestion. The rule then triggers the Plaso extension: **Detect:** @@ -99,21 +99,21 @@ If you use the LimaCharlie [Velociraptor](velociraptor.md) extension, a good use send_to_timeline: true ``` - The `send_to_timeline` parameter is optional; when set to `true`, the resulting timeline rows are also ingested as `plaso_event` events (see [Timeline Ingestion](#timeline-ingestion)). + The `send_to_timeline` parameter is optional. If you set it to `true`, the extension also ingests the timeline rows as `plaso_event` events (see [Timeline Ingestion](#timeline-ingestion)). -2. Launch a `Windows.KapeFiles.Targets` artifact collection in the LimaCharlie Velociraptor extension. This instructs Velociraptor to gather all endpoint artifacts defined in [this KAPE Target file](https://github.com/EricZimmerman/KapeFiles/blob/master/Targets/Compound/KapeTriage.tkape). +2. Start a `Windows.KapeFiles.Targets` artifact collection in the LimaCharlie Velociraptor extension. Velociraptor then collects all endpoint artifacts that [the KAPE Target file](https://github.com/EricZimmerman/KapeFiles/blob/master/Targets/Compound/KapeTriage.tkape) defines. **Argument options:** - - `EventLogs=Y` - EventLogs only, quicker processing time for proof of concept + - `EventLogs=Y` - EventLogs only, faster processing time for a proof of concept - `KapeTriage=Y` - full [KapeTriage](https://github.com/EricZimmerman/KapeFiles/blob/master/Targets/Compound/KapeTriage.tkape) files collection ![velociraptor ext 3](../../../assets/images/velociraptor-ext-3.png) -3. Once Velociraptor collects, zips, and uploads the evidence, the previously created D&R rule will send the triage `.zip` to `ext-plaso` for processing. Watch the `ext-plaso` sensor timeline for status and the Artifacts page for the resulting `.plaso` & `.csv` output files. See [Working with the Output](#working-with-the-output). +3. After Velociraptor collects, zips, and uploads the evidence, the D&R rule that you created sends the triage `.zip` to `ext-plaso` for processing. For the status, watch the `ext-plaso` sensor timeline. For the `.plaso` & `.csv` output files, watch the Artifacts page. See [Working with the Output](#working-with-the-output). ### MFT Processing -If you use the LimaCharlie [Dumper](../limacharlie/dumper.md) extension, a good use case of `ext-plaso` would be to trigger Plaso evidence processing upon ingestion of a MFT CSV artifact. +If you use the LimaCharlie [Dumper](../limacharlie/dumper.md) extension, one use of `ext-plaso` is to start Plaso evidence processing when LimaCharlie ingests an MFT CSV artifact. -1. Configure a D&R rule to watch for MFT collection events upon ingestion, and then trigger the Plaso extension: +1. Configure a D&R rule to watch for MFT collection events at ingestion. The rule then triggers the Plaso extension: **Detect:** @@ -140,21 +140,21 @@ If you use the LimaCharlie [Dumper](../limacharlie/dumper.md) extension, a good artifact_id: '{{ .routing.log_id }}' ``` -2. Launch an MFT dump in the LimaCharlie Dumper extension. +2. Start an MFT dump in the LimaCharlie Dumper extension. ![plaso ext 1](../../../assets/images/plaso-ext-1.png) -3. Once dumper is complete and uploads the evidence, the previously created D&R rule will send the zipped MFT CSV to `ext-plaso` for processing. Watch the `ext-plaso` sensor timeline for status and the Artifacts page for the resulting `.plaso` & `.csv` output files. See [Working with the Output](#working-with-the-output). +3. After the dumper completes and uploads the evidence, the D&R rule that you created sends the zipped MFT CSV to `ext-plaso` for processing. For the status, watch the `ext-plaso` sensor timeline. For the `.plaso` & `.csv` output files, watch the Artifacts page. See [Working with the Output](#working-with-the-output). ## Working with the Output -Running the extension generates the following useful outputs: +The extension generates these outputs: ![image.png](../../../assets/images/image(254).png) - `pinfo` on `ext-plaso` sensor timeline - First and foremost, after the completion of a processing job by `ext-plaso`, it is highly encouraged to analyze the resulting `pinfo` event on the `ext-plaso` sensor timeline. This event provides a detailed summary with metrics of the processing that occurred, as well as any relevant errors you should be aware of. + After `ext-plaso` completes a processing job, analyze the `pinfo` event on the `ext-plaso` sensor timeline first. The event gives a detailed summary with metrics of the processing, and the related errors. - - Pay close attention to fields such as `warnings_by_parser` or `warnings_by_path_spec` which may reveal parser errors that were encountered. - - Sample output of `pinfo` showing counts of parsed artifacts nested under `storage_counters` -- this provides insight as to which, and how many events will be present in your CSV timeline. + - Examine fields such as `warnings_by_parser` or `warnings_by_path_spec`. These fields can show parser errors. + - This sample output of `pinfo` shows the counts of parsed artifacts under `storage_counters`. The counts show which events are in your CSV timeline, and how many. ```text "amcache": 986, @@ -202,10 +202,10 @@ Running the extension generates the following useful outputs: ![image.png](../../../assets/images/image(253).png) - `plaso` artifact - The downloadable `.plaso` file contains the raw output of `log2timeline.py` and can be [imported into Timesketch](https://timesketch.org/guides/user/upload-data/) as a timeline. + The downloadable `.plaso` file contains the raw output of `log2timeline.py`. You can [import it into Timesketch](https://timesketch.org/guides/user/upload-data/) as a timeline. - `csv` artifact - The downloadable `.csv` file can be easily viewed in any CSV viewer, but a highly recommended tool for this is [Timeline Explorer](https://ericzimmerman.github.io/) from Eric Zimmerman. + You can view the downloadable `.csv` file in any CSV viewer. A recommended tool is [Timeline Explorer](https://ericzimmerman.github.io/) from Eric Zimmerman. ### Timeline Events -If the request was made with `send_to_timeline: true`, the full timeline is also available as `plaso_event` events on the `ext-plaso` sensor timeline, where it can be explored chronologically, queried with LCQL, and matched by D&R rules. See [Timeline Ingestion](#timeline-ingestion). +If the request used `send_to_timeline: true`, the full timeline is also available as `plaso_event` events on the `ext-plaso` sensor timeline. You can examine these events in chronological order, query them with LCQL, and match them with D&R rules. See [Timeline Ingestion](#timeline-ingestion). diff --git a/docs/5-integrations/extensions/third-party/renigma.md b/docs/5-integrations/extensions/third-party/renigma.md index 61bd224ff..22fa724d0 100644 --- a/docs/5-integrations/extensions/third-party/renigma.md +++ b/docs/5-integrations/extensions/third-party/renigma.md @@ -2,17 +2,17 @@ ## About REnigma -[REnigma](https://dtrsec.com/) is an advanced malware analysis platform leveraging its unique Record and Replay technology to deliver unparalleled precision and depth. By recording every state change in a virtual machine during live execution, REnigma enables analysts to replay and analyze malware behaviors offline, down to the instruction level. This approach eliminates the risk of evasion and ensures a comprehensive capture of malicious activity. For SOC teams triaging alerts or incident responders conducting deep dives, REnigma offers rapid detonation, precision analysis, and effortless artifact extraction. Its API integrations further enhance workflows, enabling seamless automation and streamlined investigation processes. +[REnigma](https://dtrsec.com/) is a malware analysis platform that uses Record and Replay technology. REnigma records each state change in a virtual machine during live execution. Analysts can then replay and analyze the behavior of the malware offline, down to the instruction level. This method removes the risk of evasion and captures all malicious activity. For SOC teams that triage alerts, and for incident responders, REnigma gives fast detonation, precise analysis, and extraction of artifacts. Its API integrations also automate investigation workflows. ## About the Extension -The LimaCharlie Extension for REnigma seamlessly integrates with the REnigma API, enabling automated analysis of suspicious URLs or files collected using the LimaCharlie BinLib or Artifact Extensions. When a file or URL triggers an alert in LimaCharlie, preconfigured Detection & Response () rules can automatically queue the item for further investigation in REnigma. +The LimaCharlie Extension for REnigma connects to the REnigma API. It analyzes suspicious URLs or files that the LimaCharlie BinLib or Artifact Extensions collect. When a file or URL triggers an alert in LimaCharlie, preconfigured Detection & Response () rules can queue the item for investigation in REnigma. -Through the integration, these D&R rules send the artifact or URL directly to REnigma, where it is recorded and analyzed in a controlled virtual machine environment. Analysts can then access detailed execution data, artifacts, and network patterns captured by REnigma's Record and Replay technology. This workflow not only streamlines the triage process but also provides deep insights into potential threats without requiring manual intervention at every step. +These D&R rules send the artifact or URL directly to REnigma. REnigma records and analyzes the item in a controlled virtual machine. Analysts can then see the execution data, the artifacts, and the network patterns that the Record and Replay technology captured. This workflow shortens the triage process. It also gives deep information about possible threats without manual work at each step. ## Configuration -To use the REnigma extension, you will need your REnigma URL and API key. [Contact the REnigma team for access](https://dtrsec.com/contact.html). +To use the REnigma extension, you need your REnigma URL and API key. [Contact the REnigma team for access](https://dtrsec.com/contact.html). ![Configuration To use the REnigma extension, you will need your REnigma URL and API key](../../../assets/images/image(284).png) @@ -20,11 +20,11 @@ To use the REnigma extension, you will need your REnigma URL and API key. [Conta You can submit a file or URL to the REnigma extension for processing in one of 2 ways: -1. Via the LimaCharlie web UI: +1. With the LimaCharlie web app: - 1. Submit the ID of the artifact you wish to process with REnigma, and it will get uploaded and processed via a series of D&R rules. You will see the output in the `ext-renigma` sensor timeline.![You can submit a file or URL to the REnigma extension for processing in one of 2 ways: 1](../../../assets/images/image(297).png) - 2. Submit the URL you wish to analyze with REnigma, and it will get sent and processed via a series of D&R rules. You will see the output in the `ext-renigma` sensor timeline.![You can submit a file or URL to the REnigma extension for processing in one of 2 ways: 1](../../../assets/images/image(296).png) -2. Via D&R rules: + 1. Submit the ID of the artifact that you want REnigma to process. A series of D&R rules uploads and processes the artifact. The output shows in the `ext-renigma` sensor timeline.![You can submit a file or URL to the REnigma extension for processing in one of 2 ways: 1](../../../assets/images/image(297).png) + 2. Submit the URL that you want REnigma to analyze. A series of D&R rules sends and processes the URL. The output shows in the `ext-renigma` sensor timeline.![You can submit a file or URL to the REnigma extension for processing in one of 2 ways: 1](../../../assets/images/image(296).png) +2. With D&R rules: 1. Detect: @@ -47,7 +47,7 @@ You can submit a file or URL to the REnigma extension for processing in one of 2 disable_internet: false ``` -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. Extensions integrate third-party tools, automate workflows, and add new capabilities. Organizations subscribe to Extensions and give them specific permissions to interact with their infrastructure. An Extension can be private or public, for one organization or for the community. This framework supports scale, flexibility, and secure, repeatable deployments. ## Related Articles diff --git a/docs/5-integrations/extensions/third-party/secureannex.md b/docs/5-integrations/extensions/third-party/secureannex.md index c3801825d..e3cb6239f 100644 --- a/docs/5-integrations/extensions/third-party/secureannex.md +++ b/docs/5-integrations/extensions/third-party/secureannex.md @@ -1,8 +1,8 @@ # Secure Annex -[Secure Annex](https://secureannex.com/) is a browser extension security platform that provides a comprehensive analysis of the Chrome extensions installed across your organization's endpoints. +[Secure Annex](https://secureannex.com/) is a security platform for browser extensions. It analyzes the Chrome extensions that are installed on the endpoints in your organization. -The Secure Annex LimaCharlie Extension allows you to query the Secure Annex API with the IDs of Chrome extensions installed on endpoints within your organization in order to get detailed information about the extensions. You can then perform additional analysis or craft rules based on the results. +The Secure Annex LimaCharlie Extension queries the Secure Annex API with the IDs of the Chrome extensions on the endpoints in your organization. The query returns detailed information about the extensions. You can then do more analysis, or write rules that use the results. API endpoints available for querying are: @@ -13,42 +13,42 @@ API endpoints available for querying are: - /urls - /analysis -This is currently only supported on Windows, macOS, and Chrome sensors. +At this time, only Windows, macOS, and Chrome sensors support this. ## Setup 1. Sign up and get an API key at 2. Subscribe to the Secure Annex extension in LimaCharlie - -3. Add the API key to the Secure Annex extension configuration within LimaCharlie +3. Add the API key to the configuration of the Secure Annex extension in LimaCharlie ## Usage ### Manually in the GUI -You can trigger an extension request manually within the web app by clicking the `Get extensions from endpoint` button. This will allow you to choose a sensor, or sensors via a Sensor Selector, to get extensions from. See [sensor selector expression examples](../../../8-reference/sensor-selector-expressions.md). +To trigger an extension request manually, click the `Get extensions from endpoint` button in the web app. Then choose the sensor, or the sensors, to get extensions from. To choose many sensors, use a Sensor Selector. See [sensor selector expression examples](../../../8-reference/sensor-selector-expressions.md). -The extensions are gathered from endpoints via the reliable tasking extension, which appends `secureannex_extensions` to the investigation ID of the `RECEIPT` or `OS_PACKAGES_REP` event in order to trigger an extension request to query Secure Annex. The results will be in the timeline of the `ext-secureannex` sensor. +The reliable tasking extension collects the extensions from the endpoints. It adds `secureannex_extensions` to the investigation ID of the `RECEIPT` or `OS_PACKAGES_REP` event. This triggers an extension request that queries Secure Annex. The results are in the timeline of the `ext-secureannex` sensor. ### Automatically via D&R Rules -Upon subscribing to the Secure Annex extension, several D&R rules are added to your organization in a **disabled state** to help you get more use out of the extension and automate your detections. They are as follows: +When you subscribe to the Secure Annex extension, LimaCharlie adds several D&R rules to your organization in a **disabled state**. These rules help you use the extension and automate your detections. The rules are: - `ext-secureannex-detect-vulnerabilities` - - This will look at the vulnerabilities and associated severities in the `vulnerability` results returned, and create detections on high and critical vulnerabilities found + - This rule looks at the vulnerabilities and their severities in the `vulnerability` results. It creates detections for the high and critical vulnerabilities that it finds - `ext-secureannex-detect-risk-rating` - - This will look at the risks and associated severities in the `manifest` results returned, and create detections on high and critical severities found + - This rule looks at the risks and their severities in the `manifest` results. It creates detections for the high and critical severities that it finds - `ext-secureannex-get-extensions-windows` - - This schedules a base64 encoded PowerShell script to run every 24 hours to query Windows sensors for installed Chrome extensions, and bring back a list of the extension IDs and versions - - The results will have a `secureannex_extensions` investigation ID associated that will allow LimaCharlie to automatically create Secure Annex extension requests with the IDs and versions included to perform a full analysis and bring back the results into the `ext-secureannex` sensor + - This rule schedules a base64 encoded PowerShell script every 24 hours. The script queries Windows sensors for installed Chrome extensions and returns a list of the extension IDs and versions + - The results have a `secureannex_extensions` investigation ID. LimaCharlie uses this ID to create Secure Annex extension requests that include the IDs and versions. The requests do a full analysis and return the results to the `ext-secureannex` sensor - `ext-secureannex-get-extensions-mac` - - This schedules a base64 encoded bash script to run every 24 hours to query macOS sensors for installed Chrome extensions, and bring back a list of the extension IDs and versions - - The results will have a `secureannex_extensions` investigation ID associated that will allow LimaCharlie to automatically create Secure Annex extension requests with the IDs and versions included to perform a full analysis and bring back the results into the `ext-secureannex` sensor + - This rule schedules a base64 encoded bash script every 24 hours. The script queries macOS sensors for installed Chrome extensions and returns a list of the extension IDs and versions + - The results have a `secureannex_extensions` investigation ID. LimaCharlie uses this ID to create Secure Annex extension requests that include the IDs and versions. The requests do a full analysis and return the results to the `ext-secureannex` sensor - `ext-secureannex-get-extensions-chrome` - - This schedules the `OS_PACKAGES` command to run every 24 hours to query Chrome sensors for installed Chrome extensions, and bring back a list of the extension IDs and versions - - The results will have an investigation ID associated that will allow LimaCharlie to automatically create Secure Annex extension requests with the IDs and versions included to perform a full analysis and bring back the results into the `ext-secureannex` sensor + - This rule schedules the `OS_PACKAGES` command every 24 hours. The command queries Chrome sensors for installed Chrome extensions and returns a list of the extension IDs and versions + - The results have an investigation ID. LimaCharlie uses this ID to create Secure Annex extension requests that include the IDs and versions. The requests do a full analysis and return the results to the `ext-secureannex` sensor -If you wish to use these, you need to enable them first. You can also copy the contents of these rules and create your own so they are no longer managed by the Secure Annex extension if you wish to modify them. +To use these rules, first enable them. To change a rule, copy its contents and create your own rule. The Secure Annex extension does not manage your own rules. ### Results -Results will show up in the live feed and timeline of the `ext-secureannex` Sensor. +Results show in the live feed and the timeline of the `ext-secureannex` Sensor. diff --git a/docs/5-integrations/extensions/third-party/sentinelone.md b/docs/5-integrations/extensions/third-party/sentinelone.md index 64099b064..771444ccd 100644 --- a/docs/5-integrations/extensions/third-party/sentinelone.md +++ b/docs/5-integrations/extensions/third-party/sentinelone.md @@ -1,17 +1,17 @@ # SentinelOne -[SentinelOne](https://www.sentinelone.com/) is an endpoint protection platform. The SentinelOne LimaCharlie Extension exposes the SentinelOne Management API to D&R rules and AI agents: list and act on agents (isolate, scan), triage threats (mitigate, verdict, incident status, notes), blocklist file hashes, and read the tenant's org hierarchy and activity log. +[SentinelOne](https://www.sentinelone.com/) is an endpoint protection platform. The SentinelOne LimaCharlie Extension gives D&R rules and AI agents access to the SentinelOne Management API. With the extension, you can list agents and act on them (isolate, scan). You can also triage threats (mitigate, verdict, incident status, notes), blocklist file hashes, and read the org hierarchy and the activity log of the tenant. -The extension provides two layers: +The extension has two layers: -- **Typed actions** for the common EDR/SecOps workflows, with friendly parameter names and built-in safety rails. -- A generic **`api_call`** passthrough for any SentinelOne endpoint not covered by a typed action. +- **Typed actions** for the common EDR/SecOps workflows. These actions have clear parameter names and built-in safety limits. +- A generic **`api_call`** passthrough for each SentinelOne endpoint that a typed action does not cover. ## Setup ### 1. Create a SentinelOne API token -In the SentinelOne management console, create an API token. A **Service User** token (Settings → Users → Service Users) is recommended: it is an API-only credential with a configurable expiry, unlike regular user tokens which expire after 30 days. Scope it to the sites/accounts the extension should manage. +In the SentinelOne management console, create an API token. A **Service User** token (Settings → Users → Service Users) is the recommended type. It is an API-only credential with a configurable expiry. Regular user tokens expire after 30 days. Scope the token to the sites and accounts that the extension manages. ### 2. Subscribe to the extension @@ -19,7 +19,7 @@ Subscribe to `ext-sentinelone` from the LimaCharlie **Marketplace** (Extensions ### 3. Store the API token -In **Secrets Manager**, create a new secret (for example `sentinelone-api-token`) and paste the API token as its value. +In **Secrets Manager**, create a new secret (for example `sentinelone-api-token`). Paste the API token as the value of the secret. ### 4. Configure the extension @@ -28,38 +28,38 @@ In **Extensions → ext-sentinelone → Configuration**, fill in: | Field | Required | Value | | --- | --- | --- | | `console_url` | yes | Your SentinelOne management console URL, e.g. `https://usea1-partners.sentinelone.net` | -| `api_token` | yes | Reference to the secret created in step 3, e.g. `hive://secret/sentinelone-api-token` | +| `api_token` | yes | Reference to the secret that you created in step 3, e.g. `hive://secret/sentinelone-api-token` | | `api_version` | no | API version path segment. Defaults to `v2.1`. | -| `site_ids` | no | List of SentinelOne site ids. When set, **every** call is restricted to these sites. See [Org scoping](#org-scoping). | -| `account_ids` | no | List of SentinelOne account ids. When set, every call is restricted to these accounts (combined with `site_ids` when both are set). | +| `site_ids` | no | List of SentinelOne site ids. If you set this field, the extension restricts **every** call to these sites. See [Org scoping](#org-scoping). | +| `account_ids` | no | List of SentinelOne account ids. If you set this field, the extension restricts every call to these accounts. If you set `site_ids` too, the extension combines the two fields. | -The token is sent as `Authorization: ApiToken ` on every request. Rotating the secret in Secrets Manager takes effect on the next request after a surfaced `401`. +The extension sends the token as `Authorization: ApiToken ` on each request. If you rotate the secret in Secrets Manager, the change takes effect on the next request after a surfaced `401`. ## Org scoping -For the MSSP / multi-tenant pattern — where one SentinelOne console holds many customers, split across **accounts** and **sites** — set `site_ids` and/or `account_ids` in the configuration to pin a single LimaCharlie organization to a single SentinelOne customer. Every call the organization makes is then restricted to that scope. For example, `list_agents` returns only that customer's endpoints, and a mitigation can only act within it. +One SentinelOne console can hold many customers, split across **accounts** and **sites**. For this MSSP or multi-tenant pattern, set `site_ids` or `account_ids` in the configuration. These fields pin one LimaCharlie organization to one SentinelOne customer. The extension then restricts each call from the organization to that scope. For example, `list_agents` returns only the endpoints of that customer, and a mitigation can act only inside the scope. The scope is a **hard cap**, not a default: -- **List actions** (`list_agents`, `list_threats`, `list_activities`, `list_sites` / `list_accounts` / `list_groups`) apply the scope to the `site_ids` / `account_ids` filters. A per-request `site_ids` / `account_ids` is **intersected** with the configured scope — a request can narrow within the scope but never widen past it, and a request that targets ids wholly outside the scope is **rejected**. -- **Mutating actions** (isolate / scan / mitigate / verdict / incident / note) inject the scope into the action's target filter, so an entity selected purely by id is still confined to the configured sites/accounts — you cannot act on another tenant's agent or threat by guessing its id. -- **`blocklist_hash`** cannot be applied `tenant`-wide for a scoped organization; the configured scope is used automatically when no scope is given on the request. -- **`api_call`** (the generic passthrough): a **write** (`POST` / `PUT` / `DELETE`) that carries no target `filter` cannot be constrained and is **refused** for a scoped organization — use a typed action or include a filter. A **read** (`GET`) has the scope injected into the query; a read of a single resource by path (for example `sites/`) cannot be constrained this way, so the typed actions are the fully-enforced surface. +- **List actions** (`list_agents`, `list_threats`, `list_activities`, `list_sites` / `list_accounts` / `list_groups`) apply the scope to the `site_ids` / `account_ids` filters. The extension **intersects** a per-request `site_ids` / `account_ids` with the configured scope. A request can narrow the scope but cannot widen it. The extension **rejects** a request that targets ids fully outside the scope. +- **Mutating actions** (isolate / scan / mitigate / verdict / incident / note) put the scope into the target filter of the action. An entity that you select only by id stays inside the configured sites and accounts. You cannot act on the agent or threat of another tenant if you guess its id. +- **`blocklist_hash`** cannot apply `tenant`-wide for a scoped organization. If the request gives no scope, the extension uses the configured scope. +- **`api_call`** (the generic passthrough): the extension cannot constrain a **write** (`POST` / `PUT` / `DELETE`) that carries no target `filter`, and it **refuses** that write for a scoped organization. Use a typed action, or include a filter. For a **read** (`GET`), the extension puts the scope into the query. It cannot constrain a read of a single resource by path (for example `sites/`), so the typed actions are the fully-enforced surface. !!! note "Scope by the right dimension" - Scope by `account_ids` when a customer maps to a SentinelOne *account*, and by `site_ids` when it maps to a *site*. The hierarchy-list actions can only filter by a dimension the endpoint supports: `list_accounts` filters by `account_ids` only (an account has no parent site), so an organization scoped by `site_ids` alone does not constrain `list_accounts`. Prefer `account_ids` (or set both) if listing the account hierarchy must also be scoped. The API token itself should also be scoped to the intended sites/accounts in SentinelOne — the configuration scope is enforced on top of the token's own permissions, not instead of them. + Scope by `account_ids` when a customer maps to a SentinelOne *account*, and by `site_ids` when it maps to a *site*. The hierarchy-list actions can filter only by a dimension that the endpoint supports. `list_accounts` filters by `account_ids` only, because an account has no parent site, so an organization scoped by `site_ids` alone does not constrain `list_accounts`. Use `account_ids`, or set both fields, if the list of the account hierarchy must also be scoped. Scope the API token itself to the intended sites and accounts in SentinelOne. The extension enforces the configuration scope on top of the permissions of the token, not instead of them. ## Actions -Every action that mutates state (isolate, scan, mitigate, verdict, incident, note) selects its targets with either an explicit id list (`agent_ids` / `threat_ids`) or a raw SentinelOne `filter` object. **An empty selector is refused** — the extension will not run an action that would target every entity in the tenant. +Each action that changes state (isolate, scan, mitigate, verdict, incident, note) selects its targets in one of two ways. Give an explicit id list (`agent_ids` / `threat_ids`), or give a raw SentinelOne `filter` object. **The extension refuses an empty selector.** It does not run an action that targets each entity in the tenant. -List actions return one page plus a cursor: `{data: [...], pagination: {nextCursor, totalItems}}`. Pass `cursor` back (together with the same filters) to fetch the next page. `limit` defaults to `100` (max `1000`). +List actions return one page and a cursor: `{data: [...], pagination: {nextCursor, totalItems}}`. To get the next page, send `cursor` back with the same filters. `limit` defaults to `100` (max `1000`). ### Generic #### `api_call` -Call any SentinelOne Management API endpoint — the escape hatch for endpoints without a typed action. +Call any SentinelOne Management API endpoint. Use this action for endpoints that have no typed action. | Field | Type | Notes | | --- | --- | --- | @@ -151,7 +151,7 @@ Set the incident status on selected threats. #### `add_threat_note` -Append a note to selected threats — useful for AI agents to record triage findings in the SentinelOne console. +Append a note to selected threats. AI agents can use this action to record triage findings in the SentinelOne console. | Field | Type | Notes | | --- | --- | --- | @@ -179,7 +179,7 @@ A scope is required: set `tenant: true` or at least one of `site_ids` / `group_i #### `list_sites` / `list_accounts` / `list_groups` -List the org hierarchy — useful to resolve the ids used by the scoping parameters above. +List the org hierarchy. Use these actions to find the ids for the scope parameters above. | Field | Type | Notes | | --- | --- | --- | @@ -212,14 +212,14 @@ Example response action that network-isolates the SentinelOne agent named in a d ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is read as a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the key is dropped from the payload. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context. Workflows that need to chain (find the agent, isolate it, annotate the threat) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold ids between calls. +`extension request` actions do not return a result to the rule. The rule engine does not put the response into the evaluation context of the rule. For a chain of steps (find the agent, isolate it, annotate the threat), use a [Playbook](../limacharlie/playbook.md) or an AI agent. A Playbook and an AI agent can hold ids between calls. ## Notes -- The token is sent as `Authorization: ApiToken ` — SentinelOne API tokens are static, not OAuth, and are not refreshable. A `401` is surfaced as a real auth failure; the extension then evicts its cached client so the next request re-reads the (possibly rotated) secret. -- SentinelOne cursors are not self-contained: re-send the same filters along with `cursor` on every page. -- `console_url` may be pasted with or without a trailing `/web/api[/version]` suffix — the extension normalizes it either way. -- Errors are surfaced as `sentinelone api on : `, with SentinelOne's error envelope flattened into the message. -- Unsubscribing from the extension preserves its saved configuration; re-subscribing restores it without reconfiguration. +- The extension sends the token as `Authorization: ApiToken `. SentinelOne API tokens are static, not OAuth, and you cannot refresh them. A `401` is surfaced as a real auth failure. The extension then removes its cached client, so the next request reads the secret again after a rotation. +- SentinelOne cursors are not self-contained. Send the same filters with `cursor` for each page. +- You can paste `console_url` with or without a trailing `/web/api[/version]` suffix. The extension normalizes both forms. +- Errors are surfaced as `sentinelone api on : `. The message holds the flattened error envelope from SentinelOne. +- If you unsubscribe from the extension, the saved configuration stays. If you subscribe again, the extension restores the configuration, and you do not configure it a second time. diff --git a/docs/5-integrations/extensions/third-party/servicenow.md b/docs/5-integrations/extensions/third-party/servicenow.md index 4500b3006..6a26f6468 100644 --- a/docs/5-integrations/extensions/third-party/servicenow.md +++ b/docs/5-integrations/extensions/third-party/servicenow.md @@ -1,23 +1,23 @@ # ServiceNow -[ServiceNow](https://www.servicenow.com/) is an IT service management (ITSM) and security operations platform used for ticketing, change/problem management, CMDB asset tracking, and security incident response. +[ServiceNow](https://www.servicenow.com/) is a platform for IT service management (ITSM) and security operations. Teams use it for ticketing, change and problem management, CMDB asset tracking, and security incident response. -The ServiceNow LimaCharlie Extension is primarily an **API bridge**: it lets LimaCharlie-side automation (D&R rules, AI agents) drive a ServiceNow instance as it sees fit — create/read/update/delete records on *any* table, append journal entries, manage attachments, count and query, and resolve CMDB items. On top of that bridge it ships typed incident conveniences and one optional, fully-configurable **Case-mirroring** recipe (LimaCharlie Cases ⇄ ServiceNow records). +The ServiceNow LimaCharlie Extension is mainly an **API bridge**. It lets automation on the LimaCharlie side (D&R rules, AI agents) drive a ServiceNow instance. The automation can create, read, update, and delete records on *any* table, append journal entries, manage attachments, count and query records, and resolve CMDB items. On top of that bridge, the extension adds typed incident actions and one optional, fully-configurable **Case-mirroring** recipe (LimaCharlie Cases ⇄ ServiceNow records). -Nothing pins the extension to the stock ITSM `incident` table. Security teams on Security Incident Response (`sn_si_incident`), change/problem workflows, or custom tables are all first-class: pass a `table` (or configure the mirror target) and the same actions apply. +The extension is not limited to the stock ITSM `incident` table. The same actions apply to Security Incident Response (`sn_si_incident`), to change and problem workflows, and to custom tables. Give a `table` value, or configure the mirror target. The sync model is stateless on the LimaCharlie side: -- **LC → ServiceNow**: `mirror_case` idempotently upserts a ServiceNow record from a LimaCharlie Case, anchored on the record's standard `correlation_id` / `correlation_display` fields. Repeated calls update the same record. -- **ServiceNow → LC**: `pull_incident_changes` returns records updated since a watermark, normalized for feeding back into Cases. Changes made by the integration's own user are excluded, breaking echo loops. +- **LC → ServiceNow**: `mirror_case` upserts a ServiceNow record from a LimaCharlie Case. The upsert is idempotent, because it uses the standard `correlation_id` / `correlation_display` fields of the record. Repeated calls update the same record. +- **ServiceNow → LC**: `pull_incident_changes` returns the records that changed since a watermark, in a normalized form for Cases. It excludes the changes of its own integration user, which stops echo loops. ## Setup ### 1. Create a ServiceNow integration user -Create a dedicated ServiceNow **integration user** for the extension and grant it the roles needed for the tables and operations you intend to drive (e.g. `itil` for incidents, `sn_si.analyst` for Security Incident Response, plus `rest_api_explorer`/table ACLs as appropriate). The integration user's ACLs govern everything the extension can read, write, or delete. +Create a dedicated ServiceNow **integration user** for the extension. Give the user the roles that the tables and the operations need (e.g. `itil` for incidents, `sn_si.analyst` for Security Incident Response, plus `rest_api_explorer` and table ACLs). The ACLs of the integration user control all that the extension can read, write, or delete. -Using a dedicated user matters for the Case-mirroring puller: `pull_incident_changes` filters out the extension's own writes by this user to break echo loops (see [Case mirroring](#case-mirroring-optional)). +A dedicated user is important for the Case-mirroring puller. `pull_incident_changes` removes the writes of this user to stop echo loops (see [Case mirroring](#case-mirroring-optional)). ### 2. Choose an authentication mode @@ -29,14 +29,14 @@ The extension supports three modes (set `auth_mode`): | `oauth_password` | `client_id`, `client_secret`, `username`, `password` | OAuth2 Resource Owner Password Credentials grant, then `refresh_token` to renew. | | `oauth_client_credentials` | `client_id`, `client_secret` | True server-to-server grant (no end-user password). Needs extra instance-side setup — see below. | -For the OAuth modes, register an OAuth application in ServiceNow (**System OAuth → Application Registry**) and copy its Client ID and Client Secret. +For the OAuth modes, register an OAuth application in ServiceNow (**System OAuth → Application Registry**). Copy its Client ID and Client Secret. -The **client credentials** grant needs two extra pieces of instance-side setup beyond the client registration: +The **client credentials** grant needs two more steps on the instance, after the client registration: -1. Set the system property `glide.oauth.inbound.client.credential.grant_type.enabled` to `true` (create it under **System Properties** if it doesn't exist). Without it the token endpoint returns `access_denied` / `server_error`. -2. On the OAuth application record, set the **OAuth Application User** (the `user` field) to your integration user. The grant issues tokens **as this user**, so it must hold the roles the actions need (e.g. `itil` / `sn_incident_write` for incident writes). Without it the token endpoint returns `unauthorized_client` ("integration user is not configured"). Set `integration_user` (below) to this same username so SN → LC polling can de-echo the extension's own writes. +1. Set the system property `glide.oauth.inbound.client.credential.grant_type.enabled` to `true`. If the property does not exist, create it under **System Properties**. Without the property, the token endpoint returns `access_denied` / `server_error`. +2. On the OAuth application record, set the **OAuth Application User** (the `user` field) to your integration user. The grant issues tokens **as this user**, so the user must hold the roles that the actions need (e.g. `itil` / `sn_incident_write` for incident writes). Without the user, the token endpoint returns `unauthorized_client` ("integration user is not configured"). Set `integration_user` (below) to this same username, so SN → LC polling can remove the echo of the extension's own writes. -The **basic** and **OAuth password** modes don't need this — they authenticate as the `username` you configure directly. +The **basic** and **OAuth password** modes do not need these steps. They authenticate as the `username` that you configure. ### 3. Subscribe to the extension @@ -44,7 +44,7 @@ Subscribe to `ext-servicenow` from the LimaCharlie **Marketplace** (Extensions ### 4. Store the credentials -In **Secrets Manager**, create secrets for the sensitive values — the `password` and `client_secret` fields are resolved as secret references at request time. For example create a `servicenow-password` secret and reference it as `hive://secret/servicenow-password`. +In **Secrets Manager**, create secrets for the sensitive values. The extension resolves the `password` and `client_secret` fields as secret references at request time. For example, create a `servicenow-password` secret and reference it as `hive://secret/servicenow-password`. ### 5. Configure the extension @@ -58,27 +58,27 @@ In **Extensions → ext-servicenow → Configuration**, fill in: | `password` | conditional | Secret reference. Required for `basic` / `oauth_password`. | | `client_id` | conditional | Required for `oauth_password` / `oauth_client_credentials`. | | `client_secret` | conditional | Secret reference. Required for `oauth_password` / `oauth_client_credentials`. | -| `integration_user` | no | The ServiceNow user the extension authenticates as. `pull_incident_changes` excludes changes made by this user. Set it to enable the echo-loop guard. | -| `correlation_display` | no | Label stamped on mirrored records' `correlation_display` field (default `LimaCharlie`). Scopes upserts and SN→LC polling, so multiple integrations can coexist. | -| `close_code` | no | `close_code` applied when mirroring a case into Resolved/Closed (default `Solution provided`). Must be a value in your instance's `close_code` choice list, which varies by ServiceNow version — the legacy `Solved (Permanently)` is not present on current releases. An invalid value is silently dropped by ServiceNow, which then trips the mandatory-resolution-code data policy. | +| `integration_user` | no | The ServiceNow user that the extension authenticates as. `pull_incident_changes` excludes the changes of this user. Set it to enable the echo-loop guard. | +| `correlation_display` | no | Label written to the `correlation_display` field of mirrored records (default `LimaCharlie`). It scopes upserts and SN→LC polling, so many integrations can work together. | +| `close_code` | no | `close_code` used when the extension mirrors a case into Resolved/Closed (default `Solution provided`). The value must be in the `close_code` choice list of your instance. This list changes with the ServiceNow version, and the legacy `Solved (Permanently)` is not in current releases. ServiceNow drops an invalid value without a message, and the mandatory-resolution-code data policy then fails. | | `mirror_table` | no | Target table for case mirroring (default `incident`; set `sn_si_incident` for Security Incident Response, or any task-derived table). | -| `mirror_subject_prefix` | no | Prefix for the mirrored record's `short_description` (default `LimaCharlie Case`). | +| `mirror_subject_prefix` | no | Prefix for the `short_description` of the mirrored record (default `LimaCharlie Case`). | | `mirror_state_map` | no | Override of case-status→record-state mapping, e.g. `{"new":1,"in_progress":2,"resolved":6,"closed":7}`. Used in both directions. | | `mirror_severity_map` | no | Override of case-severity→`{urgency,impact}` mapping, e.g. `{"critical":{"urgency":1,"impact":1}}`. | -Only `instance_url` is strictly required; the credential fields are validated at request time against the selected `auth_mode`. The extension is stateless — mirroring state lives in ServiceNow (`correlation_id`) and the returned `watermark`, so there is no database to provision. +Only `instance_url` is required. The extension validates the credential fields at request time against the selected `auth_mode`. The extension is stateless. The mirroring state is in ServiceNow (`correlation_id`) and in the returned `watermark`, so there is no database to provision. ## Actions -All actions accept a JSON request body when invoked from a D&R rule via `extension request`. The typed actions and the mirroring recipe are conveniences — a customer who models ServiceNow differently can ignore them and drive `create_record` / `update_record` / `query_table` directly. +Each action accepts a JSON request body when a D&R rule calls it with `extension request`. The typed actions and the mirroring recipe are shortcuts. A customer who models ServiceNow in another way can ignore them and use `create_record` / `update_record` / `query_table` directly. ### Generic Table API bridge (any table) -These actions operate against *any* table and never assume `incident`. +These actions work on *any* table. They never assume `incident`. #### `create_record` -Insert a record into any table with an arbitrary field map. The generic write counterpart to `query_table` — use it for `change_request`, `problem`, `sc_task`, custom tables, etc. +Insert a record into any table with a field map that you choose. This action is the generic write counterpart to `query_table`. Use it for `change_request`, `problem`, `sc_task`, custom tables, and others. | Field | Type | Notes | | --- | --- | --- | @@ -99,7 +99,7 @@ Fetch a single record from any table by `sys_id` or by its `number` field. #### `update_record` -Patch a record on any table by `sys_id` with an arbitrary field map (unspecified fields are left untouched). +Patch a record on any table by `sys_id` with a field map that you choose. The extension does not change the fields that you do not give. | Field | Type | Notes | | --- | --- | --- | @@ -109,7 +109,7 @@ Patch a record on any table by `sys_id` with an arbitrary field map (unspecified #### `delete_record` -Delete a record on any table by `sys_id`. Irreversible — the integration user's ACLs govern what can be deleted. +Delete a record on any table by `sys_id`. You cannot undo the deletion. The ACLs of the integration user control what the extension can delete. | Field | Type | Notes | | --- | --- | --- | @@ -118,7 +118,7 @@ Delete a record on any table by `sys_id`. Irreversible — the integration user' #### `query_table` -Read-only Table API query against any table (`incident`, `problem`, `change_request`, `cmdb_ci`, `sys_user`, …). An escape hatch for AI agents that need data the typed actions don't cover, and the way to resolve display names to the sys_ids the write actions expect. +Read-only Table API query against any table (`incident`, `problem`, `change_request`, `cmdb_ci`, `sys_user`, …). AI agents use it for data that the typed actions do not cover. Use it also to resolve display names to the sys_ids that the write actions need. | Field | Type | Notes | | --- | --- | --- | @@ -133,7 +133,7 @@ Returns `{ "count": N, "records": [...] }`. #### `count_records` -Return the number of records matching an encoded query, via the Aggregate API (no rows pulled). E.g. count open criticals before deciding to escalate. +Return the number of records that match an encoded query, with the Aggregate API. The action pulls no rows. For example, count the open critical records before you escalate. | Field | Type | Notes | | --- | --- | --- | @@ -142,11 +142,11 @@ Return the number of records matching an encoded query, via the Aggregate API (n ### Typed incident conveniences -Table-aware shortcuts that default to `incident`; set `table` to e.g. `sn_si_incident` to operate on Security Incident Response records. Beyond the fields below, each accepts an `extra` object to merge raw ServiceNow fields the typed schema doesn't model. +These table-aware shortcuts default to `incident`. Set `table` to `sn_si_incident`, for example, to work on Security Incident Response records. Each action also accepts an `extra` object. Use `extra` to merge raw ServiceNow fields that the typed schema does not model. #### `create_incident` -Open a record with typed subject/body, urgency/impact, and assignment. Returns the created record including its `sys_id` and `number`. +Open a record with a typed subject and body, urgency and impact, and assignment. Returns the new record with its `sys_id` and `number`. | Field | Type | Notes | | --- | --- | --- | @@ -156,7 +156,7 @@ Open a record with typed subject/body, urgency/impact, and assignment. Returns t | `state` | int | Incident state (1 New, 2 In Progress, 3 On Hold, 6 Resolved, 7 Closed, 8 Canceled). | | `urgency` | int | Urgency (1 High … 3 Low). | | `impact` | int | Impact (1 High … 3 Low). | -| `priority` | int | Usually derived from urgency×impact; set to override. | +| `priority` | int | ServiceNow usually derives this from urgency×impact. Set it to override. | | `category` | string | Category. | | `assignment_group` | string | Assignment group **sys_id** (reference; display names are not auto-resolved). | | `assigned_to` | string | Assignee user **sys_id**. | @@ -167,7 +167,7 @@ Open a record with typed subject/body, urgency/impact, and assignment. Returns t #### `update_incident` -Update a record by `sys_id`. Set `state` to drive workflow transitions, reassign, or append a work note/comment. +Update a record by `sys_id`. Set `state` to drive workflow transitions. You can also reassign the record, or append a work note or a comment. | Field | Type | Notes | | --- | --- | --- | @@ -191,7 +191,7 @@ Fetch a single record by `sys_id` or by human number (e.g. `INC0010023`, `SIR000 #### `search_incidents` -Search with a ServiceNow encoded query (`sysparm_query`), e.g. `active=true^state=2^ORDERBYDESCsys_updated_on`. Use to dedup before create or to look up existing work. +Search with a ServiceNow encoded query (`sysparm_query`), e.g. `active=true^state=2^ORDERBYDESCsys_updated_on`. Use it to remove duplicates before you create a record, or to find existing work. | Field | Type | Notes | | --- | --- | --- | @@ -208,7 +208,7 @@ Returns `{ "count": N, "incidents": [...] }`. #### `add_note` -Append an internal work note and/or a customer-visible comment to a record (default table `incident`). Journal fields **append** — they never overwrite. +Append an internal work note, a customer-visible comment, or both, to a record (default table `incident`). Journal fields **append**. They never overwrite. | Field | Type | Notes | | --- | --- | --- | @@ -232,7 +232,7 @@ Upload a file as an attachment on a record (default table `incident`). Set `cont #### `list_attachments` -List a record's attachment metadata (default table `incident`). Returns each attachment's `sys_id`, `file_name`, size and content type; pass an attachment `sys_id` to `get_attachment` to download it. +List the attachment metadata of a record (default table `incident`). Returns the `sys_id`, `file_name`, size, and content type of each attachment. To download an attachment, give its `sys_id` to `get_attachment`. | Field | Type | Notes | | --- | --- | --- | @@ -241,7 +241,7 @@ List a record's attachment metadata (default table `incident`). Returns each att #### `get_attachment` -Download an attachment's bytes by its attachment `sys_id` (from `list_attachments`). Returns `content_base64`, `content_type` and `size_bytes`. +Download the bytes of an attachment by its attachment `sys_id` (from `list_attachments`). Returns `content_base64`, `content_type` and `size_bytes`. | Field | Type | Notes | | --- | --- | --- | @@ -249,7 +249,7 @@ Download an attachment's bytes by its attachment `sys_id` (from `list_attachment #### `lookup_ci` -Resolve a CMDB configuration item (asset) by name or a custom encoded query — bridges LC sensor hostnames to the ServiceNow CMDB so incidents can reference the right asset. +Resolve a CMDB configuration item (asset) by name or with a custom encoded query. This action maps LC sensor hostnames to the ServiceNow CMDB, so incidents can reference the correct asset. | Field | Type | Notes | | --- | --- | --- | @@ -262,29 +262,29 @@ Returns `{ "count": N, "cis": [...] }`. ### Case mirroring (optional) -A bidirectional, fully-configurable recipe that keeps a [LimaCharlie Case](../limacharlie/index.md) and a ServiceNow record in sync. Mirroring is anchored on ServiceNow's purpose-built external-link fields: `correlation_id` holds the LimaCharlie case id and `correlation_display` holds the per-integration label (default `LimaCharlie`). +This recipe is bidirectional and fully configurable. It keeps a [LimaCharlie Case](../limacharlie/index.md) and a ServiceNow record in sync. The mirror uses the external-link fields of ServiceNow: `correlation_id` holds the LimaCharlie case id, and `correlation_display` holds the label of each integration (default `LimaCharlie`). #### `mirror_case` -**LC → ServiceNow.** Idempotently upsert a ServiceNow record from an LC Case. Looks the record up by `correlation_id=case_id` (scoped to this integration's `correlation_display`), so repeated calls update the same record rather than creating duplicates. Wire this to a D&R rule on case events. +**LC → ServiceNow.** Upsert a ServiceNow record from an LC Case. The action finds the record by `correlation_id=case_id`, in the scope of the `correlation_display` of this integration. Repeated calls update the same record and do not create duplicates. Connect this action to a D&R rule on case events. | Field | Type | Notes | | --- | --- | --- | | `case_id` | string | **Required.** LimaCharlie case id (stored as `correlation_id`). | | `case_number` | int | LimaCharlie case number (used in the record subject, `LimaCharlie Case #N: …`). | -| `status` | enum | `new`, `in_progress`, `resolved`, `closed`. Maps to `state` (configurable via `mirror_state_map`). | -| `severity` | enum | `critical`, `high`, `medium`, `low`, `info`. Maps to `urgency`/`impact` (configurable via `mirror_severity_map`; ServiceNow derives `priority`). | +| `status` | enum | `new`, `in_progress`, `resolved`, `closed`. Maps to `state` (configurable with `mirror_state_map`). | +| `severity` | enum | `critical`, `high`, `medium`, `low`, `info`. Maps to `urgency`/`impact` (configurable with `mirror_severity_map`; ServiceNow derives `priority`). | | `classification` | string | Case classification (`true_positive`, `false_positive`, `pending`); appended to the description. | -| `summary` | string | Case summary (becomes the record subject — first line, truncated to 160 chars — and description). | +| `summary` | string | Case summary. The first line, truncated to 160 chars, becomes the record subject. The summary also becomes the description. | | `conclusion` | string | Case conclusion (appended to description, used as `close_notes` on terminal states). | -| `assignees` | list of string | Accepted, but not currently reflected on the record. | +| `assignees` | list of string | Accepted, but not shown on the record at this time. | | `tags` | list of string | Appended to the description. | | `table` | string | Override the configured mirror target table for this call. | | `correlation_display` | string | Override the `correlation_display` label for this mirror. | | `sync_note` | string | Optional work note to record the sync on the record. | | `extra` | object | Raw fields merged into (and overriding) the mapped record fields. | -Default mappings applied (all overridable via config): +Default mappings applied (you can override all of them in the configuration): - Status → `state`: `new` → 1, `in_progress` → 2, `resolved` → 6, `closed` → 7. Terminal states (Resolved/Closed) also set `close_code` (from config) and `close_notes`. - Severity → `urgency`/`impact`: `critical` → 1/1, `high` → 1/2, `medium` → 2/2, `low` and `info` → 3/3. @@ -293,26 +293,26 @@ Returns `{ "created": bool, "sys_id": "...", "number": "...", "incident": {...} #### `pull_incident_changes` -**ServiceNow → LC.** Return records (on the mirror table, scoped to this integration's `correlation_display`) updated at/after a watermark, normalized to `{case_id, case_status, …}` ready to apply back to LC Cases. It **excludes changes made by the `integration_user`** to break echo loops, and returns a fresh `watermark` to drive the next pull. Drive it from a D&R `schedule` rule (e.g. every 12h per org) and pass the watermark back as rule state. +**ServiceNow → LC.** Return the records on the mirror table that changed at or after a watermark, in the scope of the `correlation_display` of this integration. The action normalizes each record to `{case_id, case_status, …}`, ready to apply back to LC Cases. It **excludes changes made by the `integration_user`** to stop echo loops. It also returns a fresh `watermark` for the next pull. Call it from a D&R `schedule` rule (e.g. every 12h for each org), and pass the watermark back as rule state. | Field | Type | Notes | | --- | --- | --- | -| `since` | string | ServiceNow datetime watermark (`YYYY-MM-DD HH:MM:SS`, UTC). Empty bootstraps from the most recent changes (newest first); pass the returned watermark back to move forward. | +| `since` | string | ServiceNow datetime watermark (`YYYY-MM-DD HH:MM:SS`, UTC). An empty value starts from the most recent changes (newest first). Pass the returned watermark back to move forward. | | `limit` | int | Max records (default `100`). | | `include_own_changes` | bool | Disable the echo-loop guard (include changes by the integration user). | -Returns `{ "count": N, "changes": [...], "watermark": "YYYY-MM-DD HH:MM:SS" }`. Each change carries `sys_id`, `number`, `case_id` (from `correlation_id`), `state`, a normalized `case_status` (`new` / `in_progress` / `resolved` / `closed` — On Hold maps to `in_progress`, Canceled to `closed`), `short_description`, `sys_updated_on`, and `sys_updated_by`. +Returns `{ "count": N, "changes": [...], "watermark": "YYYY-MM-DD HH:MM:SS" }`. Each change carries `sys_id`, `number`, `case_id` (from `correlation_id`), `state`, a normalized `case_status`, `short_description`, `sys_updated_on`, and `sys_updated_by`. The `case_status` value is `new`, `in_progress`, `resolved`, or `closed`. On Hold maps to `in_progress`, and Canceled maps to `closed`. -> The watermark boundary is **inclusive** (≥ `since`), so de-dupe applied changes by `sys_id`, and keep `limit` above the largest expected same-second burst of updates. +> The watermark boundary is **inclusive** (≥ `since`). Remove the duplicates in the applied changes by `sys_id`. Keep `limit` above the largest number of updates that you expect in the same second. #### Wiring up the bidirectional sync -Both directions are driven from D&R rules — the extension holds no schedule of its own: +D&R rules drive both directions. The extension holds no schedule of its own: -- **LC → ServiceNow**: a D&R rule on Case events calls `mirror_case` with the case fields, pushing changes as they happen. -- **ServiceNow → LC**: a scheduled D&R rule periodically calls `pull_incident_changes`, passing back the watermark from the previous run, and applies the returned changes to Cases. +- **LC → ServiceNow**: a D&R rule on Case events calls `mirror_case` with the case fields. It sends each change when the change happens. +- **ServiceNow → LC**: a scheduled D&R rule calls `pull_incident_changes` at intervals. The rule sends back the watermark from the previous run, and applies the returned changes to Cases. -Because `pull_incident_changes` excludes the integration user's own writes, the LC → SN → LC round trip does not re-import what the extension itself mirrored. +`pull_incident_changes` excludes the writes of the integration user. The LC → SN → LC round trip therefore does not import again what the extension mirrored. ## Detection & Response @@ -331,9 +331,9 @@ Example response action that opens a ServiceNow incident for a detection: ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is read as a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the key is dropped from the payload. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context, so the freshly-created `sys_id` is not available to a subsequent action in the same rule. Workflows that need to chain (open a record, then attach a file, then add a note) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold the `sys_id` between calls. +`extension request` actions do not return a result to the rule. The rule engine does not put the response into the evaluation context of the rule, so a later action in the same rule cannot use the new `sys_id`. For a chain of steps (open a record, attach a file, add a note), use a [Playbook](../limacharlie/playbook.md) or an AI agent. A Playbook and an AI agent can hold the `sys_id` between calls. To append triage findings on an existing record (for example from a Playbook or AI agent that already knows the `sys_id`), use `add_note`: @@ -348,11 +348,11 @@ To append triage findings on an existing record (for example from a Playbook or ## Notes -- The extension is **stateless** — mirroring state lives in ServiceNow (`correlation_id`) and the returned `watermark`; there is no database. -- Reference fields (`assignment_group`, `assigned_to`, `caller_id`) take **sys_ids**, not display names — display names are not auto-resolved. Use `query_table` against `sys_user` / `sys_user_group` to resolve a name to its sys_id first. -- ServiceNow rate limiting (`429`) is honored once per request with a `Retry-After` cap of 5 seconds; a persistent `429` surfaces to the caller. -- A business rule or data policy abort surfaces as an error either way: ServiceNow may return a non-2xx status (e.g. `403`) or, for some aborts, HTTP `200` with a `{"status": "failure"}` envelope. The extension treats both as errors, never as success. (A common cause is resolving a record with a `close_code` that isn't in the instance's choice list — see the `close_code` config note above.) -- `correlation_id` and `correlation_display` values are sanitized (encoded-query delimiters stripped) on both the write and the lookup path, keeping upserts idempotent even for hostile values. -- The OAuth access token is cached and renewed via `refresh_token` (in `oauth_password` mode). Rotating the secret in Secrets Manager evicts the cached client on the next surfaced `401`. -- `pull_incident_changes` only breaks echo loops if `integration_user` is set to the user the extension authenticates as. +- The extension is **stateless**. The mirroring state is in ServiceNow (`correlation_id`) and in the returned `watermark`. There is no database. +- Reference fields (`assignment_group`, `assigned_to`, `caller_id`) take **sys_ids**, not display names. The extension does not resolve display names. First use `query_table` on `sys_user` / `sys_user_group` to resolve a name to its sys_id. +- The extension obeys ServiceNow rate limiting (`429`) one time for each request, with a `Retry-After` cap of 5 seconds. A `429` that continues is surfaced to the caller. +- An abort from a business rule or a data policy always surfaces as an error. ServiceNow can return a non-2xx status (e.g. `403`) or, for some aborts, HTTP `200` with a `{"status": "failure"}` envelope. The extension treats both as errors, never as success. A common cause is a record that you resolve with a `close_code` that is not in the choice list of the instance — see the `close_code` config note above. +- The extension sanitizes the `correlation_id` and `correlation_display` values on the write path and on the lookup path. It removes the encoded-query delimiters. Upserts stay idempotent, also for hostile values. +- The extension caches the OAuth access token and renews it with `refresh_token` (in `oauth_password` mode). If you rotate the secret in Secrets Manager, the extension removes the cached client on the next surfaced `401`. +- `pull_incident_changes` stops echo loops only if `integration_user` is the user that the extension authenticates as. - Errors are surfaced as `servicenow api on : `. diff --git a/docs/5-integrations/extensions/third-party/strelka.md b/docs/5-integrations/extensions/third-party/strelka.md index 62a5265d6..0579391ed 100644 --- a/docs/5-integrations/extensions/third-party/strelka.md +++ b/docs/5-integrations/extensions/third-party/strelka.md @@ -2,15 +2,15 @@ ## Strelka Extension Pricing -Note that usage of ext-strelka will incur usage of Artifact Exporting (applied to processed artifacts at a rate of $0.02/GB) as well as webhook data received in LimaCharlie and the related costs on top of the ext-strelka specific pricing. +Use of ext-strelka also uses Artifact Exporting, at a rate of $0.02/GB for the processed artifacts. It also causes webhook data to arrive in LimaCharlie. These related costs are added to the specific price of ext-strelka. [Strelka](https://github.com/target/strelka) is a real-time file scanning system used for threat hunting, threat detection, and incident response. -The Strelka extension receives files using Artifacts by specifying an `artifact_id` in the `run_on` request. The extension will then process the file and return the results to the caller as well as send the results to its related Sensor. +The Strelka extension receives files as Artifacts. Give an `artifact_id` in the `run_on` request. The extension then processes the file and returns the results to the caller. It also sends the results to its related Sensor. ## Configuration -Example rule that processes all Artifacts ingested with the type `zeek-extract`: +Example rule that processes all Artifacts ingested with the type `zeek-extract`: **Detect:** @@ -34,7 +34,7 @@ value: zeek-extract ## Usage -If you use the LimaCharlie [Zeek](zeek.md) extension, a good use case would be to trigger a Zeek analysis upon ingestion of a PCAP artifact, which will generate the necessary Zeek artifacts to trigger the Strelka extension in the above example. +If you use the LimaCharlie [Zeek](zeek.md) extension, you can start a Zeek analysis when LimaCharlie ingests a PCAP artifact. The analysis generates the Zeek artifacts that trigger the Strelka extension in the example above. **Detect:** diff --git a/docs/5-integrations/extensions/third-party/threatlocker.md b/docs/5-integrations/extensions/third-party/threatlocker.md index d9d109afc..5cdd56605 100644 --- a/docs/5-integrations/extensions/third-party/threatlocker.md +++ b/docs/5-integrations/extensions/third-party/threatlocker.md @@ -1,20 +1,22 @@ # ThreatLocker -[ThreatLocker](https://threatlocker.com) is an Application Control platform whose **approval-request queue** — end-users asking for an unknown binary to be allowed — is the single biggest source of operator toil in any rollout. +[ThreatLocker](https://threatlocker.com) is an Application Control platform. Its **approval-request queue** is the largest source of manual work in a rollout. In this queue, end users ask for permission to run an unknown binary. -The ThreatLocker LimaCharlie Extension is a thin proxy over the [ThreatLocker Portal API](https://portalapi.g.threatlocker.com/swagger). It pairs with the [ThreatLocker adapter](../../../2-sensors-deployment/adapters/types/threatlocker.md), which delivers approval-request events into LimaCharlie: an AI agent (or a Playbook) reads each event, calls this extension to enrich it against the Portal API (matching built-in app, computer/group context, existing policies), then calls this extension again with the decision — **permit**, **reject**, or **ignore**. The extension itself makes no decisions; it forwards the JSON body verbatim and returns the Portal response verbatim. +The ThreatLocker LimaCharlie Extension is a thin proxy over the [ThreatLocker Portal API](https://portalapi.g.threatlocker.com/swagger). It works with the [ThreatLocker adapter](../../../2-sensors-deployment/adapters/types/threatlocker.md), which delivers approval-request events into LimaCharlie. + +An AI agent or a Playbook reads each event and calls this extension to enrich the event against the Portal API. The enrichment matches the built-in app, the computer and group context, and the existing policies. The agent then calls this extension again with the decision: **permit**, **reject**, or **ignore**. The extension makes no decisions. It forwards the JSON body verbatim and returns the Portal response verbatim. ## Setup ### 1. Create a Portal API token -In the ThreatLocker Portal, navigate to **Administration → API Users** and create a new API user. Copy the resulting **API token** — you will need it in the next step. ThreatLocker shows the token only once. +In the ThreatLocker Portal, go to **Administration → API Users** and create a new API user. Copy the **API token**. You need the token in the next step. ThreatLocker shows the token one time only. ### 2. Find your instance letter -ThreatLocker hosts each tenant on a lettered instance (`b`, `c`, `d`, …, `g`, `h`, …) and API tokens are scoped to the instance that minted them. To find yours, click the **Help** button in the top-right corner of any Portal page and read the letter in parentheses next to **ThreatLocker Access** (e.g. `ThreatLocker Access (G)` → `instance_letter: g`). +ThreatLocker hosts each tenant on a lettered instance (`b`, `c`, `d`, …, `g`, `h`, …). An API token is scoped to the instance that made it. To find your letter, click the **Help** button in the top-right corner of any Portal page. Read the letter in parentheses next to **ThreatLocker Access**. For example, `ThreatLocker Access (G)` gives `instance_letter: g`. -> ⚠️ **A token from one instance returns `403 TOKEN_REVOKED` on every other instance.** The API does not distinguish "wrong instance" from a genuinely revoked token. If you are confident the token is active and still see `TOKEN_REVOKED`, double-check the instance letter before assuming the token was revoked. +> ⚠️ **A token from one instance returns `403 TOKEN_REVOKED` on every other instance.** The API does not show a difference between a wrong instance and a revoked token. If you are sure that the token is active but you still see `TOKEN_REVOKED`, check the instance letter. Check it before you decide that the token is revoked. ### 3. Subscribe to the extension @@ -30,31 +32,31 @@ In **Extensions → ext-threatlocker → Configuration**, fill in: | Field | Required | Value | | --- | --- | --- | -| `api_token` | yes | Reference to the secret created in step 4, e.g. `hive://secret/threatlocker-api-token`. | -| `instance_letter` | yes | The single lowercase letter from step 2, e.g. `g`. | -| `managed_organization_id` | no | UUID of the managed (child) organization. Sent as the `ManagedOrganizationId` header. Used by MSP **parent** tokens to scope every call to a specific child tenant. | +| `api_token` | yes | Reference to the secret that you created in step 4, for example `hive://secret/threatlocker-api-token`. | +| `instance_letter` | yes | The one lowercase letter from step 2, for example `g`. | +| `managed_organization_id` | no | UUID of the managed (child) organization. The extension sends it as the `ManagedOrganizationId` header. MSP **parent** tokens use it to scope each call to one child tenant. | -The API token is sent **verbatim** in the `Authorization` header — there is no `Bearer` prefix and no OAuth flow. The instance letter is validated at save time; everything else is rejected at request time by the Portal API. +The extension sends the API token **verbatim** in the `Authorization` header. There is no `Bearer` prefix and no OAuth flow. The extension validates the instance letter when you save. The Portal API rejects all other bad values at request time. ## Actions -The extension exposes thirteen actions. All `POST` actions take a single `body` parameter — the JSON object forwarded verbatim as the Portal API request body. `GET` actions take typed parameters: an `id` for single-id endpoints, or named flags for the computer-group inspector. +The extension gives thirteen actions. Each `POST` action takes one `body` parameter — the JSON object that the extension forwards verbatim as the request body for the Portal API. `GET` actions take typed parameters: an `id` for single-id endpoints, or named flags for the computer-group inspector. -The body field set per endpoint is **not shadowed** by the extension — the Portal API surface is large and changes over time, so the extension stays out of the way. Refer to the ThreatLocker Portal Swagger spec (visit `https://portalapi..threatlocker.com/swagger`) for the exact field set per endpoint. +The extension does **not** shadow the set of body fields for each endpoint. The Portal API is large and changes with time, so the extension does not constrain the body. For the exact set of fields for each endpoint, see the ThreatLocker Portal Swagger spec at `https://portalapi..threatlocker.com/swagger`. ### Approval-request reads #### `approval_request_search` -`POST ApprovalRequest/ApprovalRequestGetByParameters` — list approval requests matching a filter. +`POST ApprovalRequest/ApprovalRequestGetByParameters` — list the approval requests that match a filter. | Field | Type | Notes | | --- | --- | --- | -| `body` | object | **Required.** Forwarded as the JSON request body. Common fields: `statusId` (1=pending, 4=approved, …), `searchText`, `requestTypeId`, `actionType` (array), `pageNumber`, `pageSize`, `orderBy`, `isAscending`. | +| `body` | object | **Required.** The extension forwards it as the JSON request body. Common fields: `statusId` (1=pending, 4=approved, …), `searchText`, `requestTypeId`, `actionType` (array), `pageNumber`, `pageSize`, `orderBy`, `isAscending`. | #### `approval_request_get` -`GET ApprovalRequest/ApprovalRequestGetById` — fetch a single approval request. +`GET ApprovalRequest/ApprovalRequestGetById` — fetch one approval request. | Field | Type | Notes | | --- | --- | --- | @@ -64,7 +66,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `application_get_matching` -`POST Application/ApplicationGetMatchingList` — the **primary enrichment call**. Given a file (`sha256`, path, certificates, …) returns the ThreatLocker built-in (or custom) applications it matches. An empty result is the "no built-in match" answer — meaning the file is unknown to ThreatLocker's curated catalog and an AI policy decision should weigh that accordingly. +`POST Application/ApplicationGetMatchingList` — the **primary enrichment call**. For a file (`sha256`, path, certificates, …), it returns the built-in or custom ThreatLocker applications that the file matches. An empty result means that there is no built-in match. The file is then unknown to the curated catalog of ThreatLocker, and an AI policy decision must give weight to this fact. | Field | Type | Notes | | --- | --- | --- | @@ -72,7 +74,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `application_get` -`GET Application/ApplicationGetById` — full details for a single application. +`GET Application/ApplicationGetById` — full details for one application. | Field | Type | Notes | | --- | --- | --- | @@ -80,7 +82,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `application_get_research` -`GET Application/ApplicationGetResearchDetailsById` — ThreatLocker's curated threat-research info for an application (Living-Off-The-Land flags, common abuse, reputation notes). Useful when deciding whether the matching app is sensitive enough to warrant a denial. +`GET Application/ApplicationGetResearchDetailsById` — the curated threat-research information from ThreatLocker for an application (Living-Off-The-Land flags, common abuse, reputation notes). Use it when you decide if the matched application is sensitive enough to reject. | Field | Type | Notes | | --- | --- | --- | @@ -90,7 +92,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `computer_get` -`GET Computer/ComputerGetForEditById` — fetch a single computer's full record (group, OS, tags, last check-in). The fastest path from an approval-request event's `computerId` to the device context. +`GET Computer/ComputerGetForEditById` — fetch the full record of one computer (group, OS, tags, last check-in). This is the fastest path from the `computerId` in an approval-request event to the device context. | Field | Type | Notes | | --- | --- | --- | @@ -98,7 +100,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `computer_search` -`POST Computer/ComputerGetByAllParameters` — free-text or group/mode-scoped computer search. +`POST Computer/ComputerGetByAllParameters` — computer search by free text, or scoped by group or mode. | Field | Type | Notes | | --- | --- | --- | @@ -108,7 +110,7 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `computer_group_list_for_permit` -`GET ComputerGroup/ComputerGroupGetForPermitApplication` — list the computer groups eligible to receive an approval/permit decision. Start here when picking the scope to attach a new permit policy to. +`GET ComputerGroup/ComputerGroupGetForPermitApplication` — list the computer groups that can receive an approval or permit decision. Start with this action when you select the scope for a new permit policy. | Field | Type | Notes | | --- | --- | --- | @@ -116,29 +118,29 @@ The body field set per endpoint is **not shadowed** by the extension — the Por #### `computer_group_get_full` -`GET ComputerGroup/ComputerGroupGetGroupAndComputer` — rich one-shot inspector: a group plus (optionally) every policy attached to it and every computer in it, in a single round trip. +`GET ComputerGroup/ComputerGroupGetGroupAndComputer` — one-call inspector. It returns a group and, optionally, each policy attached to the group and each computer in the group, in one round trip. | Field | Type | Notes | | --- | --- | --- | | `computer_group_id` | string | **Required.** `ComputerGroupId` (UUID). | | `os_type` | int | `0` = All, `1` = Windows, `2` = Mac, `3` = Linux. | -| `include_all_policies` | bool | Include policies attached to the group. **Recommended** — defaults to `true`. | -| `include_all_computers` | bool | Include computers in the group. **Recommended** — defaults to `true`. | +| `include_all_policies` | bool | Include the policies attached to the group. **Recommended** — the default is `true`. | +| `include_all_computers` | bool | Include the computers in the group. **Recommended** — the default is `true`. | | `include_global` | bool | Include the global "All Computers" group. | -| `include_organizations` | bool | Include parent/child orgs. | +| `include_organizations` | bool | Include parent and child orgs. | | `include_parent_groups` | bool | Include parent groups. | | `include_logged_in_objects` | bool | Include logged-in objects. | | `include_access_devices` | bool | Include access devices. | | `include_removed_computers` | bool | Include removed computers. | | `portal_module_type_id` | int | Optional `PortalModuleTypeId`. | -With `include_all_policies=true` and `include_all_computers=true` this endpoint answers, in a single call, *"who else is in this group, what policies are already attached, and would this new permit policy collide with any of them?"* +Set `include_all_policies=true` and `include_all_computers=true` to get the full group context in one call. The response shows the other computers in the group and the policies that are already attached. Use it to find a conflict between those policies and a new permit policy. ### Policy reads #### `policy_get` -`GET Policy/PolicyGetById` — fetch one policy's full record by id. The Portal API has no list-policies-by-parameters endpoint; iterate via `computer_group_get_full` with `include_all_policies=true` and resolve each policy by id with `policy_get`. +`GET Policy/PolicyGetById` — fetch the full record of one policy by id. The Portal API has no endpoint that lists policies by parameters. Instead, call `computer_group_get_full` with `include_all_policies=true`, then resolve each policy by id with `policy_get`. | Field | Type | Notes | | --- | --- | --- | @@ -146,35 +148,35 @@ With `include_all_policies=true` and `include_all_computers=true` this endpoint ### Decisions -The three write actions close the loop on an approval request — they are the only actions in this extension that mutate ThreatLocker state. +The three write actions complete an approval request. They are the only actions in this extension that change the state of ThreatLocker. #### `approval_request_permit` -`POST ApprovalRequest/ApprovalRequestPermitApplication` — **approve**. Creates (or updates) a permit policy and lets the requestor's blocked application through. +`POST ApprovalRequest/ApprovalRequestPermitApplication` — **approve**. It creates or updates a permit policy and lets the blocked application of the requestor run. | Field | Type | Notes | | --- | --- | --- | -| `body` | object | **Required.** Full `PermitApplicationDto` body. Set `body.adminNotes` to the AI's reasoning — it lands in the Portal audit trail so a human can later reconstruct *why* an automated decision was made. | +| `body` | object | **Required.** The full `PermitApplicationDto` body. Set `body.adminNotes` to the reasoning of the AI. The value goes into the Portal audit trail, so a person can later find *why* an automated decision was made. | #### `approval_request_reject` -`POST ApprovalRequest/ApprovalRequestUpdateForReject` — **deny**. Notifies the requestor with a reason. +`POST ApprovalRequest/ApprovalRequestUpdateForReject` — **deny**. It sends a reason to the requestor. | Field | Type | Notes | | --- | --- | --- | -| `body` | object | **Required.** Set `body.rejectReason` (the requestor-visible message) and `body.responseReason` (the internal audit-trail note). | +| `body` | object | **Required.** Set `body.rejectReason` (the message that the requestor sees) and `body.responseReason` (the internal note for the audit trail). | #### `approval_request_ignore` -`POST ApprovalRequest/ApprovalRequestUpdateForIgnore` — **soft-dismiss**. Leaves the request in the queue for human review without notifying the requestor. Use this when the AI cannot confidently permit or reject. +`POST ApprovalRequest/ApprovalRequestUpdateForIgnore` — **soft-dismiss**. It keeps the request in the queue for human review and does not notify the requestor. Use this action when the AI cannot permit or reject with confidence. | Field | Type | Notes | | --- | --- | --- | -| `body` | object | **Required.** Forwarded as the JSON request body. | +| `body` | object | **Required.** The extension forwards it as the JSON request body. | ## Detection & Response -Example response action that enriches a ThreatLocker approval-request event delivered by the [adapter](../../../2-sensors-deployment/adapters/types/threatlocker.md) by calling `application_get_matching` on the file's SHA-256: +This example response action enriches a ThreatLocker approval-request event that the [ThreatLocker adapter](../../../2-sensors-deployment/adapters/types/threatlocker.md) delivers. It calls `application_get_matching` with the SHA-256 hash of the file: ```yaml - action: extension request @@ -188,18 +190,18 @@ Example response action that enriches a ThreatLocker approval-request event deli ``` > **Wrap literal strings in `{{ "..." }}`.** -> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is interpreted as a [gjson](https://github.com/tidwall/gjson) path against the event and, if it doesn't resolve, the key is silently dropped from the payload. +> Values under `extension request` are evaluated as templates. A bare string without `{{ }}` is read as a [gjson](https://github.com/tidwall/gjson) path into the event. If the path does not resolve, the key is removed from the payload without a message. -`extension request` actions are fire-and-forget — the rule engine does not surface the response back into the rule's evaluation context, so the enrichment result is not available to a subsequent action in the same rule. Workflows that chain (enrich → decide → write back) belong in a [Playbook](../limacharlie/playbook.md) or an AI agent, which can hold the intermediate results between calls. +`extension request` actions do not return a result to the rule. The rule engine does not put the response into the evaluation context of the rule. Thus the enrichment result is not available to a later action in the same rule. For a chain of steps (enrich, decide, write back), use a [Playbook](../limacharlie/playbook.md) or an AI agent. These can hold the intermediate results between calls. ## Authentication and tenancy -- The Portal API token is sent **verbatim** in the `Authorization` header — there is no `Bearer` prefix. Do not paste the token with a prefix; the API will reject it. -- The token is scoped to the instance that minted it. `403 TOKEN_REVOKED` means either the token was revoked **or** the wrong `instance_letter` was configured. Verify the instance letter first. -- For **MSPs**, a single parent-tenant token can be used to drive multiple child organizations by setting `managed_organization_id` to the child organization's UUID. The header `ManagedOrganizationId` is then attached to every request and the Portal scopes the response accordingly — one extension subscription per parent tenant, not per child. +- The extension sends the Portal API token **verbatim** in the `Authorization` header. There is no `Bearer` prefix. Do not add a prefix to the token, because the API rejects it. +- The token is scoped to the instance that made it. `403 TOKEN_REVOKED` means that the token was revoked **or** that the `instance_letter` is wrong. Check the instance letter first. +- For **MSPs**, one parent-tenant token can drive many child organizations. Set `managed_organization_id` to the UUID of the child organization. The extension then adds the `ManagedOrganizationId` header to each request, and the Portal scopes the response to that child. You need one extension subscription for each parent tenant, not for each child. ## Notes -- The extension caches the underlying HTTP client per `(org, instance_letter, token, managed_organization_id)`. Rotating the secret in Secrets Manager evicts the cached client on the next surfaced `403 TOKEN_REVOKED`. -- No request or response transformation is performed — what ThreatLocker returns is what the caller sees. New Portal fields don't require a code change. -- Read actions are safe to retry. Write actions (`approval_request_permit` / `_reject` / `_ignore`) are not idempotent on the Portal side — re-firing them on the same `approvalRequestId` after the first success will surface a Portal error. +- The extension caches the HTTP client for each `(org, instance_letter, token, managed_organization_id)`. When you rotate the secret in Secrets Manager, the extension removes the cached client at the next `403 TOKEN_REVOKED`. +- The extension does not transform the request or the response. The caller sees exactly what ThreatLocker returns. New Portal fields need no change to the code. +- You can retry read actions safely. Write actions (`approval_request_permit` / `_reject` / `_ignore`) are not idempotent in the Portal. If you send one again for the same `approvalRequestId` after the first success, the Portal returns an error. diff --git a/docs/5-integrations/extensions/third-party/twilio.md b/docs/5-integrations/extensions/third-party/twilio.md index 1d09bc041..c6734c389 100644 --- a/docs/5-integrations/extensions/third-party/twilio.md +++ b/docs/5-integrations/extensions/third-party/twilio.md @@ -2,23 +2,23 @@ ## Overview -The [Twilio](https://www.twilio.com/) Extension allows you to send messages within Twilio. It requires you to setup the Twilio authentication in the **Integrations** section of your Organization. +The [Twilio](https://www.twilio.com/) Extension lets you send messages with Twilio. You must set up the Twilio authentication in the **Integrations** section of your Organization. -See Twilio's [SMS send-messages reference](https://www.twilio.com/docs/sms/send-messages) for more detail. +For more detail, see the Twilio [SMS send-messages reference](https://www.twilio.com/docs/sms/send-messages). ## Setup -To start leveraging the Twilio extension, first subscribe to the `ext-twilio` add-on that can be accessed from the LimaCharlie **Marketplace**. +To use the Twilio extension, first subscribe to the `ext-twilio` add-on in the LimaCharlie **Marketplace**. ![twilio](../../../assets/images/twilio.png) -After you have subscribed to the extension, setup the Twilio authentication in the `Secrets Manager` section of your organization. +After you subscribe to the extension, set up the Twilio authentication in the `Secrets Manager` section of your organization. -Authentication in Twilio uses two components--a SID and a token. The LimaCharlie Twilio secret will combine both components in a single field like `SID/TOKEN`. +Twilio authentication uses two parts: a SID and a token. The LimaCharlie Twilio secret combines both parts in one field, in the form `SID/TOKEN`. ### Detection & Response -Example Response portion of a rule that sends a message out via Twilio as the response action: +This example is the Response part of a rule. The response action sends a message with Twilio: ```yaml - action: extension request @@ -30,4 +30,4 @@ Example Response portion of a rule that sends a message out via Twilio as the r to: '{{ "+10123456789" }}' ``` -*Note that the* `{{ .event }}` *in the example above is the actual text that would be sent to the number you specify.* +*The* `{{ .event }}` *in the example above is the text that the extension sends to the number that you specify.* diff --git a/docs/5-integrations/extensions/third-party/velociraptor.md b/docs/5-integrations/extensions/third-party/velociraptor.md index 68feecccd..67cac45e8 100644 --- a/docs/5-integrations/extensions/third-party/velociraptor.md +++ b/docs/5-integrations/extensions/third-party/velociraptor.md @@ -2,16 +2,16 @@ ## Overview -[Velociraptor](https://github.com/Velocidex/Velociraptor) is an open source endpoint visibility tool that includes power digital forensic, incident response, and incident triage capabilities. LimaCharlie can be used to deploy Velociraptor at scale, allowing for easy artifact collection and incident analysis. +[Velociraptor](https://github.com/Velocidex/Velociraptor) is an open source endpoint visibility tool. It includes digital forensic, incident response, and incident triage functions. Use LimaCharlie to deploy Velociraptor at scale for artifact collection and incident analysis. The interface defines 2 main actions: -1. **Show Artifact** - allows you to inspect the VQL artifacts available for collection -2. **Collect Artifact** - allows you to run an artifact collection on one or more endpoints +1. **Show Artifact** - lets you inspect the VQL artifacts that are available for collection +2. **Collect Artifact** - lets you run an artifact collection on one or more endpoints ### Show Artifact -Simply choose an artifact from the list to inspect it's contents. +Choose an artifact from the list to inspect its contents. ![velociraptor ext 1](../../../assets/images/velociraptor-ext-1.png) @@ -21,41 +21,41 @@ Result of the action ### Collect Artifact -This allows you to collect one or more Velociraptor [Artifacts](https://docs.velociraptor.app/artifact_references/) from one or more endpoints via the Endpoint Agent. +This action collects one or more Velociraptor [Artifacts](https://docs.velociraptor.app/artifact_references/) from one or more endpoints through the Endpoint Agent. ![velociraptor 3](../../../assets/images/velociraptor-3.png) -Velociraptor will generate a ZIP file with all collected data, which is automatically ingested into LimaCharlie's Artifact system for download. +Velociraptor makes a ZIP file with all the collected data. LimaCharlie ingests the file automatically into its Artifact system, where you can download it. #### Arguments -- **Artifacts** - Select one or more Velociraptor artifacts you wish to collect -- **Sensor Selector** - Select either a single sensor by selecting it's Sensor ID from the dropdown or use a [Sensor Selector Expression](../../../8-reference/sensor-selector-expressions.md) to cast a wider net such as `plat==windows` +- **Artifacts** - Select one or more Velociraptor artifacts to collect +- **Sensor Selector** - Select one sensor by its Sensor ID in the dropdown. You can also use a [Sensor Selector Expression](../../../8-reference/sensor-selector-expressions.md) to target more sensors, such as `plat==windows` - **Arguments (optional)** - See below -- **Collection Seconds (optional)** - Define how long (in seconds) the Extension will wait for a targeted endpoint to come online and be processed for collection. -- **Retention Days (optional)** - Define how long the collected artifact will be retained by the platform. -- **Ignore SSL Errors (optional)** - Tells the endpoint to ignore SSL errors while running and collecting. This can be useful if the endpoint is behind a MITM proxy or firewall performing SSL interception. +- **Collection Seconds (optional)** - Set the wait time in seconds. The Extension waits for a target endpoint to come online and be processed for collection. +- **Retention Days (optional)** - Set the number of days that the platform keeps the collected artifact. +- **Ignore SSL Errors (optional)** - Tells the endpoint to ignore SSL errors during the collection. Use this option if the endpoint is behind a MITM proxy or a firewall that does SSL interception. ##### Arguments (optional) -These are optional arguments (or parameters) passed directly to the Velociraptor Artifact. Arguments use the format `"Key=[\"value\"]"` for list parameters and `"Key=Y"` for boolean parameters. +The extension passes these optional arguments (or parameters) directly to the Velociraptor Artifact. Use the format `"Key=[\"value\"]"` for list parameters and `"Key=Y"` for boolean parameters. -For example, to run a [Linux.Triage.UAC](https://triage.velocidex.com/docs/linux.triage.uac/) collection targeting all categories, specify: +For example, to run a [Linux.Triage.UAC](https://triage.velocidex.com/docs/linux.triage.uac/) collection for all categories, specify: ```text "Targets=[\"_All\"]" ``` -If `_All` returns more data than needed, you can define a single target instead. See the [UAC target reference](https://triage.velocidex.com/docs/linux.triage.uac/) for the full list of available options. +If `_All` returns more data than you need, set one target instead. For the full list of options, see the [UAC target reference](https://triage.velocidex.com/docs/linux.triage.uac/). For [Windows.KapeFiles.Targets](https://github.com/Velocidex/velociraptor/blob/master/artifacts/definitions/Windows/KapeFiles/Targets.yaml), you can use `"HighLevelTargets=[\"_KapeTriage\"]"`. ## Monitoring Collections -You are able to track Velociraptor hunts by viewing the Timeline for the `ext-velociraptor` sensor. +To track Velociraptor hunts, view the Timeline for the `ext-velociraptor` sensor. ![velociraptor ext 4](../../../assets/images/velociraptor-ext-4.png) -Once you see `artifact_uploaded` in the timeline, you can expect to find the artifact on the "Artifacts" screen. +After you see `artifact_uploaded` in the timeline, you can find the artifact on the "Artifacts" screen. ![velociraptor ext 5](../../../assets/images/velociraptor-ext-5.png) @@ -72,11 +72,11 @@ The `collect` action returns a `job_id`, for example: } ``` -This `job_id` is the extension's correlation key for the collection request. It is **not** a payload or artifact ID. The collected data is ingested as a LimaCharlie **Artifact**, which has its own artifact ID. There are two ways to map one to the other. +This `job_id` is the correlation key of the extension for the collection request. It is **not** a payload or artifact ID. LimaCharlie ingests the collected data as an **Artifact**, which has its own artifact ID. There are two ways to map one ID to the other. ### 1. Webhook events (recommended for automation) -With an `ext-velociraptor` webhook output configured, the extension emits a lifecycle of events as a collection progresses, all carrying the `job_id`: +If you configure an `ext-velociraptor` webhook output, the extension sends a set of lifecycle events during the collection. Each event contains the `job_id`: | Event | Key fields | When | |-------|------------|------| @@ -86,15 +86,15 @@ With an `ext-velociraptor` webhook output configured, the extension emits a life | `velociraptor_collection` | `job_id`, `sid`, `collection`, `collection_artifact`, `inv_id` | Collection ingested and parsed | | `job_finished` | `job_id` | All taskings for the job are complete | -The `collection_artifact` field in the `velociraptor_collection` event is the LimaCharlie **artifact ID** for that `job_id`. This is the definitive `job_id` to artifact mapping. +The `collection_artifact` field in the `velociraptor_collection` event is the LimaCharlie **artifact ID** for that `job_id`. This is the definitive map from `job_id` to artifact. ### 2. Artifact `original_path` -The ingested collection ZIP is named so that its path ends in `_.zip`. In the Artifact Collection — or in a D&R rule via `{{ .event.original_path }}` — you can match or filter artifacts by their `job_id`. +The path of the ingested collection ZIP ends in `_.zip`. In the Artifact Collection — or in a D&R rule with `{{ .event.original_path }}` — you can match or filter artifacts by their `job_id`. ## Automating Collection Retrieval -Let's say you wanted to automatically fetch new Velociraptor collections and send somewhere else for storage/processing. This can be accomplished via rules which watch for the artifact upload and send to a tailored output. +You can fetch new Velociraptor collections automatically and send them to another system for storage or processing. Use rules that watch for the artifact upload and send it to a tailored output. Example D&R rule @@ -119,15 +119,15 @@ value: velociraptor name: VR artifact ingested ``` -To see how you could use something like this to automate post-processing of Velociraptor triage collections, check out this [open source example](https://github.com/shortstack/lcvr-to-timesketch) which sends KAPE Triage acquisitions to a webhook which then retrieves the collection for processing via [Plaso](https://github.com/log2timeline/plaso/) and into [Timesketch](https://github.com/google/timesketch). +This [open source example](https://github.com/shortstack/lcvr-to-timesketch) shows how to automate the post-processing of Velociraptor triage collections. It sends KAPE Triage acquisitions to a webhook. The webhook then gets the collection, processes it with [Plaso](https://github.com/log2timeline/plaso/), and puts it into [Timesketch](https://github.com/google/timesketch). -To see how you can send Velociraptor data to BigQuery for further analysis, see this [tutorial](../../tutorials/velociraptor-bigquery.md). +To send Velociraptor data to BigQuery for more analysis, see the [Velociraptor to BigQuery tutorial](../../tutorials/velociraptor-bigquery.md). ## Using Velociraptor in D&R Rules -If you want to trigger a Velociraptor collection as a response to one of your detections, you can configure an extension request in the respond block of a rule. +To start a Velociraptor collection as a response to one of your detections, configure an extension request in the respond block of a rule. -This example will kick off the KAPE files Velociraptor artifact to collect event logs from the system involved in the detection. +This example starts the KAPE files Velociraptor artifact. The artifact collects the event logs from the system in the detection. ```yaml - action: extension request @@ -145,9 +145,9 @@ This example will kick off the KAPE files Velociraptor artifact to collect event ### Migrating D&R Rule from legacy Service to new Extension -***Note: LimaCharlie has migrated from Services to Extensions. Legacy services are no longer supported.*** +***Note: LimaCharlie migrated from Services to Extensions. Legacy services are not supported.*** -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to assess if any rules reference legacy Velociraptor service, preview the change and execute the conversion required in the rule "response". +The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) shows if a rule refers to the legacy Velociraptor service. It also previews the change and does the conversion in the "response" part of the rule. Command line to preview Velociraptor rule conversion: @@ -155,9 +155,9 @@ Command line to preview Velociraptor rule conversion: limacharlie extension convert_rules --name ext-velociraptor ``` -A dry-run response (default) will display the rule name being changed, a JSON of the service request rule and a JSON of the incoming extension request change. +A dry run is the default. It shows the name of the rule that changes, a JSON of the service request rule, and a JSON of the new extension request. -To execute the change in the rule, explicitly set `--dry-run` flag to `--no-dry-run` +To make the change in the rule, set the `--dry-run` flag to `--no-dry-run` Command line to execute Velociraptor rule conversion: diff --git a/docs/5-integrations/extensions/third-party/yara.md b/docs/5-integrations/extensions/third-party/yara.md index 1f5baaa8d..1dc756eab 100644 --- a/docs/5-integrations/extensions/third-party/yara.md +++ b/docs/5-integrations/extensions/third-party/yara.md @@ -1,6 +1,6 @@ # YARA -The [YARA](https://github.com/Yara-Rules/rules) Extension is designed to help you with all aspects of YARA scanning. It takes what is normally a manual piecewise process, provides a framework and automates it. Once configured, YARA scans can be run on demand for a particular endpoint or continuously in the background across your entire fleet. +The [YARA](https://github.com/Yara-Rules/rules) Extension helps you with all parts of YARA scanning. YARA scanning is usually a manual process in separate steps. The extension gives a framework for the process and automates it. After you configure it, you can run YARA scans on demand for one endpoint, or continuously in the background across your fleet. Yara configurations are synchronized with sensors every few minutes. @@ -12,19 +12,19 @@ There are three main sections to the YARA job: ## Where Does My YARA Scan? -Automated YARA scanners in LimaCharlie will run on all files loaded in memory (e.g. exe, dll, etc), and on the memory itself. +The automated YARA scanners in LimaCharlie scan all the files that are loaded in memory (for example exe, dll), and the memory itself. -Files on disk can be scanned using a Sensor command. You can trigger a Manual Scan that's run on-demand by: +A Sensor command scans the files on disk. To start a manual scan on demand, use one of these methods: -- Clicking the Run YARA scan button on the sensor details page, -- Clicking the Scan button on the YARA Scanners page -- Using the console -- Within the Response section of a rule (sample below) -- Using the LimaCharlie API +- Click the Run YARA scan button on the sensor details page +- Click the Scan button on the YARA Scanners page +- Use the console +- Use the Response section of a rule (sample below) +- Use the LimaCharlie API ## Rules -This is where you define your YARA rule(s). You can copy and paste your YARA rules into the `Rule` box, or you can define sources via the [ext-yara-manager](../limacharlie/yara-manager.md). Sources can be either direct links (URLs) to a given YARA rule (or directory of rules) or [ARLs](../../../8-reference/authentication-resource-locator.md) to a YARA rule. +In this section you define your YARA rules. Copy your YARA rules into the `Rule` box, or define sources with the [ext-yara-manager](../limacharlie/yara-manager.md). A source is a direct link (URL) to one YARA rule or to a directory of rules, or an [ARL](../../../8-reference/authentication-resource-locator.md) to a YARA rule. ![yara 1](../../../assets/images/yara-1.png) @@ -32,15 +32,15 @@ This is where you define your YARA rule(s). You can copy and paste your YARA rul ## Scanners -Scanners define which sets of sensors should be scanned with which sets of YARA rules. +A scanner defines which sets of sensors to scan with which sets of YARA rules. -Filter Tags are tags that must ALL be present on a sensor for it to match (AND condition), while the platform of the sensor much match one of the platforms in the filter (OR condition). +A sensor matches only if it has ALL of the Filter Tags (AND condition). The platform of the sensor must match one of the platforms in the filter (OR condition). -To apply YARA rules to scan an endpoint (or set of endpoints), you must select the platform or tags, and then add the YARA rules you would like to run. +To scan an endpoint or a set of endpoints with YARA rules, first select the platform or the tags. Then add the YARA rules that you want to run. ## Using Yara in D&R Rules -If you want to trigger a Yara scan as a response to one of your detections, you can configure an extension request in the respond block of a rule. A Yara scan request can be executed with a blank selector OR Sensor ID. However, one of them must be specified. +To start a Yara scan as a response to one of your detections, configure an extension request in the respond block of a rule. A Yara scan request can run with a blank selector OR a blank Sensor ID, but you must specify one of them. ```yaml - action: extension request @@ -55,9 +55,9 @@ If you want to trigger a Yara scan as a response to one of your detections, you ## Migrating D&R Rule from legacy Service to new Extension -***Note: LimaCharlie has migrated from Services to Extensions. Legacy services are no longer supported.*** +***Note: LimaCharlie migrated from Services to Extensions. Legacy services are not supported.*** -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to assess if any rules reference legacy Yara service, preview the change and execute the conversion required in the rule "response". +The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) shows if a rule refers to the legacy Yara service. It also previews the change and does the conversion in the "response" part of the rule. Command line to preview Yara rule conversion: @@ -65,9 +65,9 @@ Command line to preview Yara rule conversion: limacharlie extension convert_rules --name ext-yara ``` -A dry-run response (default) will display the rule name being changed, a JSON of the service request rule and a JSON of the incoming extension request change. +A dry run is the default. It shows the name of the rule that changes, a JSON of the service request rule, and a JSON of the new extension request. -To execute the change in the rule, explicitly set `--dry-run` flag to `--no-dry-run` +To make the change in the rule, set the `--dry-run` flag to `--no-dry-run` Command line to execute Yara rule conversion: diff --git a/docs/5-integrations/extensions/third-party/zeek.md b/docs/5-integrations/extensions/third-party/zeek.md index 081d790ff..a1b90a8ec 100644 --- a/docs/5-integrations/extensions/third-party/zeek.md +++ b/docs/5-integrations/extensions/third-party/zeek.md @@ -2,19 +2,19 @@ ## Zeek Extension Pricing -While it is Free to enable the Zeek extension, pricing is applied to processed PCAPs at a rate of $0.02/GB. +The Zeek extension is free to enable, but processed PCAPs cost $0.02/GB. -[Zeek](https://zeek.org/) is a comprehensive platform for network traffic analysis and intrusion detection. +[Zeek](https://zeek.org/) is a platform for network traffic analysis and intrusion detection. -Once enabled, this extension allows you to generate Zeek logs from packet capture (PCAP) files collected via Artifacts. The resulting Zeek log files are subsequently parsed and pushed into the `ext-zeek` Sensor timeline as JSON. You can create detection & response rules to automate based on Zeek log data. +After you enable this extension, it generates Zeek logs from the packet capture (PCAP) files that Artifacts collects. The Zeek log files are then parsed and sent into the `ext-zeek` Sensor timeline as JSON. You can create detection & response rules that act on the Zeek log data. -LimaCharlie will automatically kick off Zeek based on the artifact ID provided in a rule action. +LimaCharlie starts Zeek automatically for the artifact ID that a rule action gives. ## Configuration -To enable the Zeek extension, navigate to the [Zeek extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-zeek) in the marketplace. Select the Organization you wish to enable the extension for, and select Subscribe. +To enable the Zeek extension, go to the [Zeek extension page](https://app.limacharlie.io/add-ons/extension-detail/ext-zeek) in the marketplace. Select the Organization for the extension, then select Subscribe. -When enabled, you may configure the response of a D&R rule to run Zeek against an artifact event. Here is an example D&R rule: +After you enable the extension, you can configure the response of a D&R rule to run Zeek on an artifact event. This is an example D&R rule: **Detect:** @@ -43,7 +43,7 @@ target: artifact_event /opt/zeek/bin/zeek -C LogAscii::use_json=T --no-checksums --readfile /path/to/your.pcap ``` -Upon running Zeek, several JSON log files are generated. The log files are parsed and pushed into the `ext-zeek` sensor timeline. +Zeek generates several JSON log files. The log files are parsed and sent into the `ext-zeek` sensor timeline. ![Screenshot 2024-02-20 1.04.52 PM.png](../../../assets/images/Screenshot-2024-02-20-1.04.52-PM.png) @@ -53,25 +53,25 @@ Upon running Zeek, several JSON log files are generated. The log files are parse #### Note: This is only available on Linux sensors -Enable PCAP collection on your Linux sensors via a PCAP capture rule within the artifact collection extension. +Enable PCAP collection on your Linux sensors with a PCAP capture rule in the artifact collection extension. -For example, if you have an interface `ens4` and would like to gather PCAPs of network traffic on that interface on TCP port 80, you would craft the following rule. +For example, to collect PCAPs of the network traffic on interface `ens4` on TCP port 80, make this rule. ![zeek 2](../../../assets/images/zeek-2.png) -Once ~30MB of traffic has been collected, a PCAP will be uploaded as an artifact in LimaCharlie. Subsequent PCAPs will continue to be uploaded as additional PCAPs as they hit the size threshold. +After about 30MB of traffic is collected, a PCAP is uploaded as an artifact in LimaCharlie. Each new PCAP is uploaded when it reaches the same size limit. -All PCAPs uploaded will trigger the [D&R rule below](#dr-rule). +Each uploaded PCAP triggers the [D&R rule below](#dr-rule). ### Via Manual PCAP Upload -If you have already generated a PCAP on a system or systems, you can manually ingest those as artifacts by running the following in your sensor console: +If you already generated a PCAP on one or more systems, you can ingest the PCAP as an artifact. Run this command in your sensor console: ```text artifact_get --file /path/to/your.pcap --type pcap ``` -This will trigger the [D&R rule below](#dr-rule). +This command triggers the [D&R rule below](#dr-rule). ### D&R Rule @@ -98,9 +98,9 @@ target: artifact_event ### Migrating D&R Rule from legacy Service to new Extension -***Note: LimaCharlie has migrated from Services to Extensions. Legacy services are no longer supported.*** +***Note: LimaCharlie migrated from Services to Extensions. Legacy services are not supported.*** -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a direct way to assess if any rules reference legacy zeek service, preview the change and execute the conversion required in the rule "response". +The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) shows if a rule refers to the legacy zeek service. It also previews the change and does the conversion in the "response" part of the rule. Command line to preview zeek rule conversion: @@ -108,9 +108,9 @@ Command line to preview zeek rule conversion: limacharlie extension convert_rules --name ext-zeek ``` -A dry-run response (default) will display the rule name being changed, a JSON of the service request rule and a JSON of the incoming extension request change. +A dry run is the default. It shows the name of the rule that changes, a JSON of the service request rule, and a JSON of the new extension request. -To execute the change in the rule, explicitly set `--dry-run` flag to `--no-dry-run` +To make the change in the rule, set the `--dry-run` flag to `--no-dry-run` Command line to execute zeek rule conversion: diff --git a/docs/5-integrations/extensions/using-extensions.md b/docs/5-integrations/extensions/using-extensions.md index 4f2f21a68..171951235 100644 --- a/docs/5-integrations/extensions/using-extensions.md +++ b/docs/5-integrations/extensions/using-extensions.md @@ -2,25 +2,25 @@ ## Components -Extensions can be interacted with using two main components: +You interact with Extensions through two main components: ### Configurations -Extension Configurations are records in [Hive](../../7-administration/config-hive/index.md). Each Extension has its configuration in the Hive record of the same name in the `extension_configuration` Hive. +Extension Configurations are records in [Hive](../../7-administration/config-hive/index.md). Each Extension keeps its configuration in the Hive record of the same name in the `extension_configuration` Hive. -These configurations are manipulated by simply storing the value in the record, LimaCharlie takes care of validating and notifying the Extension with the new value. +To change a configuration, store the new value in the record. LimaCharlie validates the value and sends it to the Extension. -Configurations are a great way of storing rarely-written settings for an Extension without the developer of the Extension having to manage secure storage for it. +Configurations store settings that change rarely. The developer of the Extension does not need to manage secure storage for these settings. -The structure of the configuration for a given Extension is published by the Extension via its "schema". +Each Extension publishes the structure of its configuration in its "schema". Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension schema --help`. ### Requests -Requests are, as the name implies, direct individual requests to an Extension. A request contains an "action" and a "payload" (JSON object) to be sent to the Extension. Some requests can be flagged to have the Extension impersonate the requester (identity and permissions) during execution. +A request is a direct, individual call to an Extension. A request contains an "action" and a "payload" (JSON object) for the Extension. You can flag some requests so that the Extension impersonates the requester (identity and permissions) during execution. -The "action" and "payload" entirely depends on the Extension it is destined to. The list of actions and individual payload structures available for an Extension is documented by each Extension using the "schema" they publish. +The "action" and the "payload" depend on the Extension that receives them. Each Extension documents its actions and payload structures in the "schema" that it publishes. Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension schema --help`. @@ -28,25 +28,25 @@ Schemas are available through the [Schema API](https://api.limacharlie.io/static ### Interactively -The LimaCharlie webapp automatically displays a machine-generated user interface for each Extension based on the schema it publishes. +The LimaCharlie web app shows a machine-generated user interface for each Extension. It builds this interface from the schema that the Extension publishes. ### Automation -[Detection & Response Rules](../../3-detection-response/index.md), the main automation mechanism in LimaCharlie can interact with Extensions using the `extension request` action in the Response component. +[Detection & Response Rules](../../3-detection-response/index.md) are the main automation mechanism in LimaCharlie. These rules interact with Extensions through the `extension request` action in the Response component. ### API -Extensions can be interacted with using a few different APIs: +More than one API interacts with Extensions: -- Getting the schema for an Extension: [https://api.limacharlie.io/static/swagger/#/Extension-Schema](https://api.limacharlie.io/static/swagger/#/Extension-Request) -- Making requests to an Extension: +- Get the schema for an Extension: [https://api.limacharlie.io/static/swagger/#/Extension-Schema](https://api.limacharlie.io/static/swagger/#/Extension-Request) +- Make requests to an Extension: -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions expand and customize a security environment. They integrate third-party tools, automate workflows, and add new capabilities. An organization subscribes to an Extension and grants it specific permissions on the infrastructure of the organization. An Extension can be private or public. A private Extension gives tailored use, and a public Extension gives broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. ## Programmatic Management !!! info "Prerequisites" - All API examples require an API key with the `extension` permission. See [API Keys](../../7-administration/access/api-keys.md) for setup. + All API examples need an API key with the `extension` permission. See [API Keys](../../7-administration/access/api-keys.md) for setup. ### List Subscribed Extensions @@ -123,7 +123,7 @@ LimaCharlie Extensions allow users to expand and customize their security enviro === "Go" - There is no dedicated Go SDK method for listing all available extensions. Use the REST API directly. + The Go SDK has no dedicated method to list all available extensions. Use the REST API directly. === "CLI" diff --git a/docs/5-integrations/index.md b/docs/5-integrations/index.md index a0685958a..32ec9dd43 100644 --- a/docs/5-integrations/index.md +++ b/docs/5-integrations/index.md @@ -1,10 +1,10 @@ # Integrations -LimaCharlie connects to external systems in three directions: outbound (sending data out), inbound (acting on external data), and enrichment (pulling context into detections). This section covers all three. +LimaCharlie connects to external systems in three directions: outbound (data goes out), inbound (action on external data), and enrichment (context comes into detections). This section covers all three. ## Outbound — get data out of LimaCharlie -[**Outputs**](outputs/index.md) stream telemetry, detections, audit logs, and deployment events to external destinations on a continuous basis. Use them to feed your SIEM, archive to object storage, or trigger external systems via webhook. +[**Outputs**](outputs/index.md) stream telemetry, detections, audit logs, and deployment events to external destinations continuously. Use outputs to feed a SIEM, to archive to object storage, or to trigger external systems with a webhook. Destination categories: @@ -20,17 +20,17 @@ See [Outputs](outputs/index.md) for the complete list and operational reference [**Extensions**](extensions/index.md) add capabilities to LimaCharlie. Some collect or process data (Artifact, BinLib, Velociraptor, Zeek), some manage internal platform features (Git Sync, YARA Manager, Sensor Cull), some integrate workflow tools (PagerDuty, Twilio, Cases, Playbook). -[**Cloud CLI**](extensions/cloud-cli/index.md) is one specific extension that runs cloud-provider CLIs (AWS, Azure, GCP, Okta, etc.) as D&R response actions. Use it to take action *in* a cloud service from a LimaCharlie detection — disable an Okta user, isolate an EC2 instance, revoke a GitHub token. +[**Cloud CLI**](extensions/cloud-cli/index.md) is one extension that runs cloud-provider CLIs (AWS, Azure, GCP, Okta, etc.) as D&R response actions. Use it to act *in* a cloud service from a LimaCharlie detection — disable an Okta user, isolate an EC2 instance, or revoke a GitHub token. ## Enrichment — pull external data into detections -[**API Integrations**](api-integrations/index.md) let D&R rules and lookups query external services for context: VirusTotal, GreyNoise, Hybrid Analysis, IP geolocation, etc. Cheap to set up, useful for adding signal to existing detections. +[**API Integrations**](api-integrations/index.md) let D&R rules and lookups query external services for context: VirusTotal, GreyNoise, Hybrid Analysis, IP geolocation, etc. They are cheap to set up and they add signal to existing detections. Cloud CLI vs API Integrations: Cloud CLI runs commands *into* a cloud service (action). API Integrations *read* from an external service (lookup). They complement each other. ## Tutorials -End-to-end recipes combining several pieces: +End-to-end recipes that combine several pieces: - [VirusTotal Integration](tutorials/virustotal-integration.md) - [Human-in-the-Loop Response](tutorials/human-in-the-loop-response.md) diff --git a/docs/5-integrations/outputs/allowlisting.md b/docs/5-integrations/outputs/allowlisting.md index 5f2f74cb4..2f480028e 100644 --- a/docs/5-integrations/outputs/allowlisting.md +++ b/docs/5-integrations/outputs/allowlisting.md @@ -1,5 +1,5 @@ # Adding Outputs to an Allow List -At LimaCharlie, we rely on infrastructure with auto-scalers, and thus do not have static IPs nor a CIDR that you can rely on for an allow list (or "whitelisting"). +LimaCharlie uses infrastructure with auto-scalers. LimaCharlie therefore has no static IPs and no CIDR that you can use for an allow list (or "whitelisting"). -Typically, the concern around adding IPs to an allow list for Outputs is based on wanting to limit abuse and ensure that data from webhooks is truly coming from LimaCharlie and not other sources. To address this, we provide a `secret_key` parameter that can be used as a *shared secret* between LimaCharlie and your webhook receiver. When we issue a webhook, we include a `lc-signature` header that is an HMAC of the content of the webhook using the shared `secret_key`. +Users add IPs to an allow list for Outputs to limit abuse, and to make sure that webhook data comes from LimaCharlie and not from another source. For this purpose, LimaCharlie supplies a `secret_key` parameter that you use as a *shared secret* between LimaCharlie and your webhook receiver. Each webhook from LimaCharlie includes an `lc-signature` header. This header is an HMAC of the webhook content, computed with the shared `secret_key`. diff --git a/docs/5-integrations/outputs/billing.md b/docs/5-integrations/outputs/billing.md index 03a670b22..18c4b3462 100644 --- a/docs/5-integrations/outputs/billing.md +++ b/docs/5-integrations/outputs/billing.md @@ -1,10 +1,10 @@ # Output Billing -LimaCharlie aims to bill outputs at cost. This means that as a default outputs are billed accordingly to the [published pricing](https://limacharlie.io/pricing). +LimaCharlie aims to bill outputs at cost. By default, LimaCharlie bills outputs at the [published pricing](https://limacharlie.io/pricing). -An exception to this is outputs that use Google Cloud Platform mechanism where the destination region is the same as the one the relevant LimaCharlie datacenter lives in. In those cases, outputs are not billed. +There is one exception. If an output uses a Google Cloud Platform mechanism, and the destination region is the same as the region of the relevant LimaCharlie datacenter, LimaCharlie does not bill the output. -Here is a list of the relevant regions for the various LimaCharlie datacenter. +These are the relevant regions for each LimaCharlie datacenter. - USA: `us-central1` - Canada: `northamerica-northeast1` @@ -13,7 +13,7 @@ Here is a list of the relevant regions for the various LimaCharlie datacenter. - India: `asia-south1` - Australia: `australia-southeast1` -The supported GCP mechanism for free output are: +These GCP mechanisms support free output: - `gcs` - `pubsub` @@ -21,4 +21,4 @@ The supported GCP mechanism for free output are: Google Cloud Platform general region list: -IP ranges of GCP resources per region change over time. Google publishes these ranges as a JSON file here: +The IP ranges of GCP resources for each region change over time. Google publishes these ranges as a JSON file: diff --git a/docs/5-integrations/outputs/destinations/amazon-s3.md b/docs/5-integrations/outputs/destinations/amazon-s3.md index 16b36c25f..ee6756f01 100644 --- a/docs/5-integrations/outputs/destinations/amazon-s3.md +++ b/docs/5-integrations/outputs/destinations/amazon-s3.md @@ -2,16 +2,16 @@ Output events and detections to an Amazon S3 bucket. -If you have your own visualization stack, or you just need the data archived, you can output directly to Amazon S3. This way you don't need any infrastructure. +If you have your own visualization stack, or if you only need an archive of the data, output directly to Amazon S3. You then do not need your own infrastructure. - `bucket`: the path to the AWS S3 bucket. - `key_id`: the id of the AWS auth key. - `secret_key`: the AWS secret key to auth with. - `sec_per_file`: the number of seconds after which a file is cut and uploaded (default 120, maximum 3600). -- `is_compression`: if set to "true", data will be gzipped before upload. +- `is_compression`: if set to "true", LimaCharlie gzips the data before upload. - `is_indexing`: if set to "true", files are written under a time-based directory structure (`year/month/day/hour/`) instead of flat files with random names. See [File organization](#file-organization) below. -- `region_name`: the region name of the bucket, it is recommended to set it, though not always required. -- `endpoint_url`: optionally specify a custom endpoint URL, usually used with region\_name to output to S3-compatible 3rd party services. +- `region_name`: the region name of the bucket. Set this parameter, although it is not always needed. +- `endpoint_url`: an optional custom endpoint URL. Use it with region\_name to output to third-party services that are compatible with S3. - `dir`: the directory prefix - `is_no_sharding`: do not add a shard directory at the root of the files generated. @@ -30,7 +30,7 @@ is_compression: "true" ## File Organization -By default, each batch of data is uploaded as a flat file with a random (UUID) name at the root of the bucket (or under `dir` if set). File names carry no ordering, so this mode is best suited for pipelines that list and consume all new objects regardless of name. +By default, LimaCharlie uploads each batch of data as a flat file with a random (UUID) name. The file goes to the root of the bucket, or under `dir` if you set it. File names have no order. Use this mode for pipelines that list and consume all new objects without regard to the name. To organize files by date and time, set `is_indexing` to `"true"`. Files are then written under a time-based directory structure: @@ -40,13 +40,13 @@ To organize files by date and time, set `is_indexing` to `"true"`. Files are the For example: `logs/1/2026/7/7/13/d1b2c3d4-e5f6-7890-abcd-ef1234567890_12.gz` -- The timestamp components are in **UTC** and reflect when the batch was uploaded. +- The timestamp components are in **UTC**. They show when LimaCharlie uploaded the batch. - Data files begin with a `d` prefix. -- `shard` is a single hexadecimal character used to spread write load across key prefixes. If you prefer paths to start directly at the year, set `is_no_sharding` to `"true"`. -- Directory components are not zero-padded (July is `7`, not `07`), so a plain lexical sort of object keys will not be strictly chronological; parse the path components numerically if ordering matters. -- The frequency at which new files are created is controlled by `sec_per_file`. +- `shard` is a single hexadecimal character that spreads the write load across key prefixes. To make paths start at the year, set `is_no_sharding` to `"true"`. +- Directory components have no zero padding (July is `7`, not `07`). A lexical sort of object keys is therefore not chronological. If the order is important, parse the path components as numbers. +- The `sec_per_file` parameter controls how often LimaCharlie creates a new file. -The `is_compression` flag, if on, will compress each file as a GZIP when uploaded (adding a `.gz` extension). It is recommended you enable `is_compression`. +If you enable the `is_compression` flag, LimaCharlie compresses each file as a GZIP at upload and adds a `.gz` extension. LimaCharlie recommends that you enable `is_compression`. ## AWS IAM Configuration @@ -57,7 +57,7 @@ The `is_compression` flag, if on, will compress each file as a GZIP when uploade 5. Click on the user you just created and click on the `Security Credentials` tab 6. Click `Create access key` 7. Select `Other` and click `Next` -8. Provide a description (optional) and click `Create access key` +8. Give a description (optional) and click `Create access key` 9. Take note of the "Access key", "Secret access key" and ARN name for the user (starts with "arn:", shown on the user summary screen). ## AWS S3 Configuration @@ -67,7 +67,7 @@ The `is_compression` flag, if on, will compress each file as a GZIP when uploade 3. Click `Create bucket` 4. Click on your newly created bucket and click on the `Permissions` tab 5. Select `Bucket policy` and click `Edit` -6. Input the policy in [sample below](#policy-sample) where you replace the `<>` with the ARN name of the user you created and the `<>` with the name of the bucket you just created. +6. Enter the policy from the [Policy Sample](#policy-sample) section. Replace `<>` with the ARN name of the user that you created. Replace `<>` with the name of the bucket that you created. 7. Click `Save Changes` ### Policy Sample @@ -91,12 +91,12 @@ The `is_compression` flag, if on, will compress each file as a GZIP when uploade ## LimaCharlie Configuration -1. Back in the LimaCharlie GUI, in your organization view, click `Outputs` and `Add Output` -2. Select the stream you would like to send (events, detections, etc) +1. In the LimaCharlie web app, in your organization view, click `Outputs` and then `Add Output` +2. Select the stream that you want to send (events, detections, etc) 3. Select the `Amazon S3` destination -4. Give it a name, enter the bucket name, key\_id, and secret\_key you noted from AWS, and any other parameters you wish to configure +4. Give the output a name. Enter the bucket name, key\_id, and secret\_key that you noted from AWS. Enter any other parameters that you want to configure 5. Click `Save Output` -6. After a minute, the data should start getting written to your bucket +6. After about a minute, LimaCharlie starts to write the data to your bucket ## Related articles diff --git a/docs/5-integrations/outputs/destinations/apache-kafka.md b/docs/5-integrations/outputs/destinations/apache-kafka.md index b8baeb79b..da1cd2e34 100644 --- a/docs/5-integrations/outputs/destinations/apache-kafka.md +++ b/docs/5-integrations/outputs/destinations/apache-kafka.md @@ -3,14 +3,14 @@ Output events and detections to a Kafka target. - `dest_host`: the IP or DNS and port to connect to, format `kafka.myorg.com`. -- `is_tls`: if `true` will output over TCP/TLS. -- `is_strict_tls`: if `true` will enforce validation of TLS certs. -- `username`: if specified along with `password`, use for Basic authentication. -- `password`: if specified along with `username`, use for Basic authentication. +- `is_tls`: if `true`, the output uses TCP/TLS. +- `is_strict_tls`: if `true`, the output validates TLS certs. +- `username`: if you set this with `password`, LimaCharlie uses Basic authentication. +- `password`: if you set this with `username`, LimaCharlie uses Basic authentication. - `routing_topic`: use the element with this name from the `routing` of the event as the Kafka topic name. - `literal_topic`: use this specific value as a topic. -**Note on authentication:** if you specify `username` and `password`, the authentication mechanism assumed is SASL_SSL + SCRAM-SHA-512, which should be compatible with services like [AWS Manages Streaming Kafka](https://aws.amazon.com/msk/). If you require different paramaters around authentication please contact us at [support@limacharlie.io](mailto:support@limacharlie.io). +**Note on authentication:** if you set `username` and `password`, LimaCharlie assumes the authentication mechanism SASL_SSL + SCRAM-SHA-512. This mechanism can work with services such as [AWS Manages Streaming Kafka](https://aws.amazon.com/msk/). If you need different authentication parameters, contact [support@limacharlie.io](mailto:support@limacharlie.io). Example: diff --git a/docs/5-integrations/outputs/destinations/azure-event-hub.md b/docs/5-integrations/outputs/destinations/azure-event-hub.md index 75212b8f4..4b2076c0c 100644 --- a/docs/5-integrations/outputs/destinations/azure-event-hub.md +++ b/docs/5-integrations/outputs/destinations/azure-event-hub.md @@ -4,7 +4,7 @@ Output events and detections to an Azure Event Hub (similar to PubSub and Kafka) - `connection_string`: the connection string provided by Azure. -Note that the connection string should end with `;EntityPath=your-hub-name` which is sometimes missing from the "Connection String" provided by Azure. +The connection string must end with `;EntityPath=your-hub-name`. The "Connection String" from Azure sometimes does not include this part. Example: diff --git a/docs/5-integrations/outputs/destinations/bigquery.md b/docs/5-integrations/outputs/destinations/bigquery.md index 04c7ae291..6e56f4e34 100644 --- a/docs/5-integrations/outputs/destinations/bigquery.md +++ b/docs/5-integrations/outputs/destinations/bigquery.md @@ -2,15 +2,15 @@ Output events and detections to a Google Cloud BigQuery Table. -For a practical use case of this output, see this [tutorial on pushing Velociraptor data to BigQuery](../../tutorials/velociraptor-bigquery.md). +For a use case of this output, see the [tutorial on pushing Velociraptor data to BigQuery](../../tutorials/velociraptor-bigquery.md). -- `schema`: describes the column names, data types, and other information; should match the text-formatted schema from bigquery +- `schema`: the column names, data types, and other information; must match the text-formatted schema from bigquery - `table`: the table name where to send data. - `dataset`: the dataset name where to send data. - `project`: the project name where to send the data. - `secret_key`: the secret json key identifying a service account. - `sec_per_file`: the number of seconds after which a batch of data is loaded. -- `custom_transform`: should align with the schema fields/formats +- `custom_transform`: must align with the fields and formats of the schema Example: diff --git a/docs/5-integrations/outputs/destinations/elastic.md b/docs/5-integrations/outputs/destinations/elastic.md index d4d4427be..6994419cb 100644 --- a/docs/5-integrations/outputs/destinations/elastic.md +++ b/docs/5-integrations/outputs/destinations/elastic.md @@ -2,12 +2,12 @@ Output events and detections to [Elastic](https://www.elastic.co/). -- `addresses`: the IPs or DNS where to send the data to. -- `index`: the index name to send data to. -- `username`: user name if using username/password auth. (use either username/password -or- API key) -- `password`: password if using username/password auth. -- `cloud_id`: Cloud ID from Elastic. -- `api_key`: API key; if using it for auth. (use either username/password -or- API key) +- `addresses`: the IPs or DNS names to send the data to. +- `index`: the index name to send the data to. +- `username`: the user name, if you authenticate with a user name and a password. (Use either a user name and a password, or an API key.) +- `password`: the password, if you authenticate with a user name and a password. +- `cloud_id`: the Cloud ID from Elastic. +- `api_key`: the API key, if you authenticate with an API key. (Use either a user name and a password, or an API key.) Example: diff --git a/docs/5-integrations/outputs/destinations/google-cloud-storage.md b/docs/5-integrations/outputs/destinations/google-cloud-storage.md index 466face41..81b0adb47 100644 --- a/docs/5-integrations/outputs/destinations/google-cloud-storage.md +++ b/docs/5-integrations/outputs/destinations/google-cloud-storage.md @@ -2,17 +2,17 @@ Output events and detections to a GCS bucket. -Looking for Google Chronicle? +You can also use this output with Google Chronicle. -If you already use Google Chronicle, we make it easy to send telemetry you've collected in LimaCharlie to Chronicle. You can get that set up by creating an Output in LimaCharlie to a GCS bucket. +If you use Google Chronicle, you can send the telemetry that you collect in LimaCharlie to Chronicle. To set this up, create an output in LimaCharlie to a GCS bucket. - `bucket`: the path to the GCS bucket. -- `secret_key`: the secret json key identifying a service account. +- `secret_key`: the secret json key that identifies a service account. - `sec_per_file`: the number of seconds after which a file is cut and uploaded (default 120, maximum 3600). -- `is_compression`: if set to "true", data will be gzipped before upload. +- `is_compression`: if set to "true", the data is gzipped before upload. - `is_indexing`: if set to "true", files are written under a time-based directory structure (`year/month/day/hour/`) instead of flat files with random names. See [File organization](#file-organization) below. -- `dir`: the directory prefix where to output the files on the remote host. -- `is_no_sharding`: do not add a shard directory at the root of the files generated. +- `dir`: the directory prefix for the files on the remote host. +- `is_no_sharding`: do not add a shard directory at the root of the generated files. Example: @@ -37,7 +37,7 @@ is_compression: "true" ## File Organization -By default, each batch of data is uploaded as a flat file with a random (UUID) name at the root of the bucket (or under `dir` if set). File names carry no ordering, so this mode is best suited for pipelines that list and consume all new objects regardless of name. +By default, each batch of data is uploaded as a flat file with a random (UUID) name at the root of the bucket, or under `dir` if you set it. The file names have no order. Use this mode for pipelines that list and consume all new objects, and that ignore the names. To organize files by date and time, set `is_indexing` to `"true"`. Files are then written under a time-based directory structure: @@ -47,11 +47,11 @@ To organize files by date and time, set `is_indexing` to `"true"`. Files are the For example: `logs/1/2026/7/7/13/d1b2c3d4-e5f6-7890-abcd-ef1234567890_12.gz` -- The timestamp components are in **UTC** and reflect when the batch was uploaded. +- The timestamp components are in **UTC**. They show when the batch was uploaded. - Data files begin with a `d` prefix. -- `shard` is a single hexadecimal character used to spread write load across key prefixes. If you prefer paths to start directly at the year, set `is_no_sharding` to `"true"`. -- Directory components are not zero-padded (July is `7`, not `07`), so a plain lexical sort of object keys will not be strictly chronological; parse the path components numerically if ordering matters. -- The frequency at which new files are created is controlled by `sec_per_file`. +- `shard` is a single hexadecimal character that spreads the write load across key prefixes. To make the paths start at the year, set `is_no_sharding` to `"true"`. +- Directory components are not zero-padded (July is `7`, not `07`). A plain lexical sort of the object keys is thus not strictly chronological. If the order is important, parse the path components as numbers. +- The `sec_per_file` value controls how often a new file is created. ## Related articles diff --git a/docs/5-integrations/outputs/destinations/google-pubsub.md b/docs/5-integrations/outputs/destinations/google-pubsub.md index f52ae8fd6..364b86053 100644 --- a/docs/5-integrations/outputs/destinations/google-pubsub.md +++ b/docs/5-integrations/outputs/destinations/google-pubsub.md @@ -2,9 +2,9 @@ Output events and detections to a Pubsub topic. -- `secret_key`: the secret json key identifying a service account. -- `project`: the GCP Project name where the Topic lives. -- `topic`: use this specific value as a topic. +- `secret_key`: the secret json key that identifies a service account. +- `project`: the name of the GCP Project that contains the Topic. +- `topic`: the specific value to use as a topic. Example: diff --git a/docs/5-integrations/outputs/destinations/humio.md b/docs/5-integrations/outputs/destinations/humio.md index dfa85612e..e00ac857a 100644 --- a/docs/5-integrations/outputs/destinations/humio.md +++ b/docs/5-integrations/outputs/destinations/humio.md @@ -4,7 +4,7 @@ Output events and detections to the [Humio.com](https://humio.com) service. - `humio_repo`: the name of the humio repo to upload to. - `humio_api_token`: the humio ingestion token. -- `endpoint_url`: optionally specify a custom endpoint URL, if you have Humio deployed on-prem use this to point to it, otherwise it defaults to the Humio cloud. +- `endpoint_url`: an optional custom endpoint URL. If you deploy Humio on-prem, set this value to the address of that deployment. The default is the Humio cloud. Example: @@ -13,7 +13,7 @@ humio_repo: sandbox humio_api_token: fdkoefj0erigjre8iANUDBFyfjfoerjfi9erge ``` -Note: You may need to [create a new parser in Humio](https://docs.humio.com/docs/parsers/creating-a-parser/) to correctly [parse timestamps](https://docs.humio.com/reference/query-functions/functions/parsetimestamp/). You can use the following JSON parser: +Note: To [parse timestamps](https://docs.humio.com/reference/query-functions/functions/parsetimestamp/) correctly, it can be necessary to [create a new parser in Humio](https://docs.humio.com/docs/parsers/creating-a-parser/). You can use this JSON parser: ```text parseJson() | parseTimestamp(field=@timestamp,format="unixTimeMillis",timezone="Etc/UTC") diff --git a/docs/5-integrations/outputs/destinations/ms-teams.md b/docs/5-integrations/outputs/destinations/ms-teams.md index 63c0f6eb2..dcb56a32e 100644 --- a/docs/5-integrations/outputs/destinations/ms-teams.md +++ b/docs/5-integrations/outputs/destinations/ms-teams.md @@ -1,6 +1,6 @@ # Microsoft Teams -Output detections and audit (only) to a Microsoft Teams channel via webhook. +Output detections and audit (only) to a Microsoft Teams channel through a webhook. Messages are delivered as [Adaptive Cards](https://learn.microsoft.com/en-us/adaptive-cards/). @@ -15,23 +15,27 @@ webhook_url: https://..environment.api.powerplatform.com ## Provisioning -LimaCharlie connects to a Teams channel using a **Power Automate Workflow** webhook. +LimaCharlie connects to a Teams channel with a **Power Automate Workflow** webhook. !!! warning "Incoming Webhooks retired" Microsoft retired Office 365 Connectors (including Incoming Webhooks) from Teams. The old `webhook.office.com` URLs no longer work. You must use a Power Automate Workflow as described below. ### Create a Workflow webhook -1. In Microsoft Teams, navigate to the target channel +1. In Microsoft Teams, go to the target channel 2. Click **...** (More options) next to the channel name 3. Select **Workflows** -4. Search for and select the **Send webhook alerts to a channel** template -5. Give the workflow a name (e.g. "LimaCharlie") and authenticate your account -6. Click **Next**, confirm the Team and Channel, then click **Add workflow** -7. Copy the webhook URL from the confirmation dialog — this is the `webhook_url` you need in LimaCharlie +4. Search for the **Send webhook alerts to a channel** template +5. Select the template +6. Give the workflow a name (e.g. "LimaCharlie") +7. Authenticate your account +8. Click **Next** +9. Confirm the Team and the Channel +10. Click **Add workflow** +11. Copy the webhook URL from the confirmation dialog. This is the `webhook_url` that you need in LimaCharlie For details, see [Create incoming webhooks with Workflows](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498). !!! note "Workflow limitations" - - Workflows post via **Flow bot**, which only works in **public channels**. For shared channels, open the workflow in Power Automate and change "Post As" from Flow bot to User. - - Workflows are linked to the user who created them. If that user leaves the organization the workflow stops working. Add co-owners in Power Automate to avoid this. + - Workflows post through **Flow bot**. Flow bot works only in **public channels**. For shared channels, open the workflow in Power Automate. Then change "Post As" from Flow bot to User. + - Each workflow is linked to the user that created it. If that user leaves the organization, the workflow stops. To prevent this, add co-owners in Power Automate. diff --git a/docs/5-integrations/outputs/destinations/opensearch.md b/docs/5-integrations/outputs/destinations/opensearch.md index 01f2469aa..e4211b2b9 100644 --- a/docs/5-integrations/outputs/destinations/opensearch.md +++ b/docs/5-integrations/outputs/destinations/opensearch.md @@ -2,10 +2,10 @@ Output events and detections to [OpenSearch](https://opensearch.org/). -- `addresses`: the IPs or DNS where to send the data to -- `index`: the index name to send data to -- `username`: user name if using username/password auth -- `password`: password if using username/password auth +- `addresses`: the IPs or DNS names to send the data to +- `index`: the index name to send the data to +- `username`: the user name, if you authenticate with a user name and a password +- `password`: the password, if you authenticate with a user name and a password Example: diff --git a/docs/5-integrations/outputs/destinations/scp.md b/docs/5-integrations/outputs/destinations/scp.md index a7742f2b8..b98448960 100644 --- a/docs/5-integrations/outputs/destinations/scp.md +++ b/docs/5-integrations/outputs/destinations/scp.md @@ -2,10 +2,10 @@ Output events and detections over SCP (SSH file transfer). -- `dest_host`: the ip:port where to send the data to, like `1.2.3.4:22`. -- `dir`: the directory where to output the files on the remote host. +- `dest_host`: the ip:port to send the data to, like `1.2.3.4:22`. +- `dir`: the directory for the files on the remote host. - `username`: the SSH username to log in with. -- `password`: optional password to use to login with. +- `password`: the optional password to log in with. - `secret_key`: the optional SSH private key to authenticate with. Example: diff --git a/docs/5-integrations/outputs/destinations/sftp.md b/docs/5-integrations/outputs/destinations/sftp.md index 95888815f..532741706 100644 --- a/docs/5-integrations/outputs/destinations/sftp.md +++ b/docs/5-integrations/outputs/destinations/sftp.md @@ -2,10 +2,10 @@ Output events and detections over SFTP. -- `dest_host`: the ip:port where to send the data to, like `1.2.3.4:22`. -- `dir`: the directory where to output the files on the remote host. +- `dest_host`: the ip:port to send the data to, like `1.2.3.4:22`. +- `dir`: the directory for the files on the remote host. - `username`: the username to log in with. -- `password`: optional password to use to login with. +- `password`: the optional password to log in with. - `secret_key`: the optional SSH private key to authenticate with. Example: diff --git a/docs/5-integrations/outputs/destinations/slack.md b/docs/5-integrations/outputs/destinations/slack.md index c53560509..fba302fd1 100644 --- a/docs/5-integrations/outputs/destinations/slack.md +++ b/docs/5-integrations/outputs/destinations/slack.md @@ -14,23 +14,28 @@ slack_channel: #detections ## Provisioning -To use this Output, you need to create a Slack App and Bot: +To use this Output, you must create a Slack App and a Bot: 1. Go to [https://api.slack.com/apps](https://api.slack.com/apps) -2. Click **Create New App**, select **From scratch**, and choose the workspace -3. From the sidebar, click **OAuth & Permissions** -4. Under **Bot Token Scopes**, click **Add an OAuth Scope** and add `chat:write` -5. From the sidebar, click **Install App**, then **Install to Workspace** -6. Copy the **Bot User OAuth Token** — this is the `slack_api_token` you need in LimaCharlie -7. In your Slack workspace, go to the target channel and invite the bot with the slash command: `/invite @your-app-name` +2. Click **Create New App** +3. Select **From scratch** +4. Choose the workspace +5. From the sidebar, click **OAuth & Permissions** +6. Under **Bot Token Scopes**, click **Add an OAuth Scope** +7. Add the `chat:write` scope +8. From the sidebar, click **Install App** +9. Click **Install to Workspace** +10. Copy the **Bot User OAuth Token**. This is the `slack_api_token` that you need in LimaCharlie +11. In your Slack workspace, go to the target channel +12. Invite the bot with the slash command: `/invite @your-app-name` ### Interactivity Setup (for ext-feedback) -If using this output with the [Feedback extension](../../extensions/limacharlie/feedback.md) for interactive Slack messages (approval buttons, acknowledgements): +If you use this output with the [Feedback extension](../../extensions/limacharlie/feedback.md) for interactive Slack messages (approval buttons, acknowledgements): 1. In your Slack App settings ([api.slack.com/apps](https://api.slack.com/apps)), click **Interactivity & Shortcuts** in the sidebar 2. Toggle **Interactivity** to **On** 3. Set the **Request URL** to `https://feedback-system.limacharlie.io/callback/slack` 4. Click **Save Changes** -This allows Slack to send button-click interactions back to the feedback extension for processing. No additional LimaCharlie output parameters are needed — the extension registers the callback automatically. +These settings let Slack send button-click interactions back to the feedback extension for processing. You do not need more LimaCharlie output parameters. The extension registers the callback automatically. diff --git a/docs/5-integrations/outputs/destinations/smtp.md b/docs/5-integrations/outputs/destinations/smtp.md index bf318f751..3baabc79c 100644 --- a/docs/5-integrations/outputs/destinations/smtp.md +++ b/docs/5-integrations/outputs/destinations/smtp.md @@ -1,10 +1,10 @@ # SMTP -One option to export data from LimaCharlie is via SMTP, allowing you to send emails directly to a case management inbox or send high-priority detections to an on-call, shared email. +SMTP is one option to export data from LimaCharlie. You can send emails directly to an inbox for case management. You can also send high-priority detections to a shared on-call email. -To utilize SMTP output, you will need: +To use the SMTP output, you need: -- An SMTP server that utilizes SSL +- An SMTP server that uses SSL - Username and password to send through the SMTP server (if applicable) - A destination email, to receive output @@ -12,20 +12,20 @@ To utilize SMTP output, you will need: ![smtp](../../../assets/images/smtp(1).png) -Output individually each event, detection, audit, deployment or log through an email. +This output sends each event, detection, audit, deployment or log in a separate email. -- `dest_host`: the IP or DNS (and optionally port) of the SMTP server to use to send the email. -- `dest_email`: one or more email addresses to send the email to. Multiple addresses can be provided comma-separated (for example `soc@corp.com, oncall@corp.com`), and display names are supported (for example `SOC `). Every address receives a copy and appears in the `To:` header. -- `cc_email`: (optional) one or more comma-separated email addresses to add to the `Cc:` header. Each receives a copy. -- `bcc_email`: (optional) one or more comma-separated email addresses to copy without exposing them in the message headers (blind copy). +- `dest_host`: the IP or DNS (and optionally the port) of the SMTP server that sends the email. +- `dest_email`: one or more email addresses that receive the email. To give more than one address, separate the addresses with commas (for example `soc@corp.com, oncall@corp.com`). Display names are supported (for example `SOC `). Every address gets a copy and appears in the `To:` header. +- `cc_email`: (optional) one or more email addresses, separated with commas, to add to the `Cc:` header. Each address gets a copy. +- `bcc_email`: (optional) one or more email addresses, separated with commas, that get a copy but do not appear in the message headers (blind copy). - `from_email`: the email address set in the From field. -- `username`: the username (if any) used to authenticate to the SMTP server. -- `password`: the password (if any) used to authenticate to the SMTP server. -- `secret_key`: an arbitrary shared secret used to compute an HMAC (SHA256) signature of the email to verify authenticity. This is a required field. See "Webhook Details" section below. -- `is_readable`: if 'true' the email format will be HTML and designed to be readable by a human instead of a machine. -- `is_starttls`: if 'true', use the Start TLS method of securing the connection instead of pure SSL. -- `is_authlogin`: if 'true', authenticate using `AUTH LOGIN` instead of `AUTH PLAIN`. -- `subject`: is specified, use this as the alternate "subject" line. +- `username`: the username (if any) that authenticates to the SMTP server. +- `password`: the password (if any) that authenticates to the SMTP server. +- `secret_key`: a shared secret of your choice. It computes an HMAC (SHA256) signature of the email to check authenticity. This field is required. See the "Webhook Details" section below. +- `is_readable`: if 'true', the email format is HTML that a human can read instead of a machine. +- `is_starttls`: if 'true', use the Start TLS method to secure the connection instead of pure SSL. +- `is_authlogin`: if 'true', authenticate with `AUTH LOGIN` instead of `AUTH PLAIN`. +- `subject`: if specified, use this as the alternate "subject" line. Example: @@ -42,7 +42,7 @@ is_authlogin: false subject: LC Detection- ``` -Example sending to multiple recipients with `Cc` and `Bcc`: +Example that sends to more than one recipient with `Cc` and `Bcc`: ```text dest_host: smtp.gmail.com @@ -54,7 +54,7 @@ secret_key: this-is-my-secret-shared-key is_readable: true ``` -> Note: recipients in `dest_email` and `cc_email` appear in the message headers, so they can see each other. Use `bcc_email` for recipients who should receive a copy without being visible to the others. A malformed address in any of these fields will cause the output to fail validation when it is saved. +> Note: recipients in `dest_email` and `cc_email` appear in the message headers, so they can see each other. Use `bcc_email` for recipients that get a copy but stay hidden from the others. If an address in one of these fields is malformed, the output fails validation when you save it. ## Related articles diff --git a/docs/5-integrations/outputs/destinations/splunk.md b/docs/5-integrations/outputs/destinations/splunk.md index 9ef275270..ac716115c 100644 --- a/docs/5-integrations/outputs/destinations/splunk.md +++ b/docs/5-integrations/outputs/destinations/splunk.md @@ -1,14 +1,14 @@ # Splunk -To send data from LimaCharlie to Splunk, you will need to configure an output. +To send data from LimaCharlie to Splunk, configure an output. -Want to reduce Splunk spend? +LimaCharlie can reduce your Splunk spend. -[Watch the webinar recording](https://www.youtube.com/watch?v=lqPqkDkd7I8) to learn about using LimaCharlie to reduce spending on Splunk and other high-cost security data solutions. +[Watch the webinar recording](https://www.youtube.com/watch?v=lqPqkDkd7I8) to learn how LimaCharlie reduces spending on Splunk and other security data solutions with high cost. ## Splunk Setup -Follow Splunk's guide to [set up an HEC](https://docs.splunk.com/Documentation/Splunk/8.0.2/Data/UsetheHTTPEventCollector), and as you do, set the source type to `_json`. +Obey Splunk's guide to [set up an HEC](https://docs.splunk.com/Documentation/Splunk/8.0.2/Data/UsetheHTTPEventCollector). Set the source type to `_json`. ### LimaCharlie Setup @@ -16,7 +16,7 @@ From the **Outputs** view, click `Add Output`. ![splunk 1](../../../assets/images/splunk-1.png) -Choose the type of stream you want to output from LimaCharlie. +Choose the type of stream that you want to output from LimaCharlie. ![splunk 2](../../../assets/images/splunk-2(1).png) @@ -28,7 +28,7 @@ Enter the output name. ![splunk 4](../../../assets/images/splunk-4.png) -Enter the [correct HEC URI](https://docs.splunk.com/Documentation/Splunk/8.0.2/Data/UsetheHTTPEventCollector#Send_data_to_HTTP_Event_Collector) for your Splunk implementation as Destination Host. Use the /services/collector/event endpoint. Note if you are using Spunk Cloud, this will be the string from the URL `https://.splunkcloud.com/`. +Enter the [correct HEC URI](https://docs.splunk.com/Documentation/Splunk/8.0.2/Data/UsetheHTTPEventCollector#Send_data_to_HTTP_Event_Collector) for your Splunk implementation as Destination Host. Use the /services/collector/event endpoint. For Splunk Cloud, this is the string from the URL `https://.splunkcloud.com/`. Here is a sample Splunk HEC configuration: @@ -36,20 +36,20 @@ Destination Host = `https://host.domain.com:8088/services/collector/raw` Auth Header Name = Authorization Auth Header value = Splunk xxxxxx-xxxx-xxxx-xxxx-xxxxxx -Before saving the output, you can configure any of the advanced Output settings. +Before you save the output, you can configure the advanced Output settings. -**Tag** - Providing a tag name allows you to only send events from sensor with this tag. Tags can be managed at the sensor details view. +**Tag** - Give a tag name to send only the events from sensors with this tag. You manage tags in the sensor details view. -**Sensor** - choosing a sensor ID will only send events or detections from this sensor. +**Sensor** - choose a sensor ID to send only the events or detections from this sensor. -Flatten will flatted the JSON; no changes are needed for the email configuration. +Flatten flattens the JSON. The email configuration needs no changes. -\*\*Wrap JSON event with Event Type \*\*- by default, we do not add prefix in front of every record. Prefix is useful for loading data into relational databases. If you are looking to receive a human-readable email, leave this option unchecked. +\*\*Wrap JSON event with Event Type \*\*- by default, LimaCharlie does not add a prefix in front of every record. A prefix is useful when you load data into relational databases. To get an email that a human can read, leave this option unchecked. -**Delete on Failure** - when set to Yes, the system will completely delete the output configuration in case of failure. This is useful when you are configuring a temporary output needed for a short while and you don't want to have to worry about cleaning up later. +**Delete on Failure** - when set to Yes, the system deletes the full output configuration if a failure occurs. Use this for a temporary output that you do not want to remove later. -You can choose to only send a specific list of event types by configuring an allow list in the **Detection Category** section. Alternatively, if you want to exclude certain event types, you can denote it in a deny list **(Disallowed Detection Categories)**. +To send only a specific list of event types, configure an allow list in the **Detection Category** section. To exclude event types, list them in the deny list **(Disallowed Detection Categories)**. -**Do not include routing** flag allows users to forward only the original logs to outputs, excluding the routing label. This can be helpful for users wanting to use LimaCharlie for storage optimization since the routing label can add significant overhead. +The **Do not include routing** flag sends only the original logs to outputs, without the routing label. This helps when you use LimaCharlie to optimize storage, because the routing label can add large overhead. ![splunk 5](../../../assets/images/splunk-5.png) diff --git a/docs/5-integrations/outputs/destinations/syslog.md b/docs/5-integrations/outputs/destinations/syslog.md index ae6727d33..c08dbc98c 100644 --- a/docs/5-integrations/outputs/destinations/syslog.md +++ b/docs/5-integrations/outputs/destinations/syslog.md @@ -5,10 +5,10 @@ Output events and detections to a syslog target. - `dest_host`: the IP or DNS and port to connect to, format `www.myorg.com:514`. -- `is_tls`: if `true` will output over TCP/TLS. -- `is_strict_tls`: if `true` will enforce validation of TLS certs. -- `is_no_header`: if `true` will not emit a Syslog header before every message. This effectively turns it into a TCP output. -- `structured_data`: arbitrary field to include in syslog "Structured Data" headers. Sometimes useful for cloud SIEMs integration. +- `is_tls`: if `true`, the output sends data over TCP/TLS. +- `is_strict_tls`: if `true`, the output validates TLS certs. +- `is_no_header`: if `true`, the output does not send a Syslog header before each message. This makes it a TCP output. +- `structured_data`: a field of your choice to include in syslog "Structured Data" headers. This field can help with integration into cloud SIEMs. Example: diff --git a/docs/5-integrations/outputs/destinations/telegram.md b/docs/5-integrations/outputs/destinations/telegram.md index 019c9b791..b82636765 100644 --- a/docs/5-integrations/outputs/destinations/telegram.md +++ b/docs/5-integrations/outputs/destinations/telegram.md @@ -3,7 +3,7 @@ Output detections and audit (only) to a Telegram chat, group, or channel. - `bot_token`: the Telegram Bot API token obtained from @BotFather. -- `chat_id`: the target chat, group, or channel ID to send messages to. +- `chat_id`: the ID of the target chat, group, or channel that receives the messages. - `parse_mode`: (optional) message formatting mode: `Markdown`, `MarkdownV2`, or `HTML`. - `message`: (optional) a template string for custom message formatting. @@ -17,14 +17,14 @@ parse_mode: Markdown ## Provisioning -To use this Output, you need to create a Telegram Bot: +To use this Output, create a Telegram Bot: -1. Open Telegram and message [@BotFather](https://t.me/BotFather) -2. Send `/newbot` and follow the prompts to name your bot -3. Copy the bot token provided — this is the `bot_token` you need in LimaCharlie -4. Add the bot to the chat, group, or channel where you want to receive messages +1. Open Telegram. Send a message to [@BotFather](https://t.me/BotFather) +2. Send `/newbot`. Obey the prompts to name your bot +3. Copy the bot token. This is the `bot_token` that you need in LimaCharlie +4. Add the bot to the chat, group, or channel that receives the messages 5. For channels, add the bot as an administrator with "Post Messages" permission 6. Get the `chat_id` for your target: - - For **private chats**: message the bot, then visit `https://api.telegram.org/bot/getUpdates` to find your chat ID + - For **private chats**: send a message to the bot, then open `https://api.telegram.org/bot/getUpdates` to find your chat ID - For **groups**: add the bot to the group, send a message, then check `getUpdates` for the group's chat ID (a negative number) - For **public channels**: use `@channelusername` as the chat ID diff --git a/docs/5-integrations/outputs/destinations/tines.md b/docs/5-integrations/outputs/destinations/tines.md index bea88666c..8bf04b0fe 100644 --- a/docs/5-integrations/outputs/destinations/tines.md +++ b/docs/5-integrations/outputs/destinations/tines.md @@ -10,7 +10,7 @@ Example: dest_host: https://something.tines.com/webhook/de2314c5f6246d17e82bf7b5742c9eaf/2d2dbcd2ab3845e9592d33c0526bc123 ``` -Detections or events sent to Tines via an output can be used to subsequently create cases, or take other actions within Tines. +Tines can use the detections or events that an output sends to create cases or to do other actions. ![image.png](../../../assets/images/image(251).png) diff --git a/docs/5-integrations/outputs/destinations/webhook-bulk.md b/docs/5-integrations/outputs/destinations/webhook-bulk.md index fe55beba2..6102e5150 100644 --- a/docs/5-integrations/outputs/destinations/webhook-bulk.md +++ b/docs/5-integrations/outputs/destinations/webhook-bulk.md @@ -3,7 +3,7 @@ Output batches of events, detections, audits, deployments or artifacts through a POST webhook. - `dest_host`: the IP or DNS, port and page to HTTP(S) POST to, format `https://www.myorg.com:514/whatever`. -- `secret_key`: an arbitrary shared secret used to compute an HMAC (SHA256) signature of the webhook to verify authenticity. This is a required field. [See "Webhook Details" section.](webhook.md) +- `secret_key`: a shared secret of your choice. It computes an HMAC (SHA256) signature of the webhook to check authenticity. This field is required. [See "Webhook Details" section.](webhook.md) - `auth_header_name` and `auth_header_value`: set a specific value to a specific HTTP header name in the outgoing webhooks. - `sec_per_file`: the number of seconds after which a file is cut and uploaded. - `is_no_sharding`: do not add a shard directory at the root of the files generated. diff --git a/docs/5-integrations/outputs/destinations/webhook.md b/docs/5-integrations/outputs/destinations/webhook.md index 738911199..0cf26d6af 100644 --- a/docs/5-integrations/outputs/destinations/webhook.md +++ b/docs/5-integrations/outputs/destinations/webhook.md @@ -1,9 +1,9 @@ # Webhook -Output individually each event, detection, audit, deployment or artifact through a POST webhook. +This output sends each event, detection, audit, deployment or artifact in a separate POST webhook. - `dest_host`: the IP or DNS, port and page to HTTP(S) POST to, format `https://www.myorg.com:514/whatever`. -- `secret_key`: an arbitrary shared secret used to compute an HMAC (SHA256) signature of the webhook to verify authenticity. [See "Webhook Details" section.](../allowlisting.md) +- `secret_key`: a shared secret of your choice. It computes an HMAC (SHA256) signature of the webhook to check authenticity. [See "Webhook Details" section.](../allowlisting.md) - `auth_header_name` and `auth_header_value`: set a specific value to a specific HTTP header name in the outgoing webhooks. Example: diff --git a/docs/5-integrations/outputs/index.md b/docs/5-integrations/outputs/index.md index 9ccb1ec86..e78484e3f 100644 --- a/docs/5-integrations/outputs/index.md +++ b/docs/5-integrations/outputs/index.md @@ -14,7 +14,7 @@ Stream telemetry to external destinations. ## Programmatic Management !!! info "Prerequisites" - All API examples require an API key with the `output` permission. See [API Keys](../../7-administration/access/api-keys.md) for setup. + All API examples need an API key with the `output` permission. See [API Keys](../../7-administration/access/api-keys.md) for setup. ### List Outputs diff --git a/docs/5-integrations/outputs/stream-structures.md b/docs/5-integrations/outputs/stream-structures.md index 5e19e6b9f..8614e3556 100644 --- a/docs/5-integrations/outputs/stream-structures.md +++ b/docs/5-integrations/outputs/stream-structures.md @@ -1,11 +1,11 @@ # Output Stream Structures -LimaCharlie routes data through four distinct output streams, each with a different structure and purpose. Understanding these structures is essential for: +LimaCharlie routes data through four output streams. Each stream has a different structure and purpose. You must know these structures to do these tasks: -- Configuring output destinations correctly -- Building parsers in external systems (SIEM, data lake, etc.) -- Filtering and transforming data before sending it -- Integrating with webhooks, APIs, and automation platforms +- Configure output destinations correctly +- Build parsers in external systems (SIEM, data lake, etc.) +- Filter and transform data before you send it +- Integrate with webhooks, APIs, and automation platforms ## Overview of Output Streams @@ -24,7 +24,7 @@ LimaCharlie routes data through four distinct output streams, each with a differ ### Structure -All events follow a canonical two-level structure: +All events use a canonical two-level structure: ```json { @@ -104,13 +104,13 @@ The `event` object varies by `event_type`. Common event types include: ## 2. Detection Stream Structure -**Purpose**: Alerts generated when D&R rules match events +**Purpose**: Alerts that D&R rules generate when a rule matches an event **Stream Name**: `detect` ### Structure -Detections include the original event's routing, the triggering event data, and detection-specific metadata: +A detection includes the routing of the original event, the event data that triggered the rule, and metadata for the detection: ```json { @@ -174,7 +174,7 @@ Detections include the original event's routing, the triggering event data, and ### Key Field: detect_data -The `detect_data` field contains **structured IOCs** extracted by the D&R rule. This is extremely valuable for: +The `detect_data` field contains **structured IOCs** that the D&R rule extracted. This field is valuable for: - Automated enrichment (lookup IPs, domains, hashes) - SOAR playbook inputs @@ -222,7 +222,7 @@ Example `detect_data` for different detection types: ### Structure -Audit logs track actions within the LimaCharlie platform: +Audit logs track actions in the LimaCharlie platform: ```json { @@ -257,7 +257,7 @@ Audit logs track actions within the LimaCharlie platform: | `origin` | string | Origin of action (api, ui, cli, system) | | `time` | integer | Unix timestamp in seconds | | `ident` | string | Identity performing the action (email, API key name) | -| `entity` | object | Object the action was performed on | +| `entity` | object | Object that the action applies to | | `mtd` | object | Action characteristics (action type, source IP, etc.) | | `component` | string | Component name (for error messages) | | `error` | string | Error message (if applicable) | @@ -347,8 +347,8 @@ Deployment events track sensor installations, removals, and updates: ### Use Cases -- **Asset Tracking**: Monitor endpoint agent deployment status -- **Compliance**: Ensure all required endpoints have sensors +- **Asset Tracking**: Monitor the deployment status of each sensor +- **Compliance**: Make sure that all necessary endpoints have sensors - **Lifecycle Management**: Track sensor versions and upgrades - **Alerting**: Detect unexpected sensor removals @@ -394,11 +394,11 @@ secret_key: YOUR-SECRET-KEY ## Filtering and Transforming Streams -**IMPORTANT**: Filter parameters use **newline-separated string format**, not YAML arrays. Each item must be on its own line within a multiline string. +**IMPORTANT**: Filter parameters use a **newline-separated string format**, not YAML arrays. Put each item on its own line in a multiline string. ### Event Type Filtering -Filter specific event types using whitelist/blacklist: +Filter specific event types with a whitelist or a blacklist: ```yaml # Only send NEW_PROCESS and TERMINATE_PROCESS events @@ -417,7 +417,7 @@ event_black_list: | - Use the pipe (`|`) operator for multiline strings in YAML - Each event type on its own line - No hyphens or list syntax -- Empty lines and whitespace are automatically trimmed +- Empty lines and whitespace are trimmed automatically ### Category Filtering @@ -449,7 +449,7 @@ tag_black_list: | staging ``` -**Note**: The `tag` parameter accepts a single tag string. To filter multiple tags, use `tag_black_list` to exclude unwanted tags. +**Note**: The `tag` parameter accepts one tag string. To filter more than one tag, use `tag_black_list` to exclude the unwanted tags. ### Rule Tag Filtering @@ -468,7 +468,7 @@ rule_tag_black_list: | experimental ``` -**Use Case**: Rule tags help organize detections by threat type, compliance requirement, or confidence level. +**Use Case**: Rule tags help you organize detections by threat type, compliance requirement, or confidence level. --- @@ -483,19 +483,19 @@ rule_tag_black_list: | ### 2. Optimize Event Stream Volume -Event streams can be high-volume. Consider: +Event streams can have a high volume. Consider these options: -- Filtering by `event_type` to send only relevant events -- Using separate outputs for different event types -- Sampling high-frequency events if full fidelity isn't needed +- Filter by `event_type` to send only the relevant events +- Use separate outputs for different event types +- Sample high-frequency events if you do not need full fidelity ### 3. Parse Detection IOCs -Always extract and process `detect_data` - it contains pre-parsed IOCs ready for enrichment and response. +Always extract and process `detect_data`. It contains pre-parsed IOCs that are ready for enrichment and response. ### 4. Retain Audit Logs Separately -Audit logs are critical for compliance and should be stored in tamper-proof, long-term storage separate from operational data. +Audit logs are critical for compliance. Store them in tamper-proof, long-term storage that is separate from operational data. ### 5. Monitor Deployment Stream @@ -509,7 +509,7 @@ Use deployment events to track sensor health and detect: ## Related Documentation -- [The `routing` Section](../../8-reference/routing.md) - Deep dive into the metadata envelope shared by events and detections +- [The `routing` Section](../../8-reference/routing.md) - Details about the metadata envelope that events and detections share - [Event Structure Reference](../../8-reference/event-schemas.md#event-structure-reference) - [Detection Structure](../../3-detection-response/tutorials/writing-testing-rules.md) - [LimaCharlie Data Structures](../../1-getting-started/core-concepts.md#limacharlie-data-structures) diff --git a/docs/5-integrations/outputs/testing.md b/docs/5-integrations/outputs/testing.md index 07663fd16..8a3cc2c31 100644 --- a/docs/5-integrations/outputs/testing.md +++ b/docs/5-integrations/outputs/testing.md @@ -1,9 +1,9 @@ # Testing Outputs -The easiest way to test if the outputs are configured correctly is to set the stream to `Audit` which will send auditing events about activity around the management of the platform in the cloud. You can then edit the same output or make any other change on the platform, which will trigger an audit event to be sent. +To test if an output is configured correctly, set the stream to `Audit`. This stream sends audit events about the management of the platform in the cloud. Then edit the same output, or make another change on the platform. The change triggers an audit event. -After you have confirmed that the output configurations works, you can switch the data stream from `Audit` to the one you are looking to use. +After you confirm that the output configuration works, change the data stream from `Audit` to the stream that you want to use. -If you are running into an error configuring an output, the error details will be listed in the Platform Logs section under Errors, with the key that looks like `outputs/OUTPUT_NAME`. +If an error occurs when you configure an output, the error details are in the Platform Logs section under Errors. The key looks like `outputs/OUTPUT_NAME`. -If an output fails, it gets disabled temporarily to avoid spam. It will be re-enabled automatically after a while, or you can force it to be re-enabled by updating the configuration. +If an output fails, the cloud disables it temporarily to stop spam. The cloud enables the output again after some time. You can also update the configuration to enable the output again. diff --git a/docs/5-integrations/services/replay.md b/docs/5-integrations/services/replay.md index 7cc58b0f7..2de00d86b 100644 --- a/docs/5-integrations/services/replay.md +++ b/docs/5-integrations/services/replay.md @@ -1,30 +1,30 @@ # Replay -Replay allows you to run Detection & Response (D&R) rules against historical traffic. - This can be done in a few combinations of sources: +Replay runs Detection & Response (D&R) rules against historical traffic. + You can combine these sources: Rule Source: -- Existing rule in the organization, by name. -- Rule in the replay request. +- An existing rule in the organization, by name. +- A rule in the replay request. Traffic: -- Sensor historical traffic. -- Local events provided during request. +- Historical traffic from a sensor. +- Local events that you supply in the request. ## Using -Using the Replay API requires the [API key](../../7-administration/access/api-keys.md) to have the following permissions: +The Replay API needs an [API key](../../7-administration/access/api-keys.md) with these permissions: - `insight.evt.get` -The returned data from the API contains the following: +The API returns this data: -- `responses`: a list of the actions that would have been taken by the rule (like `report`, `task`, etc). -- `num_evals`: a number of evaluation operations performed by the rule. This is a rough estimate of the performance of the rule. -- `num_events`: the number of events that were replayed. -- `eval_time`: the number of seconds it took to replay the data. +- `responses`: a list of the actions that the rule would take (such as `report` or `task`). +- `num_evals`: the number of evaluation operations that the rule did. This number is a rough estimate of the performance of the rule. +- `num_events`: the number of events that Replay replayed. +- `eval_time`: the number of seconds to replay the data. ```json { @@ -43,11 +43,11 @@ The returned data from the API contains the following: ### Query Language -To use Replay in LCQL Mode (LimaCharlie Query Language), you can specify your query in the `query` parameter of the Replay Request (defined below) when using the REST interface, or you can use the LimaCharlie Python SDK/CLI's [query interface](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Query.py): `limacharlie search --help`. +The REST interface also accepts LCQL Mode (LimaCharlie Query Language). Put your query in the `query` parameter of the Replay Request that is defined below. You can also use the [query interface](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Query.py) of the LimaCharlie Python SDK and CLI: `limacharlie search --help`. ### Python CLI -The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives you a friendly way to replay data, and to do so across larger datasets by automatically splitting up your query into multiple queries that can run in parallel. +The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) replays data. For a large dataset, the CLI splits your query into many queries that run in parallel. Sample command line to query one sensor: @@ -61,7 +61,7 @@ Sample command line to query an entire organization: limacharlie replay run --name my-rule-name --start 1555359000 --end 1556568600 ``` -When specifying a rule via `--detect-file` and `--respond-file`, each file should be in `JSON` or `YAML` format. For example, a detect file: +When you specify a rule with `--detect-file` and `--respond-file`, use the `JSON` or `YAML` format for each file. For example, a detect file: ```yaml event: DNS_REQUEST @@ -77,28 +77,28 @@ And a respond file: name: dilbert-is-here ``` -Instead of replaying against an entire organization, you may use events from a local file via the `limacharlie dr test` command with the `--events` flag. +You can use events from a local file instead of an entire organization. Use the `limacharlie dr test` command with the `--events` flag. -We invite you to look at the command line usage itself, as the tool evolves. +The tool changes over time. Look at the command line usage itself for the current options. ### REST API -The Replay API is available to all DataCenter locations using a per-location URL. - To get the appropriate URL for your organization, use the [`getOrgURLs` REST endpoint](https://api.limacharlie.io/static/swagger/#/Organizations/getOrgURLs) and look for the URL named `replay`. +The Replay API is available in all DataCenter locations. Each location has its own URL. + To get the correct URL for your organization, use the [`getOrgURLs` REST endpoint](https://api.limacharlie.io/static/swagger/#/Organizations/getOrgURLs) and look for the URL named `replay`. -Having per-location URLs will allow us to guarantee that processing occurs within the geographical area you chose. Currently, some locations are NOT guaranteed to be in the same area due to the fact we are using the Google Cloud Run product which is not available globally. For these cases, processing is currently done in the United States, but as soon as it becomes available in your area, the processing will be moved transparently. +A URL for each location keeps the processing inside the geographical area that you chose. Some locations are NOT in the same area, because LimaCharlie uses the Google Cloud Run product, which is not available in all areas. For these locations, the processing is done in the United States. When Google Cloud Run becomes available in your area, the processing moves there transparently. Authentication to this API works with the same JWTs as the main limacharlie.io API. -For this example, we will use the experimental datacenter's URL: +This example uses the URL of the experimental datacenter: ```python https://0651b4f82df0a29c.replay.limacharlie.io/ ``` -The API mainly works on a per-sensor basis, on a limited amount of time. Replaying for multiple sensors (or entire org), or longer time period is done through multiple parallel API calls. This multiplexing is taken care of by the Python CLI above. +The API works mainly for one sensor and for a limited period of time. To replay many sensors, an entire organization, or a longer period, make many parallel API calls. The Python CLI above makes these parallel calls for you. -To query Replay, do a `POST` with a `Content-Type` header of `application-json` and with a JSON body like: +To query Replay, send a `POST` request with a `Content-Type` header of `application-json` and a JSON body like this: ```json { @@ -129,13 +129,13 @@ To query Replay, do a `POST` with a `Content-Type` header of `application-json` } ``` -Like the other endpoints you can also submit a `rule_name` in the URL query if you want +Like the other endpoints, you can also put a `rule_name` in the URL query to use an existing organization rule. -You may also specify a `limit_event` and `limit_eval` parameter as integers. They will limit the number of events evaluated and the number of rule evaluations performed (approximately). If the limits are reached, the response will contain an item named `limit_eval_reached: true` and `limit_event_reached: true`. +You can also give the `limit_event` and `limit_eval` parameters as integers. They limit the approximate number of events that Replay evaluates and the approximate number of rule evaluations. If Replay reaches the limits, the response contains an item named `limit_eval_reached: true` and `limit_event_reached: true`. -Finally, you may also set `trace` to `true` in the request to receive a detailed trace of the rule evaluation. This is useful in the development of new rules to find where rules are failing. +You can also set `trace` to `true` in the request to get a detailed trace of the rule evaluation. The trace helps you find where a new rule fails. ## Billing -The Replay service is billed on a per event evaluated. +The Replay service is billed for each event that it evaluates. diff --git a/docs/5-integrations/tutorials/hayabusa-bigquery.md b/docs/5-integrations/tutorials/hayabusa-bigquery.md index ec5874210..16b158908 100644 --- a/docs/5-integrations/tutorials/hayabusa-bigquery.md +++ b/docs/5-integrations/tutorials/hayabusa-bigquery.md @@ -2,58 +2,58 @@ ## Overview -Our BigQuery output allows you to send Hayabusa analysis results to a BigQuery table allowing SQL-like queries against the data. This allows you to perform analysis at scale against massive datasets. For guidance on using Hayabusa within LimaCharlie, see [Hayabusa Extension](../extensions/third-party/hayabusa.md). +The BigQuery output sends Hayabusa analysis results to a BigQuery table. You can then run SQL-like queries against the data and analyze very large datasets. To learn how to use Hayabusa in LimaCharlie, see [Hayabusa Extension](../extensions/third-party/hayabusa.md). -Imagine you wanted to analyze event logs from 10s, 100s, or 1000s of systems using Hayabusa. You have a couple options: +To analyze event logs from 10s, 100s, or 1000s of systems with Hayabusa, you have two options: -1. Send the resulting CSV artifact to another platform, like [Timesketch](https://timesketch.org/), for further analysis, as the CSV generated by Hayabusa in LimaCharlie is compatible with Timesketch -2. Run queries against all of the data returned by Hayabusa in BigQuery +1. Send the CSV artifact to another platform, such as [Timesketch](https://timesketch.org/), for more analysis. The CSV that Hayabusa creates in LimaCharlie is compatible with Timesketch +2. Run queries in BigQuery against all the data that Hayabusa returns -BigQuery dataset containing Hayabusa results: +A BigQuery dataset that contains Hayabusa results: ![Screenshot 2024-02-27 10.50.46 AM.png](../../assets/images/Screenshot-2024-02-27-10.50.46-AM.png) ### Steps to Accomplish -1. You will need a Google Cloud project -2. You will need to create a service account within your Google Cloud project +1. Get a Google Cloud project +2. Create a service account in your Google Cloud project - 1. Navigate to your project - 2. Navigate to IAM - 3. Navigate to Service Accounts > Create Service Account - 4. Click on newly created Service Account and create a new key + 1. Go to your project + 2. Go to IAM + 3. Go to Service Accounts > Create Service Account + 4. Click the new Service Account and create a new key 1. ![image.png](../../assets/images/image(188).png) - 2. This will provide you with the JSON format secret key you will later setup in your LimaCharlie output. - 5. In BigQuery, create a Dataset, Table, & Schema similar to the screenshot below. Keep in mind, the name of your dataset and table are arbitrary but they need to match what you configure in your output in LimaCharlie. + 2. This gives you the secret key in JSON format. You configure this key later in your LimaCharlie output. + 5. In BigQuery, create a Dataset, Table, & Schema like the screenshot below. The names of your dataset and table are arbitrary, but they must match the names that you configure in your output in LimaCharlie. 1. Project - `your_project_name` 2. Dataset - `hayabusa` 3. Table - `hayabusa` 4. Schema - `computer:STRING, message:STRING, timestamp:STRING, details:STRING, channel:STRING, event_id:STRING, level:STRING, mitre_tactics:STRING, mitre_tags:STRING, extra:STRING` - 1. Note that this can be any of the fields from the Hayabusa event that you wish to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** -3. Now we're ready to create our LimaCharlie Events Output + 1. This can be any of the fields from the Hayabusa event that you want to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** +3. Create the LimaCharlie Events Output - 1. In the side navigation menu, click "Outputs" then add a new ouput + 1. In the side navigation menu, click "Outputs" and add a new output 1. **Output stream**: Events 2. **Destination**: Google Cloud BigQuery 1. **Name**: `hayabusa-bigquery` - 1. You can change this, but it affects a subsequent step so take note of the output name + 1. You can change this name, but it affects a later step, so note the output name 2. **schema**: `computer:STRING, message:STRING, timestamp:STRING, details:STRING, channel:STRING, event_id:STRING, level:STRING, mitre_tactics:STRING, mitre_tags:STRING, extra:STRING` - 1. Note that this can be any of the fields from the Hayabusa event that you wish to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** - 3. **Dataset**: *whatever you named BQ your dataset above* - 4. **Table**: *whatever you named your BQ table above* + 1. This can be any of the fields from the Hayabusa event that you want to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** + 3. **Dataset**: *the name that you gave your BQ dataset above* + 4. **Table**: *the name that you gave your BQ table above* 5. **Project**: *your* GCP *project name* - 6. **Secret Key**: *provide the JSON secret key for your GCP service account* + 6. **Secret Key**: *give the JSON secret key for your GCP service account* 7. **Advanced Options** - 1. **Custom Transform**: paste in this JSON + 1. **Custom Transform**: paste this JSON - 1. Note that this can be any of the fields from the Hayabusa event that you wish to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** + 1. This can be any of the fields from the Hayabusa event that you want to use. **This schema and transform are based on the CSV output using the** `timesketch-verbose` **profile.** ```json { @@ -72,4 +72,4 @@ BigQuery dataset containing Hayabusa results: 2. **Specific Event Types**: `hayabusa_event` 3. **Sensor**: `ext-hayabusa` -4. You are now ready to send Hayabusa events to BigQuery! +4. You can now send Hayabusa events to BigQuery diff --git a/docs/5-integrations/tutorials/human-in-the-loop-response.md b/docs/5-integrations/tutorials/human-in-the-loop-response.md index 1c950250f..c8a170966 100644 --- a/docs/5-integrations/tutorials/human-in-the-loop-response.md +++ b/docs/5-integrations/tutorials/human-in-the-loop-response.md @@ -1,6 +1,6 @@ # Human-in-the-Loop Response Automation -This tutorial walks through building an end-to-end workflow that detects a credential dumping tool, asks a SOC analyst for approval before isolating the host, and executes the response via a Python playbook. It demonstrates how D&R rules, the [Feedback extension](../extensions/limacharlie/feedback.md), and [Playbooks](../extensions/limacharlie/playbook.md) work together to implement human-in-the-loop security automation. +This tutorial builds a workflow that detects a credential dumping tool. The workflow asks a SOC analyst for approval before it isolates the host, then does the response with a Python playbook. It shows how D&R rules, the [Feedback extension](../extensions/limacharlie/feedback.md), and [Playbooks](../extensions/limacharlie/playbook.md) work together for human-in-the-loop security automation. ## What You Will Build @@ -30,23 +30,23 @@ NEW_PROCESS event (mimikatz.exe) the host for monitoring ``` -**Why human-in-the-loop?** Automated isolation is effective but disruptive. A sysadmin running a legitimate tool on a server, or a red team engagement, can trigger credential-tool detections. Asking a human before isolating avoids costly false-positive disruptions while still ensuring fast response when the threat is real. +**Reason for human-in-the-loop:** Automated isolation works, but it interrupts users. A sysadmin who runs a legitimate tool on a server, or a red team engagement, can trigger credential-tool detections. A question to a human before the isolation stops costly interruptions from false positives. The response is still fast when the threat is real. ## Prerequisites -Subscribe to the following extensions in the [LimaCharlie marketplace](https://app.limacharlie.io/add-ons): +Subscribe to these extensions in the [LimaCharlie marketplace](https://app.limacharlie.io/add-ons): - **Feedback** (`ext-feedback`) -- delivers approval requests and collects responses -- **Playbook** (`ext-playbook`) -- executes Python playbooks +- **Playbook** (`ext-playbook`) -- runs Python playbooks -You also need a [Slack Tailored Output](../outputs/destinations/slack.md) configured with a `slack_api_token` and `slack_channel`. See [Feedback Slack Setup](../extensions/limacharlie/feedback.md#slack-setup) for details on creating a Slack App with interactivity enabled. +You also need a [Slack Tailored Output](../outputs/destinations/slack.md) that has a `slack_api_token` and a `slack_channel`. To create a Slack App with interactivity enabled, see [Feedback Slack Setup](../extensions/limacharlie/feedback.md#slack-setup). !!! tip "No Slack?" - You can use any channel type ([Telegram](../extensions/limacharlie/feedback.md#telegram-setup), [Microsoft Teams](../extensions/limacharlie/feedback.md#microsoft-teams-setup), [email](../extensions/limacharlie/feedback.md#email-setup), or `web`). Replace the channel type in Step 1 accordingly. The D&R rule, playbook, and response flow are identical regardless of channel. + You can use any channel type ([Telegram](../extensions/limacharlie/feedback.md#telegram-setup), [Microsoft Teams](../extensions/limacharlie/feedback.md#microsoft-teams-setup), [email](../extensions/limacharlie/feedback.md#email-setup), or `web`). Replace the channel type in Step 1. The D&R rule, the playbook, and the response flow are the same for each channel. ## Step 1: Create a Feedback Channel -Add a Slack channel to the Feedback extension config. This tells ext-feedback where to deliver approval requests. +Add a Slack channel to the Feedback extension config. The channel tells ext-feedback where to deliver approval requests. === "CLI" ```bash @@ -74,7 +74,7 @@ Add a Slack channel to the Feedback extension config. This tells ext-feedback wh comment: "" ``` -Verify the channel was created: +Check that the channel exists: ```bash limacharlie feedback channel list @@ -82,11 +82,11 @@ limacharlie feedback channel list ## Step 2: Write the D&R Rule -This rule detects credential dumping tools and asks for human approval before taking action. The response is routed to a playbook that handles isolation or monitoring. +This rule detects credential dumping tools and asks a human for approval before it acts. The response goes to a playbook that isolates the host or monitors it. ### Detection -The detection matches processes whose file path ends with known credential dumping tool names: +The detection matches a process with a file path that ends with the name of a known credential dumping tool: ```yaml op: or @@ -109,11 +109,11 @@ rules: ``` !!! note - This is a simplified detection for illustration. Production rules would include additional context (e.g., command-line arguments targeting `lsass`, hash lookups, or behavioral patterns). + This detection is simplified for the example. A production rule includes more context, such as command-line arguments that target `lsass`, hash lookups, or behavioral patterns. ### Response -The response has two actions: report the detection, and request approval via ext-feedback. +The response has two actions: it reports the detection, and it requests approval through ext-feedback. ```yaml - action: report @@ -150,15 +150,15 @@ The response has two actions: report the detection, and request approval via ext **Key design decisions:** -- **Suppression** prevents the same host from flooding the Slack channel. Keyed on hostname, it ensures at most one approval request per host per hour. Without this, a noisy process restarting repeatedly would generate dozens of Slack messages. -- **Timeout** auto-denies after 10 minutes. The playbook still runs on timeout (with `responder: "timeout"`), so the host gets tagged for monitoring even if no one is watching Slack. -- **`approved_content` / `denied_content`** carry the sensor ID and hostname through the human decision point, so the playbook has everything it needs to act without additional API calls to look up the sensor. +- **Suppression** stops the same host from sending too many messages to the Slack channel. The key is the hostname, so each host sends a maximum of one approval request each hour. Without suppression, a noisy process that restarts many times creates dozens of Slack messages. +- **Timeout** denies the request automatically after 10 minutes. The playbook still runs at the timeout (with `responder: "timeout"`), so the host is tagged for monitoring even if nobody watches Slack. +- **`approved_content` / `denied_content`** carry the sensor ID and the hostname through the human decision. The playbook then has all the data that it needs to act, and it makes no more API calls to look up the sensor. ## Step 3: Create the Playbook -Create a playbook named `handle-isolation-decision` in the Playbooks section (Automation > Playbooks in the web UI), or via Infrastructure as Code. +Create a playbook named `handle-isolation-decision` in the Playbooks section (Automation > Playbooks in the web app), or with Infrastructure as Code. -This playbook receives the feedback response and either isolates the host or tags it for monitoring. +The playbook receives the feedback response. It isolates the host or tags it for monitoring. ### Playbook Code @@ -217,7 +217,7 @@ def playbook(sdk, data): ### What the Playbook Receives -When ext-feedback dispatches to a playbook, the `data` parameter contains: +When ext-feedback sends the response to a playbook, the `data` parameter contains: | Field | Description | |-------|-------------| @@ -227,11 +227,11 @@ When ext-feedback dispatches to a playbook, the `data` parameter contains: | `responder` | Username of the person who responded, or `"timeout"` | | `content` | The JSON from `approved_content` or `denied_content` (whichever matches the choice) | -The `content` field is where the D&R rule's context (sensor ID, hostname, file path) arrives. This is why the `approved_content` and `denied_content` in the D&R rule include `sid` and `hostname` -- they travel through the feedback system and arrive intact in the playbook. +The `content` field holds the context from the D&R rule: the sensor ID, the hostname, and the file path. For this reason, `approved_content` and `denied_content` in the D&R rule include `sid` and `hostname`. These values move through the feedback system and arrive intact in the playbook. ### Infrastructure as Code -To manage the playbook via [git-sync](../extensions/limacharlie/git-sync.md): +To manage the playbook with [git-sync](../extensions/limacharlie/git-sync.md): ```yaml hives: @@ -292,11 +292,11 @@ hives: ``` !!! warning - The playbook needs an API key with `sensor.set` permissions (for isolation and tagging). When triggering the playbook from a D&R rule, pass credentials via the `credentials` field, or configure the playbook extension with a default API key. + The playbook needs an API key with `sensor.set` permissions for isolation and tagging. When you trigger the playbook from a D&R rule, give the credentials in the `credentials` field. You can also configure the playbook extension with a default API key. ## Step 4: Test the Workflow -You can test the full flow without waiting for a real detection by sending a feedback request directly from the CLI: +To test the full flow without a real detection, send a feedback request from the CLI: ```bash limacharlie feedback request-approval \ @@ -308,13 +308,13 @@ limacharlie feedback request-approval \ --timeout 120 --timeout-choice denied ``` -Replace `YOUR_SENSOR_SID` with a real sensor ID from your organization. After running this command: +Replace `YOUR_SENSOR_SID` with a real sensor ID from your organization. After you run this command: 1. A message appears in your Slack channel with **Approve** and **Deny** buttons 2. Click **Approve** -- the `handle-isolation-decision` playbook runs and isolates the sensor 3. Click **Deny** -- the playbook tags the sensor with `cred-tool-monitor` for 24 hours -If you want to test without affecting a real sensor, use the `web` channel instead to get a URL you can open in a browser: +To test without a change to a real sensor, use the `web` channel. It gives you a URL that you can open in a browser: ```bash limacharlie feedback channel add --name test-web --type web @@ -327,13 +327,13 @@ limacharlie feedback request-approval \ --denied-content '{"sid": "test-sid", "hostname": "workstation-42", "file_path": "mimikatz.exe", "action": "monitor"}' ``` -The CLI returns a `url` you can open in your browser to respond. +The CLI returns a `url` that you can open in your browser to respond. ## How It All Fits Together 1. A `NEW_PROCESS` event fires when mimikatz.exe runs on an endpoint 2. The D&R rule matches and sends a `request_simple_approval` to ext-feedback -3. Suppression checks whether this host already has a pending request (keyed on hostname, 1-hour window) -- if so, the action is skipped +3. Suppression checks if this host already has a pending request (keyed on hostname, 1-hour window) -- if it does, the action is skipped 4. ext-feedback delivers the question to Slack with Approve/Deny buttons 5. A SOC analyst clicks **Approve** (or the 10-minute timeout fires and auto-denies) 6. ext-feedback routes the response through the webhook adapter and D&R pipeline @@ -342,10 +342,10 @@ The CLI returns a `url` you can open in your browser to respond. ## Extending the Pattern -**Escalation chain:** If the timeout fires, have the playbook send a second feedback request to a different channel (e.g., `management-approvals`) with a shorter timeout before auto-isolating. +**Escalation chain:** When the timeout occurs, let the playbook send a second feedback request to a different channel, such as `management-approvals`. Give this second request a shorter timeout before the automatic isolation. -**Multi-step workflow:** Chain multiple feedback requests. For example, after isolation approval, ask "Run memory forensics on this host?" with the response going to a second playbook that triggers [Velociraptor](../extensions/third-party/velociraptor.md) or a [Dumper](../extensions/limacharlie/dumper.md) collection. +**Multi-step workflow:** Chain many feedback requests. For example, after the approval of the isolation, ask "Run memory forensics on this host?". Send the response to a second playbook that starts a [Velociraptor](../extensions/third-party/velociraptor.md) or [Dumper](../extensions/limacharlie/dumper.md) collection. -**Audit trail:** Set the feedback destination to `case` instead of `playbook` to log every approval decision as a case note, creating a reviewable audit trail. +**Audit trail:** Set the feedback destination to `case` instead of `playbook`. Each approval decision becomes a case note, which gives you an audit trail that you can review. -**AI agent follow-up:** Set the feedback destination to `ai_agent` to start an AI agent session when the human responds. The agent receives the feedback response appended to its prompt, allowing it to take context-aware automated action based on the human's decision. +**AI agent follow-up:** Set the feedback destination to `ai_agent` to start an AI agent session when the human responds. The agent gets the feedback response at the end of its prompt. The agent can then take automated action that uses the context of the human decision. diff --git a/docs/5-integrations/tutorials/velociraptor-bigquery.md b/docs/5-integrations/tutorials/velociraptor-bigquery.md index f12c22636..f7e78b933 100644 --- a/docs/5-integrations/tutorials/velociraptor-bigquery.md +++ b/docs/5-integrations/tutorials/velociraptor-bigquery.md @@ -2,59 +2,59 @@ ## Overview -Our BigQuery output allows you to send Velociraptor hunt results to a BigQuery table allowing SQL-like queries against the hunt data. This is very similar to using [Velociraptor notebooks](https://docs.velociraptor.app/docs/vql/notebooks/), allowing you to perform hunt analysis at scale against massive datasets. For guidance on using LimaCharlie to execute Velociraptor hunts, see [Velociraptor Extension](../extensions/third-party/velociraptor.md). +The BigQuery output sends Velociraptor hunt results to a BigQuery table, where you can run SQL-like queries against the hunt data. This is similar to [Velociraptor notebooks](https://docs.velociraptor.app/docs/vql/notebooks/), and it lets you analyze hunts against very large datasets. To learn how to run Velociraptor hunts with LimaCharlie, see [Velociraptor Extension](../extensions/third-party/velociraptor.md). -Imagine you wanted to obtain running processes from 10s, 100s, or 1000s of systems using Velociraptor. You could easily issue a `Windows.System.Pslist` hunt across these systems, and let LimaCharlie push Velociraptor to the endpoints and collect the results. The issue is, if you want to run queries against all of the data returned by the hunts, you'll need a database-like tool to do that which is where BigQuery comes in. +You want to get the running processes from 10s, 100s, or 1000s of systems with Velociraptor. You can issue a `Windows.System.Pslist` hunt across these systems, and LimaCharlie pushes Velociraptor to the endpoints and collects the results. To run queries against all the data that the hunts return, you need a database tool. BigQuery is that tool. -BigQuery dataset containing Velociraptor hunt results: +A BigQuery dataset that contains Velociraptor hunt results: ![image.png](../../assets/images/image(186).png) ### Prerequisites -1. **A Google Cloud project with billing enabled.** LimaCharlie writes to BigQuery using streaming inserts, which are not available in the free tier (BigQuery sandbox). If billing is not enabled on the project, the output will fail with an error like: +1. **A Google Cloud project with billing enabled.** LimaCharlie writes to BigQuery with streaming inserts, which are not available in the free tier (BigQuery sandbox). If billing is not enabled on the project, the output fails with an error like this: ```text googleapi: Error 403: Access Denied: BigQuery BigQuery: Streaming insert is not allowed in the free tier, accessDenied ``` -2. **The ability to create service account keys.** Some organizations enforce the `iam.disableServiceAccountKeyCreation` organization policy, which blocks the creation of service account JSON keys. If key creation fails with a policy error, an administrator will need to grant an exception for the project (Organization Policies > "Disable service account key creation"), or you can use a project outside of that policy. +2. **The ability to create service account keys.** Some organizations enforce the `iam.disableServiceAccountKeyCreation` organization policy, which blocks the creation of JSON keys for service accounts. If the key creation fails with a policy error, an administrator must grant an exception for the project (Organization Policies > "Disable service account key creation"). You can also use a project that this policy does not control. ### Steps to Accomplish -1. You will need to create a service account within your Google Cloud project +1. Create a service account in your Google Cloud project - 1. Navigate to your project - 2. Navigate to IAM - 3. Navigate to Service Accounts > Create Service Account - 4. Click on newly created Service Account and create a new key + 1. Go to your project + 2. Go to IAM + 3. Go to Service Accounts > Create Service Account + 4. Click the new Service Account and create a new key 1. ![image.png](../../assets/images/image(188).png) - 2. This will provide you with the JSON format secret key you will later setup in your LimaCharlie output - 5. In BigQuery, create a Dataset, Table, & Schema similar to the screenshot below + 2. This gives you the secret key in JSON format. You configure this key later in your LimaCharlie output + 5. In BigQuery, create a Dataset, Table, & Schema like the screenshot below 1. ![image.png](../../assets/images/image(189).png) - 6. Grant the service account the **BigQuery Data Editor** role, either on the project or scoped to the dataset you just created + 6. Give the service account the **BigQuery Data Editor** role, on the project or on the new dataset - 1. The output needs the `bigquery.tables.get` permission (to read the table schema) and `bigquery.tables.updateData` (to stream rows in). Roles like *BigQuery Data Viewer* or *BigQuery Job User* are **not** sufficient — without *BigQuery Data Editor* the output will fail with an error like `Permission bigquery.tables.get denied on table :. (or it may not exist)` -2. Now we're ready to create our LimaCharlie tailored output + 1. The output needs the `bigquery.tables.get` permission to read the table schema, and `bigquery.tables.updateData` to stream rows in. Roles such as *BigQuery Data Viewer* or *BigQuery Job User* are **not** enough. Without *BigQuery Data Editor*, the output fails with an error like `Permission bigquery.tables.get denied on table :.
(or it may not exist)` +2. Create the LimaCharlie tailored output - 1. In the side navigation menu, click "Outputs" then add a new output + 1. In the side navigation menu, click "Outputs" and add a new output 1. **Output stream**: Tailored 2. **Destination**: Google Cloud BigQuery 1. **Name**: `bigquery-tailored` - 1. You can change this, but it affects a subsequent step so take note of the output name - 2. **Dataset**: *whatever you named BQ your dataset above* - 3. **Table**: *whatever you named your BQ table above* + 1. You can change this name, but it affects a later step, so note the output name + 2. **Dataset**: *the name that you gave your BQ dataset above* + 3. **Table**: *the name that you gave your BQ table above* - 1. The output streams rows directly into this table, so the table's columns (defined when you created it above, e.g. `sid:STRING, job_id:STRING, artifact:JSON`) must match the fields produced by the Custom Transform below — rows with fields that don't exist as columns are rejected by BigQuery - 4. **Project**: *your GCP project **ID*** (e.g. `my-project-123456`, not the display name — you can find it on the GCP console dashboard or in the resource picker) - 5. **Secret Key**: *provide the JSON secret key for your GCP service account* + 1. The output streams rows directly into this table. The columns of the table that you defined above, for example `sid:STRING, job_id:STRING, artifact:JSON`, must match the fields from the Custom Transform below. BigQuery rejects rows with fields that do not exist as columns + 4. **Project**: *your GCP project **ID*** (for example `my-project-123456`, not the display name). You can find the ID on the GCP console dashboard or in the resource picker + 5. **Secret Key**: *give the JSON secret key for your GCP service account* 6. **Advanced Options** - 1. **Custom Transform**: paste in this JSON + 1. **Custom Transform**: paste this JSON ```json { @@ -66,7 +66,7 @@ BigQuery dataset containing Velociraptor hunt results: 2. **Specific Event Types**: `velociraptor_collection` 3. ![velociraptor](../../assets/images/velociraptor.png) -3. We now need a rule that will watch for Velociraptor collections and send them to the new tailored output +3. Create a rule that watches for Velociraptor collections and sends them to the new tailored output 1. Create a new D&R rule @@ -87,25 +87,25 @@ BigQuery dataset containing Velociraptor hunt results: name: Velociraptor hunt sent to BigQuery ``` -4. You are now ready to send Velociraptor hunts to BigQuery! +4. You can now send Velociraptor hunts to BigQuery ## Including the Hostname -The `velociraptor_collection` event identifies the endpoint by its sensor ID (`sid`) only — it does not contain the hostname, and because the event is delivered through the extension's webhook adapter, the output's `routing` metadata identifies the adapter rather than the endpoint. To get the hostname alongside your hunt results, include the built-in `Generic.Client.Info` artifact in your collections; its `BasicInformation` source reports the endpoint's `Hostname` and `Fqdn` as part of the collection results. +The `velociraptor_collection` event identifies the endpoint only by its sensor ID (`sid`). The event does not contain the hostname. The extension delivers the event through its webhook adapter, so the `routing` metadata of the output identifies the adapter and not the endpoint. To get the hostname with your hunt results, include the built-in `Generic.Client.Info` artifact in your collections. Its `BasicInformation` source reports the `Hostname` and the `Fqdn` of the endpoint in the collection results. -For example, when starting a collection, use an artifact list like: +For example, when you start a collection, use an artifact list like this: ```json ["Generic.Client.Info", "Windows.System.Pslist"] ``` -You can then surface the hostname as its own BigQuery column. First add the column to your table (fields sent by the output must exist as columns, or the rows will be rejected): +You can then show the hostname in its own BigQuery column. First, add the column to your table (each field that the output sends must exist as a column, or BigQuery rejects the rows): ```sql ALTER TABLE `velociraptor.hunts` ADD COLUMN hostname STRING ``` -Then add a `hostname` field to the output's Custom Transform, extracted from the `Generic.Client.Info` results: +Then add a `hostname` field to the Custom Transform of the output. This field comes from the `Generic.Client.Info` results: ```json { @@ -116,7 +116,7 @@ Then add a `hostname` field to the output's Custom Transform, extracted from the } ``` -Alternatively, leave the schema and transform as-is and extract the hostname at query time from the `artifact` JSON column: +As an alternative, keep the schema and the transform, and extract the hostname from the `artifact` JSON column at query time: ```sql SELECT @@ -130,11 +130,11 @@ FROM ### Query Examples -Once the data arrives in BigQuery, it will be in three simple columns: `sid`, `job_id`, and `artifact`. The `artifact` column contains the raw JSON of the hunt results from each sensor that returned results. +After the data arrives in BigQuery, it is in three columns: `sid`, `job_id`, and `artifact`. The `artifact` column contains the raw JSON of the hunt results from each sensor that returned results. ![image.png](../../assets/images/image(191).png) -Let's say we wanted to split out all results of a `Windows.System.Pslist` hunt so that each process, from each system, is returned in its own row. Here is an example notebook to accomplish this: +To split all results of a `Windows.System.Pslist` hunt so that each process from each system is in its own row, use this example notebook: ```sql SELECT @@ -153,12 +153,12 @@ FROM LIMIT 1000 ``` -Be sure to swap out `lc-demo-infra.velociraptor.hunts` for your own `project.dataset.table` names. +Replace `lc-demo-infra.velociraptor.hunts` with your own `project.dataset.table` names. -This results in the following view of our data +This query gives this view of the data ![image.png](../../assets/images/image(200).png) -Suppose we wanted to perform some stacking analysis to identify the rarest combinations of `Exe` and `CommandLine`; the following query could help: +To do a stacking analysis that finds the rarest combinations of `Exe` and `CommandLine`, use this query: ```sql SELECT @@ -175,10 +175,10 @@ ORDER BY Count ASC ``` -This results in the following view of our data +This query gives this view of the data ![image.png](../../assets/images/image(201).png) -Now let's say you wanted to look for only processes that are `Authenticode` = `untrusted`, you would use a query such as this: +To find only the processes that are `Authenticode` = `untrusted`, use a query such as this: ```sql SELECT @@ -201,11 +201,11 @@ LIMIT 1000 ### WHERE Filters for Specific Conditions -Here are some brief examples of `WHERE` statements to perform specific filtering. +These are short examples of `WHERE` statements that do specific filtering. #### String presence -This example checks for the presence of a string `mimikatz` appearing anywhere within `CommandLine` +This example checks for the string `mimikatz` at any position in `CommandLine` ```text WHERE @@ -214,7 +214,7 @@ WHERE #### Compare integers -This example checks for the presence of an integer `0` in a numeric field `GroupID` +This example checks for the integer `0` in the numeric field `GroupID` ```text WHERE @@ -223,7 +223,7 @@ WHERE ### Parsing Nested JSON Objects -In the `Windows.System.Pslist` examples above, there are a few columns which contain nested JSON such as `Authenticode` and `Hash`. To expand these objects in their entirety in the corresponding column/row, we'd write a query like this: +In the `Windows.System.Pslist` examples above, some columns contain nested JSON, such as `Authenticode` and `Hash`. To expand these objects fully in the related column and row, write a query like this: ```sql SELECT @@ -237,5 +237,5 @@ FROM LIMIT 1000 ``` -See the output of this query below: +The output of this query is below: ![image.png](../../assets/images/image(202).png) diff --git a/docs/5-integrations/tutorials/virustotal-integration.md b/docs/5-integrations/tutorials/virustotal-integration.md index 99fea7f36..40edb2981 100644 --- a/docs/5-integrations/tutorials/virustotal-integration.md +++ b/docs/5-integrations/tutorials/virustotal-integration.md @@ -1,16 +1,16 @@ # VirusTotal Integration -You can easily integrate LimaCharlie with VirusTotal to enhance your data enrichment and detections. You will need a VirusTotal API key in order to utilize this add-on. +You can integrate LimaCharlie with VirusTotal to improve your data enrichment and your detections. You need a VirusTotal API key to use this add-on. VirusTotal Data Caching -The free tier of VirusTotal allows four lookups per minute via the API. LimaCharlie employs a global cache of VirusTotal requests which should significantly reduce costs if you are using VirusTotal at scale. VirusTotal requests are cached for 3 days. +The free tier of VirusTotal allows four lookups each minute through the API. LimaCharlie uses a global cache of VirusTotal requests. The cache can reduce your costs when you make many VirusTotal requests. LimaCharlie keeps VirusTotal requests in the cache for 3 days. -Once you have your VirusTotal API key, you can add it in the Organization integrations section of the LimaCharlie web app. +After you get your VirusTotal API key, add the key in the Organization integrations section of the LimaCharlie web app. ![vt key](../../assets/images/vt-key.png) -Once you have entered your API key, you can then create a rule to perform a lookup of a hash. For example, the following rule will let you know if there is a hit from VirusTotal on a hash with at least two different engines. +After you enter the API key, create a D&R rule that does a lookup of a hash. The rule below matches when at least two VirusTotal engines report a hit on a hash. ```yaml path: event/HASH diff --git a/docs/6-developer-guide/cli.md b/docs/6-developer-guide/cli.md index 651ba962a..36aa61531 100644 --- a/docs/6-developer-guide/cli.md +++ b/docs/6-developer-guide/cli.md @@ -1,13 +1,13 @@ # CLI Extension -The `limacharlie-cli` extension allows you to run [LimaCharlie CLI commands](sdk-overview.md) from within D&R rule response actions. This is useful for automating infrastructure changes (syncing configs, managing rules, etc.) in response to detections. +The `limacharlie-cli` extension lets you run [LimaCharlie CLI commands](sdk-overview.md) from D&R rule response actions. Use it to automate changes to your infrastructure in response to detections, for example to sync configurations or to manage rules. !!! note This page documents the `limacharlie-cli` **extension** for use in D&R rules. For the CLI tool itself, see the [Command Line Interface](sdk-overview.md) page. ## Usage -Trigger a CLI command as a D&R rule response action using `extension request`: +To trigger a CLI command as a D&R rule response action, use `extension request`: ```yaml - action: extension request @@ -20,5 +20,5 @@ Trigger a CLI command as a D&R rule response action using `extension request`: Field descriptions: -- `command_line`: the full CLI command to execute. -- `credentials`: a reference to stored credentials in the [secrets manager](../7-administration/config-hive/secrets.md), used to authenticate the CLI command. +- `command_line`: the full CLI command to run. +- `credentials`: a reference to credentials that are stored in the [secrets manager](../7-administration/config-hive/secrets.md). The CLI command uses them to authenticate. diff --git a/docs/6-developer-guide/extensions/building-extensions.md b/docs/6-developer-guide/extensions/building-extensions.md index 4e6240dcd..d98f53dda 100644 --- a/docs/6-developer-guide/extensions/building-extensions.md +++ b/docs/6-developer-guide/extensions/building-extensions.md @@ -2,61 +2,61 @@ This section is a work in progress -Feel free to reach out to us on the [community forum](https://community.limacharlie.com/) if you'd like to learn more +To learn more, ask a question on the [community forum](https://community.limacharlie.com/) ## Why Extensions? -Building functionality as a LimaCharlie Extension provides you specific convenience: +When you build functionality as a LimaCharlie Extension, you get these advantages: -- **Multi-tenancy**: LC organizations can subscribe to your extension and you can replicate the features you're building across tenants. -- **Credentials handling**: you don't need to store any credentials from LC organizations. Every callback you receive will include an authenticated LimaCharlie SDK for the Organization relevant to the callback, with the permissions you requesed for the extension. -- **Configuration**: you're always welcome to store some configuration wherever the extension lives, but as a convenience LC will provide you with a configuration JSON object for your extension (stored in Hive) and with a callback for you to validate the content of the configuration when a user makes a modification. -- **GUI**: each extension defines its own Schema, a structure indicating to LimaCharlie what actions the extension exposes, how to call it and what to expect as a return value from actions. This information is then automatically interpreted by LimaCharlie to generate a custom user interface for your extension, making it extremely easy to expose new functionality in LimaCharlie without having to build any kind of UI (though you're always free to build one if you'd like). +- **Multi-tenancy**: LC organizations can subscribe to your extension. You can replicate the features that you build across many organizations. +- **Credentials handling**: you do not need to store credentials from LC organizations. Each callback that you receive includes an authenticated LimaCharlie SDK for the Organization of that callback. The SDK has the permissions that you requested for the extension. +- **Configuration**: you can store configuration where the extension runs. LC also gives you a configuration JSON object for your extension, stored in Hive. LC gives you a callback to validate the content of the configuration when a user changes it. +- **GUI**: each extension defines its own Schema. The Schema shows LimaCharlie what actions the extension exposes, how to call them, and what each action returns. LimaCharlie reads the Schema and generates a custom user interface for your extension. You do not need to build a user interface, but you can build one. ### Public/Private Limitations -Anyone can build Extensions for LimaCharlie. The only limit is put on making an Extension public. Private extensions require the owner of the extension to have the `billing.ctrl` and `user.ctrl` permission on an organization in order to subscribe the organization to the private extension. +Anyone can build Extensions for LimaCharlie. The only limit applies when you make an Extension public. To subscribe an organization to a private extension, the owner of the extension needs the `billing.ctrl` and `user.ctrl` permission on that organization. ### Want to take your Extension public? -If you'd like to make your extension public (and/or monetize it), reach out to `answers@limacharlie.io` and we'll help you out. Once public, an extension is visible by everyone and can subscribed by everyone. +To make your extension public, or to monetize it, send a message to `answers@limacharlie.io`. A public extension is visible to everyone, and everyone can subscribe to it. ## High Level Structure ![image.png](../../assets/images/image(252).png) -Extensions are small services that receive webhooks from LimaCharlie. This means building an extension requires exposing a small HTTPS service to the internet. We recommend using something like [Google Cloud Run](https://cloud.google.com/run/), but ultimately you could also use AWS Lambdas or even host on your own hardware. +Extensions are small services that receive webhooks from LimaCharlie. To build an extension, you must expose a small HTTPS service to the internet. LimaCharlie recommends a service such as [Google Cloud Run](https://cloud.google.com/run/), but you can also use AWS Lambdas or host the service on your own hardware. -This https server will communicate with the LimaCharlie cloud according to a simple protocol using JSON. +This HTTPS server communicates with the LimaCharlie cloud with a simple protocol that uses JSON. -That being said, don't worry, you don't need to know the underlying way the extension protocol works as long as you're comfortable with our public implementations. +You do not need to know how the extension protocol works if you use the public implementations. ## Getting Started -Want to get your hands on an example? We recommend using one of the following frameworks to get started. +To start from an example, use one of these frameworks. - Golang: - Python: -For a more step-by-step overview, let's dig into some of the core concepts of building an extension. We will reference Golang since it provides stricter typing, but conceptually it's the same across implementations. +The next sections explain the core concepts to build an extension. The examples use Golang because it has stricter typing, but the concepts are the same in each implementation. ### Extension Definition -To create an extension, start by creating a definition - accessible through the [web interface for your personal add-ons](https://app.limacharlie.io/add-ons/published). +To create an extension, first create a definition. Use the [web interface for your personal add-ons](https://app.limacharlie.io/add-ons/published). -The required aspects of your definition are as follows: +Your definition needs these parts: -- **Destination URL:** this is the HTTPS URL where your extension will be reachable at. -- **Required Extensions:** this is the list of other extensions your extension assumes it will have access to. When an org subscribes and is missing one of those, the user will be prompted to subscribe to these. -- **Shared Secret:** this is an arbitrary string that will be used by LimaCharlie and your extension to sign webhooks to your extension, allowing it to very the authenticity of the hook. Make it something at least 32 characters and random. -- **Extension Flairs:** these are modifiers that will be applied to your extension. Namely the `segment` flair will isolate the resources the extension can access so that it can only see and modify things (like rules) that it has created, making it great for extensions that need a narrow scope, you should enable it unless you know you need it off. The `bulk` flair tells LimaCharlie that it expects to make a lot of API calls to the LC cloud, which will increase the API quota for the extension. -- **Permissions:** the list of permissions this extension requires on each organization subscribed to it. Use the least amount of permissions possible. +- **Destination URL:** the HTTPS URL where your extension is reachable. +- **Required Extensions:** the list of other extensions that your extension needs access to. If an org subscribes and one of them is missing, the user is prompted to subscribe to it. +- **Shared Secret:** an arbitrary string. LimaCharlie and your extension use it to sign webhooks to your extension, so the extension can verify that a hook is authentic. Use a random string of at least 32 characters. +- **Extension Flairs:** modifiers that apply to your extension. The `segment` flair isolates the resources that the extension can access. The extension then sees and changes only the objects, such as rules, that it created. This flair is good for extensions that need a narrow scope, and you should enable it unless you know that you need it off. The `bulk` flair tells LimaCharlie that the extension expects to make many API calls to the LC cloud. This flair increases the API quota for the extension. +- **Permissions:** the list of permissions that this extension needs on each organization that subscribes to it. Use the smallest number of permissions. ### Schema -The Extension Schema is the next important piece of building your extension. It describes what your extension can do and helps define the GUI. +The Extension Schema is the next important part of your extension. It describes what your extension can do, and it helps define the GUI. -Here's an example high-level structure of a schema. +This example shows the high-level structure of a schema. ```json { @@ -95,14 +95,14 @@ Here's an example high-level structure of a schema. ``` **The Field Configuration** - Notice that for both the `config_schema` and the `request_schema` there is a recurring object structure that looks like the following: + The `config_schema` and the `request_schema` both use the same object structure: ```text "fields": { .. }, // key-value pair "requirements": [[]], ``` -While hidden in the example above, each `field` key-value pair shares the same structure and has a minimal implementation as such: +The example above hides the contents of `fields`. Each `field` key-value pair has the same structure. The minimal form is: ```text field_name: { @@ -111,7 +111,7 @@ field_name: { }, ``` -The `requirements` field references the field keys to define whether or not certain fields individually or as a set are required. You can think of the first array to join elements with an AND, while the nested array serves as an OR. +The `requirements` field references the field keys. It defines which fields are required, alone or as a set. The first array joins its elements with an AND. The nested array joins its elements with an OR. For example: - `[['denominator'], ['numerator']]` means: @@ -119,76 +119,76 @@ The `requirements` field references the field keys to define whether or not cert - `[['denominator'], ['numerator', 'default']]` means: (denominator AND ( one of numerator OR default)). -When getting started, we recommend utilizing the simplest data type applicable. This will enable you to get a grasp of the whole extensions framework and allow you to quickly test our your service. Such as `string`, `boolean`, `json`, etc. +When you start, use the simplest data type that applies, such as `string`, `boolean`, or `json`. A simple data type helps you learn the extensions framework and test your service quickly. -Afterwards, we recommend you define the data_type and other optional fields further, so that the UI may adapt to your defined data types. For more details, see the [data types reference](schema-data-types.md) or the [lc-extension SDK source](https://github.com/refractionPOINT/lc-extension/blob/master/common/config_schema.go). +After that, define the data_type and the other optional fields in more detail. The UI then adapts to the data types that you define. For more details, see the [data types reference](schema-data-types.md) or the [lc-extension SDK source](https://github.com/refractionPOINT/lc-extension/blob/master/common/config_schema.go). #### Config Schema (optional) -The config schema is a description of what the extension's config should look like, when stored as a Hive record in the `extension_configuration` Hive for convenience. +The config schema describes the extension's config, as stored in a Hive record in the `extension_configuration` Hive. -Not all extensions will have a configuration, feel free to reach out on the [community forum](https://community.limacharlie.com/) if you need help determining whether or not your extension needs a configuration. +Not all extensions have a configuration. If you need help to decide if your extension needs one, ask on the [community forum](https://community.limacharlie.com/). -At the core, the config schema is simply a list of fields. +The config schema is a list of fields. #### Request Schema -Every Request Schema exists as a key value pair of the request name, and a corresponding schema contents. The critical contents include the following fields: +Each Request Schema is a key-value pair of the request name and the contents of its schema. The critical contents are these fields: -- **is_impersonated**: Whether or not the request impersonates the user through it's authentication -- **is_user_facing**: Whether or not this request should be visisble to the user in the UI. It does not prevent this request from bieng used through the API or as a `supported_action` (more on that later). -- **parameters**: This contains the data_type and other fields *(recall the same fields format as the config schema)* +- **is_impersonated**: shows if the request impersonates the user through its authentication. +- **is_user_facing**: shows if the request is visible to the user in the UI. It does not stop the use of the request through the API or as a `supported_action`. +- **parameters**: contains the data_type and other fields *(the same fields format as the config schema)* -Other optional fields exist to facilitate the user experience, such as: +Other optional fields improve the user experience: - **short_description** - **long_description** -- **messages**: Includes 3 nested fields, `in_progress`, `success`, `error` to provide additional context for each case. +- **messages**: includes 3 nested fields, `in_progress`, `success`, and `error`, to give more context for each case. #### Response Schema (optional) -Each request schema may optionally contain a response schema in the same fields format as a config schema and the request parameters. +Each request schema can contain a response schema. It uses the same fields format as a config schema and the request parameters. -When getting started, we recommend that you skip this until you are ready to refine the extension's GUI, or you wish to clarify that kind of response a user should expect. +Skip the response schema when you start. Add it when you refine the extension's GUI, or when you want to show what kind of response a user gets. ### Callbacks -Callbacks are functionality that an extension can specify whenever some type of event occurs. +Callbacks are code that an extension can specify for each type of event that occurs. #### Configuration Validation Callback -This callback is used by LimaCharlie to check the validity of a change in configuration done in Hive. If the configuration is valid, return success, otherwise you can return an error. +LimaCharlie uses this callback to check a change of configuration in Hive. If the configuration is valid, return success. If it is not valid, return an error. #### Event Callback -Events are events generated by the LimaCharlie platform outside your control. Currently, these 3 events are supported: +The LimaCharlie platform generates events that you do not control. Currently, it supports these 3 events: - **subscribe**: called when an organization subscribes to an extension. - **unsubscribe**: called when an organization unsubscribes from an extension. -- **update**: called once a day per organization subscribed to the extension. It is a convenient way to perform updates to an organization like when needing to update D&R rules used by the extension. +- **update**: called one time each day for each organization that subscribes to the extension. Use it to make updates to an organization, for example to update the D&R rules that the extension uses. -Your extension will only receive these events if they were specified as of-interest in the extension's Schema. +Your extension receives these events only if the extension's Schema specifies them as of-interest. #### Request Callback -The requests are the core way users, D&R rules or other extensions can interact with your extension. You can define one callback per `action`. It is common for an extension to have multiple actions, some public (for user-generated requests) and some private (to be used internally by the extension in the course of doing whatever it does). +Requests are the core way for users, D&R rules, or other extensions to interact with your extension. You can define one callback for each `action`. Many extensions have multiple actions. Some actions are public, for requests that users generate. Other actions are private, and the extension uses them internally. ## Simplified Frameworks -The Golang implementation of Extensions provides 3 different simplified frameworks to make the job of producing a new extension more straight forward in specific cases: +The Golang implementation of Extensions gives you 3 different simplified frameworks. They make a new extension easier to build in specific cases: ### D&R -This simplified framework, found in `dr.go` allows you to package D&R rules as an extension making it easy for you to distribute and update D&R rules to many orgs. Its core mechanism is based on defining the `GetRules()` function and returning a structure like `map[DR-Namespace]map[RuleName]RuleContent`. The simplified framework takes care of the recurring updates and everything else. +This simplified framework is in `dr.go`. It lets you package D&R rules as an extension, and then distribute and update the D&R rules to many orgs. To use it, define the `GetRules()` function and return a structure such as `map[DR-Namespace]map[RuleName]RuleContent`. The simplified framework does the recurring updates and the other work. ### Lookup -Similarl to the D&R simplified framework, but is used to package Lookups. Example: +This framework is similar to the D&R simplified framework, but it packages Lookups. Example: ### CLI -This simplified framework serves to streamline the integration of 3rd party Command Line Interface tools so that they can be automated using LimaCharlie, often bringing bi-directionality to the platform. +This simplified framework integrates 3rd party Command Line Interface tools. LimaCharlie can then automate those tools, which often adds bi-directionality to the platform. -LimaCharlie Extensions allow users to expand and customize their security environments by integrating third-party tools, automating workflows, and adding new capabilities. Organizations subscribe to Extensions, which are granted specific permissions to interact with their infrastructure. Extensions can be private or public, enabling tailored use or broader community sharing. This framework supports scalability, flexibility, and secure, repeatable deployments. +LimaCharlie Extensions let users expand and customize their security environments. An Extension integrates third-party tools, automates workflows, and adds new capabilities. An organization subscribes to an Extension and grants it specific permissions to interact with the infrastructure of the organization. An Extension can be private, for tailored use, or public, to share with the community. This framework supports scalability, flexibility, and secure, repeatable deployments. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment where you manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, and gives you complete control of security operations. This structure supports flexible, multi-tenant setups for managed security providers, and for enterprises that manage many departments or clients. diff --git a/docs/6-developer-guide/extensions/building-ui.md b/docs/6-developer-guide/extensions/building-ui.md index 616ed7ace..7107c3d43 100644 --- a/docs/6-developer-guide/extensions/building-ui.md +++ b/docs/6-developer-guide/extensions/building-ui.md @@ -2,63 +2,63 @@ ## Auto Generated UI -The Extensions UI uses the information provided in the schema to auto-determine it's UI elements, and for most simple extensions, the UI will be able to auto conform based on the bare minimum schema definition alone. However, further customization may be made in the schema for more complex or specific use cases by adjusting the layout, or adjusting the details for a specific field. +The Extensions UI uses the information in the schema to determine its UI elements. For most simple extensions, the minimum schema definition is enough. For more complex or specific use cases, you can customize the schema. Adjust the layout, or adjust the details of a specific field. ### Deconstructing the Page -Generally the top of the extension page will show the extension label and it's short description. If it exists, it will also show a button for quick access to this extension's "associated sensor". +The top of the extension page shows the extension label and its short description. If an "associated sensor" exists for the extension, the page also shows a button for quick access to that sensor. ![ext 1](../../assets/images/ext-1.png) -In the top right, any actions (as defined in your request schema) will be displayed as a dropdown and button. +In the top right, the page shows the actions from your request schema as a dropdown and a button. ![ext 2](../../assets/images/ext-2.png) -Note that there are small changes to this structure depending on the layout selected, however all variations should be intuitive as they do not deviate much from this general page structure. - Beyond this, main content of the page is determined by the layout. +This structure has small changes for each layout that you select, but each variation stays close to the general page structure. + The layout determines the main content of the page. ### Picking Your Layout Type -- `auto` (default layout, it will pick one of the below) +- `auto` (default layout, it picks one of the layouts below) - `config` (use this if you have a configuration) -- `editor` (very specific use-case for editing large code blocks like yaml) +- `editor` (a specific use case, to edit large code blocks such as yaml) - `action` (use this to prioritize certain actions in the UI) - `description` -- `key` (just a variation of description) +- `key` (a variation of description) -For the action, and editor layouts, make sure you define one (or more) default actions as well. The editor UI for the action layout will show all the actions in-page, as opposed to a button on the top right. When set to the editor layout, the UI will automatically run the default action and display the results and a supported action. +For the action and editor layouts, make sure that you also define one or more default actions. For the action layout, the editor UI shows all the actions in the page, and not as a button in the top right. For the editor layout, the UI runs the default action and shows the results and a supported action. ### Form Data Types -Every field has the following optional details to further adjust the UI. +Each field has these optional details to adjust the UI. -- **label**: Add a label if you want a more 'human-legible' label on this field -- **placeholder**: Placeholder text on the input can serve as an example for the user -- **description**: A description for this field can be added that will be available as a tooltip on the UI next to the field label -- **display\_index**: The display index starts at 1 (not 0) and guides the GUI on the order to show the fields. A display index of 1, will display before a display index of 2. -- **default\_value**: A default value for the field, will auto-populate the field with this value +- **label**: Add a label to give this field a more 'human-legible' name +- **placeholder**: Placeholder text in the input gives the user an example +- **description**: Add a description for this field. The UI shows it as a tooltip next to the field label +- **display\_index**: The display index starts at 1, not 0, and tells the GUI the order to show the fields. A field with display index 1 shows before a field with display index 2. +- **default\_value**: A default value for the field. The UI fills the field with this value -Some other configurations that conditionally apply to specific data\_types: +Other configurations apply only to specific data\_types: - **filter**: Available on select primitive data\_types. - **enum\_values**: Details on the available enums, to support the enum data type. - **complex\_enum\_values**: Details to support the complex enum data type. Supports reference links, and categories. -- **object**: An object that contains nested key-value pairs for more fields, and serves to detail the nested fields. +- **object**: An object that contains nested key-value pairs for more fields. It gives the details of the nested fields. -For the complete list of all data types, please see the [page on data types](schema-data-types.md). +For the complete list of data types, see the [page on data types](schema-data-types.md). ## Nuanced Usage -If your extension requires it, there are more opportunities to adjust the UI in order to better guide or facilitate a user on using your extension. +If your extension needs it, you can adjust the UI more, to guide the user and to help the user work with your extension. ### Multiple Layouts as Tabs -In the schema, it is possible to define several views to utilize a combination of layout types. This may be useful in order to guide a user on how you want them to use your extension. +In the schema, you can define several views that use a combination of layout types. Use several views to guide the user on how to use your extension. ![ext 3](../../assets/images/ext-3.png) ### Setting Supported Actions -Functionality for this field is set to be expanded in the future +The functionality of this field will expand in the future -Please feel free to reach out to us on the [community forum](https://community.limacharlie.com/) if you'd like to stay up to date on +To stay up to date, ask a question on the [community forum](https://community.limacharlie.com/) -Supported actions are tied to a request's (also called "actions") response. It allows the response data to be modified and passed along to a follow-up action. This may be useful when operating a dry run, or triggering a workflow. +Supported actions are tied to the response of a request (also called an "action"). They let you change the response data and pass it to a follow-up action. Use them for a dry run, or to trigger a workflow. diff --git a/docs/6-developer-guide/extensions/schema-data-types.md b/docs/6-developer-guide/extensions/schema-data-types.md index 77c32c083..20a6b936e 100644 --- a/docs/6-developer-guide/extensions/schema-data-types.md +++ b/docs/6-developer-guide/extensions/schema-data-types.md @@ -2,17 +2,17 @@ ## All Data Types -The data types in your schema can be subdivided into three categories: Primitives, Code Blocks, and Objects (including records and tables). These data types allow for a cleaner UI and a more intuitive schema. +The data types in your schema have three categories: Primitives, Code Blocks, and Objects (which include records and tables). These data types give a cleaner UI and a more intuitive schema. -For a direct code reference, check out the type definitions in [Go](https://github.com/refractionPOINT/lc-extension/blob/master/common/config_schema.go) or [Python](https://github.com/refractionPOINT/lc-extension/blob/master/python/lcextension/schema.py). +For a direct code reference, see the type definitions in [Go](https://github.com/refractionPOINT/lc-extension/blob/master/common/config_schema.go) or [Python](https://github.com/refractionPOINT/lc-extension/blob/master/python/lcextension/schema.py). ### Before you Start -When getting started, we recommend using the simplest data type applicable for each field in your schema to enable quick and reliable testing of your service. +When you start, use the simplest data type that applies to each field in your schema. A simple data type lets you test your service quickly and reliably. ## Schema Element Fields -Each field in a schema is a `SchemaElement` with the following properties: +Each field in a schema is a `SchemaElement` with these properties: | Field | Type | Description | | --- | --- | --- | @@ -20,7 +20,7 @@ Each field in a schema is a `SchemaElement` with the following properties: | `description` | string | Description of the field | | `placeholder` | string | Placeholder text to display | | `data_type` | string | One of the data types listed below | -| `is_list` | bool | Whether this field accepts a list of items | +| `is_list` | bool | Shows if this field accepts a list of items | | `display_index` | int | Controls the display order in the UI | | `default_value` | any | Default value for optional fields | | `object` | object | If `data_type` is `object` or `record`, contains the nested schema definition | @@ -30,7 +30,7 @@ Each field in a schema is a `SchemaElement` with the following properties: ### Filters -Filters can be applied to restrict valid values for certain data types: +Use filters to restrict the valid values for certain data types: - `min` and `max`: apply to `integer`, `time`, and `duration` types - `whitelist` and `blacklist`: apply to `event_name` and `string` types @@ -38,7 +38,7 @@ Filters can be applied to restrict valid values for certain data types: - `platforms`: applies to `sid` and `platform` types !!! note - Some filter combinations may not be fully supported for all types. Please reach out if a filter does not work as expected. + Not all filter combinations have full support for all types. Ask for help if a filter does not work as you expect. ## Primitives @@ -48,8 +48,8 @@ Filters can be applied to restrict valid values for certain data types: | `text` | Multi-line text input | | `integer` | Numeric integer value | | `bool` | Boolean true/false toggle | -| `enum` | Single selection from a list. Requires the `enum_values` field | -| `complex_enum` | Detailed enum selection with categories, descriptions, and reference links. Requires the `complex_enum_values` field | +| `enum` | Single selection from a list. Needs the `enum_values` field | +| `complex_enum` | Detailed enum selection with categories, descriptions, and reference links. Needs the `complex_enum_values` field | | `sid` | Sensor ID selector from your Organization's sensors | | `oid` | Your Organization's ID | | `platform` | Platform selector | @@ -61,12 +61,12 @@ Filters can be applied to restrict valid values for certain data types: | `url` | URL input | | `domain` | Domain name input | | `event_name` | Event name selector | -| `yara_rule_name` | Selector from your Organization's YARA rules (requires appropriate permissions) | +| `yara_rule_name` | Selector from your Organization's YARA rules (needs the appropriate permissions) | | `secret` | Selector from your Organization's secrets manager | ## Code Blocks -The following code block data types are available: +These code block data types are available: | Name | Description | | --- | --- | @@ -76,15 +76,15 @@ The following code block data types are available: | `code` | Generic code editor | !!! note - YARA rule UI support is limited. Code blocks do not support the `is_list` field. If your extension requires a set of code blocks, wrap them in a key-value pair using the `record` data type (see Objects section below). + YARA rule UI support is limited. Code blocks do not support the `is_list` field. If your extension needs a set of code blocks, put them in a key-value pair with the `record` data type (see the Objects section below). ## Objects and Records -Objects and records provide structured, nested data. Objects group related fields together, while records define key-value collections where keys are user-specified. +Objects and records give structured, nested data. Objects group related fields together. Records define key-value collections in which the user specifies the keys. ### Single Objects -Plain objects allow for nested fields. They are visually the same as if the nested fields were flattened. The parent object's description provides additional context. +Plain objects allow nested fields. In the UI, they look the same as flattened nested fields. The description of the parent object gives more context. ```json { @@ -126,7 +126,7 @@ Lists of objects display as tables in the UI. Enable `is_list` on an object to c ### Records -Records use the `record` data type to define key-value collections where each entry has a user-specified key and a structured value. The `key` field in the object definition specifies the key's name and type. Optional `element_name` and `element_desc` fields provide UI labels for each entry. +Records use the `record` data type to define key-value collections. Each entry has a key that the user specifies and a structured value. The `key` field in the object definition sets the name and the type of the key. The optional `element_name` and `element_desc` fields give UI labels for each entry. ```json { diff --git a/docs/6-developer-guide/frontier-models.md b/docs/6-developer-guide/frontier-models.md index 9a1dda403..4548dc5c0 100644 --- a/docs/6-developer-guide/frontier-models.md +++ b/docs/6-developer-guide/frontier-models.md @@ -1,13 +1,13 @@ # Using the CLI with other Frontier Models -LimaCharlie's deepest AI integration is with Claude — [AI Sessions](../9-ai-sessions/index.md) in the browser and the [Claude Code plugin](mcp-server.md#option-1-claude-code-plugin-recommended) in the terminal. But the platform itself is API-first and model-agnostic: any agent that can run shell commands can operate it through the [`limacharlie` CLI](cli.md), whatever frontier model it runs on. +The deepest AI integration of LimaCharlie is with Claude: [AI Sessions](../9-ai-sessions/index.md) in the browser and the [Claude Code plugin](mcp-server.md#option-1-claude-code-plugin-recommended) in the terminal. But the platform is API-first and model-agnostic. Any agent that can run shell commands can operate the platform through the [`limacharlie` CLI](cli.md), on any frontier model. -The CLI is the recommended integration for agents that aren't Claude Code. Two things make it work especially well: +The CLI is the recommended integration for agents other than Claude Code. Two properties make it work well: -- Every command supports `--ai-help` — help text written specifically for LLM consumption, so an agent can teach itself the platform as it goes -- It is scriptable: cron jobs, CI checks, and bulk operations work the same way for an agent as for a human +- Every command supports `--ai-help`. This help text is written for an LLM, so an agent can learn the platform while it works +- You can script it. Cron jobs, CI checks, and bulk operations work the same way for an agent and for a person -The [MCP server](mcp-server.md) can be added alongside the CLI when you want structured tools with typed results, or used on its own for clients that can't run shell commands. +Add the [MCP server](mcp-server.md) with the CLI when you want structured tools with typed results. You can also use the MCP server alone, for clients that cannot run shell commands. ## The CLI in 60 seconds @@ -17,7 +17,7 @@ limacharlie auth login --oid YOUR_ORG_ID --api-key YOUR_API_KEY limacharlie auth whoami # verify ``` -Or via Docker, with no Python needed: +Or with Docker, which needs no Python: ```bash docker run -v ${HOME}/.limacharlie:/root/.limacharlie:ro refractionpoint/limacharlie:latest whoami @@ -30,7 +30,7 @@ export LC_OID="your-org-id" export LC_API_KEY="your-api-key" ``` -The credentials file supports named environments, selected with `LC_CURRENT_ENV`: +The credentials file supports named environments. Select an environment with `LC_CURRENT_ENV`: ```yaml oid: "default-org-id" @@ -46,13 +46,13 @@ env: ### Scoping the agent's key -Grant only what the agent needs — see [Permission Requirements](mcp-server.md#permission-requirements) for permission sets by use case, and [API Keys](../7-administration/access/api-keys.md) for creating keys. +Grant only the permissions that the agent needs. See [Permission Requirements](mcp-server.md#permission-requirements) for permission sets by use case, and [API Keys](../7-administration/access/api-keys.md) to create keys. -> **Tip:** make two keys — `ai-readonly` and `ai-responder` — and only export the responder key into your shell when you're actively doing response work. Never run an agent's auto-approval mode with a key that holds write permissions like `sensor.task` or `dr.set`. +> **Tip:** Make two keys: `ai-readonly` and `ai-responder`. Export the responder key into your shell only when you do response work. Never run the auto-approval mode of an agent with a key that has write permissions such as `sensor.task` or `dr.set`. ## Teach the model the platform -Regardless of tool, agents perform dramatically better with standing context about the platform: what the key concepts are, how LCQL works, and what the safety rules are. Save the following as a context file your agent loads automatically — `AGENTS.md` is a widely-supported convention (Codex, and Gemini CLI when configured; Claude Code reads `CLAUDE.md`). +For any tool, agents work much better with standing context about the platform: the key concepts, the operation of LCQL, and the safety rules. Save the text below as a context file that your agent loads automatically. `AGENTS.md` is a widely-supported convention (Codex, and Gemini CLI when you configure it; Claude Code reads `CLAUDE.md`). ??? example "LimaCharlie agent context file (click to expand, copy into AGENTS.md)" @@ -198,9 +198,9 @@ Setup for [Google's Gemini CLI](https://github.com/google-gemini/gemini-cli). npm install -g @google/gemini-cli # or: brew install gemini-cli, or: npx @google/gemini-cli ``` -Authenticate by running `gemini` and signing in with Google, or export a `GEMINI_API_KEY` from AI Studio, or use Vertex AI. +To authenticate, run `gemini` and sign in with Google. As an alternative, export a `GEMINI_API_KEY` from AI Studio, or use Vertex AI. -Install the `limacharlie` CLI as shown above — Gemini CLI can run shell commands, so this alone gives the agent access to the full platform. +Install the `limacharlie` CLI as shown above. Gemini CLI can run shell commands, so the CLI alone gives the agent access to the full platform. ### (Optional) Connect the MCP server @@ -211,7 +211,7 @@ gemini mcp add limacharlie https://mcp.limacharlie.io/mcp --transport http \ --header "Authorization: Bearer YOUR_API_KEY:YOUR_ORG_ID" ``` -Or edit `~/.gemini/settings.json` (user-wide) / `/.gemini/settings.json` (project-scoped, wins on conflict) directly: +Or edit `~/.gemini/settings.json` (user-wide) or `/.gemini/settings.json` (project-scoped, wins on conflict) directly: ```json { @@ -229,19 +229,19 @@ Or edit `~/.gemini/settings.json` (user-wide) / `/.gemini/settings.json Notes: -- `httpUrl` selects the streamable HTTP transport, which is what the LimaCharlie server uses. Don't confuse it with `url`, which is SSE. -- The token format is `API_KEY` + colon + `ORG_ID` for an organization key. For multi-org access, exchange a *user* API key for a JWT (see [Connecting AI Assistants](mcp-server.md#option-3-http-mcp-with-keys)) and use `Bearer YOUR_JWT` instead — but JWTs expire after 1 hour, so the static `key:oid` form is more practical for a config file. -- If you keep the token in the user-scoped file, `chmod 600 ~/.gemini/settings.json`. Avoid putting it in a project-scoped settings file that might get committed. +- `httpUrl` selects the streamable HTTP transport, which the LimaCharlie server uses. Do not confuse `httpUrl` with `url`, which is SSE. +- The token format for an organization key is `API_KEY` + colon + `ORG_ID`. For multi-org access, exchange a *user* API key for a JWT (see [Connecting AI Assistants](mcp-server.md#option-3-http-mcp-with-keys)) and use `Bearer YOUR_JWT` instead. But JWTs expire after 1 hour, so the static `key:oid` form is more practical for a config file. +- If you keep the token in the user-scoped file, run `chmod 600 ~/.gemini/settings.json`. Do not put the token in a project-scoped settings file, which someone can commit. -Verify: start `gemini` and run `/mcp` — you should see `limacharlie` as `CONNECTED` with its tool list. +To confirm the connection, start `gemini` and run `/mcp`. The output shows `limacharlie` as `CONNECTED` with its tool list. -The full server exposes a large number of tools, which costs context. Use `includeTools` to allowlist what you need, or `excludeTools` to cut what you don't (for example `"excludeTools": ["delete_sensor", "delete_org_note", "remove_org_user"]`). +The full server exposes many tools, and the tool list costs context. Use `includeTools` to allowlist the tools that you need, or `excludeTools` to remove the tools that you do not need (for example `"excludeTools": ["delete_sensor", "delete_org_note", "remove_org_user"]`). -> **Warning:** do not set `"trust": true` for the LimaCharlie server. Keeping trust off means Gemini asks before each tool call — exactly what you want when tools can isolate machines from the network. +> **Warning:** Do not set `"trust": true` for the LimaCharlie server. When trust is off, Gemini asks before each tool call. This is necessary because the tools can isolate machines from the network. ### Context file -Gemini CLI automatically loads context files named `GEMINI.md` from `~/.gemini/GEMINI.md`, the project root, and directories it works in. Save the [agent context file](#teach-the-model-the-platform) into your working directory as `GEMINI.md`. Or, to share one context file across tools, configure Gemini to also read `AGENTS.md` — in settings.json: +Gemini CLI loads context files named `GEMINI.md` automatically from `~/.gemini/GEMINI.md`, the project root, and the directories where it works. Save the [agent context file](#teach-the-model-the-platform) into your working directory as `GEMINI.md`. To share one context file between tools, configure Gemini to read `AGENTS.md` also. In settings.json: ```json { @@ -249,7 +249,7 @@ Gemini CLI automatically loads context files named `GEMINI.md` from `~/.gemini/G } ``` -Confirm it loaded with `/memory show`. +Confirm the load with `/memory show`. ### Custom slash commands @@ -275,7 +275,7 @@ take any response actions. """ ``` -Then inside Gemini, run `/lc:triage` or `/lc:hunt 8.8.8.8`. +Then, in Gemini, run `/lc:triage` or `/lc:hunt 8.8.8.8`. ### Headless / scripted usage @@ -286,7 +286,7 @@ gemini -p "Use LimaCharlie tools to summarize the last 24h of detections by cate --output-format text > /tmp/lc-daily-report.md ``` -`--output-format json` gives you `{response, stats}` for piping into other tools; `stream-json` emits NDJSON events. The default approval mode requires confirmation for tool calls, which blocks headless runs — for unattended read-only jobs, either allowlist just the read tools you need (`tools.allowed` in settings, or `includeTools` on the MCP server) or — only with a read-only API key — `--approval-mode yolo`. Never combine yolo mode with a key that has `sensor.task` or `dr.set`. +`--output-format json` gives you `{response, stats}` for a pipe into other tools. `stream-json` emits NDJSON events. The default approval mode needs confirmation for tool calls, which blocks headless runs. For unattended read-only jobs, allowlist only the read tools that you need (`tools.allowed` in settings, or `includeTools` on the MCP server). As an alternative, use `--approval-mode yolo`, but only with a read-only API key. Never combine yolo mode with a key that has `sensor.task` or `dr.set`. ## OpenAI Codex @@ -298,20 +298,20 @@ Setup for [OpenAI's Codex CLI](https://github.com/openai/codex). npm install -g @openai/codex # or: brew install --cask codex ``` -Authenticate with `codex login` (ChatGPT account, browser OAuth; `--device-auth` for headless boxes) or an API key: `echo $OPENAI_API_KEY | codex login --with-api-key`. +Authenticate with `codex login` (ChatGPT account, browser OAuth; `--device-auth` for headless machines) or an API key: `echo $OPENAI_API_KEY | codex login --with-api-key`. -Install the `limacharlie` CLI as shown above. One caveat: Codex's default sandbox blocks outbound network, so for `limacharlie` CLI calls to work you'll either approve escalations as they come, or set: +Install the `limacharlie` CLI as shown above. The default sandbox of Codex blocks the outbound network. To make `limacharlie` CLI calls work, approve each escalation, or set: ```toml [sandbox_workspace_write] network_access = true ``` -(MCP tools, if you add them below, are unaffected — they run outside the sandbox.) +(The sandbox does not affect the MCP tools that you add below. They run outside the sandbox.) ### (Optional) Connect the MCP server -Codex configures MCP servers in `~/.codex/config.toml`. The LimaCharlie hosted server is a remote streamable-HTTP server, configured with `url`: +Codex configures MCP servers in `~/.codex/config.toml`. The hosted LimaCharlie server is a remote streamable-HTTP server. Configure it with `url`: ```toml [mcp_servers.limacharlie] @@ -327,13 +327,13 @@ Then in your shell profile: export LC_MCP_TOKEN="YOUR_API_KEY:YOUR_ORG_ID" ``` -`bearer_token_env_var` tells Codex to read the token from the environment and send `Authorization: Bearer ` — your secret stays out of the config file. The token format is `API_KEY` + colon + `ORG_ID` for an organization API key; for multi-org access, exchange a *user* API key for a JWT instead (see [Connecting AI Assistants](mcp-server.md#option-3-http-mcp-with-keys)). +`bearer_token_env_var` tells Codex to read the token from the environment and to send `Authorization: Bearer `. Your secret stays out of the config file. The token format for an organization API key is `API_KEY` + colon + `ORG_ID`. For multi-org access, exchange a *user* API key for a JWT instead (see [Connecting AI Assistants](mcp-server.md#option-3-http-mcp-with-keys)). -Verify: start `codex` and type `/mcp` — you should see `limacharlie` connected with its tools. Outside a session: `codex mcp list`. +To confirm the connection, start `codex` and type `/mcp`. The output shows `limacharlie` connected with its tools. Outside a session, run `codex mcp list`. ### Guardrails -Codex lets you gate MCP tools per server and per tool. Auto-approve reads, prompt on everything else: +Codex lets you gate MCP tools for each server and for each tool. Auto-approve the reads, and prompt for all other tools: ```toml [mcp_servers.limacharlie] @@ -352,17 +352,17 @@ approval_mode = "approve" approval_mode = "approve" ``` -Or hard-disable destructive tools entirely: +Or disable the destructive tools completely: ```toml disabled_tools = ["delete_sensor", "delete_org_note", "remove_org_user"] ``` -If the tool count is heavy on context, allowlist with `enabled_tools = [...]`. +If the tool count costs too much context, allowlist tools with `enabled_tools = [...]`. ### Context file -Codex automatically loads `AGENTS.md` from `~/.codex/AGENTS.md` (global), your repo root, and the working directory — later files win. Save the [agent context file](#teach-the-model-the-platform) as `AGENTS.md` in your working directory. +Codex loads `AGENTS.md` automatically from `~/.codex/AGENTS.md` (global), your repo root, and the working directory. The later files win. Save the [agent context file](#teach-the-model-the-platform) as `AGENTS.md` in your working directory. ### Headless / scripted usage @@ -372,11 +372,11 @@ codex exec -a never --sandbox read-only \ -o /tmp/lc-daily-report.md ``` -Useful flags: `--json` (NDJSON event stream), `-o report.md` (write the final message to a file), `--sandbox read-only`, `-a never` (no approval prompts — only safe with a read-only LimaCharlie key). For finer command-level control (for example, allow `limacharlie search` unprompted but gate everything else), see Codex [execpolicy rules](https://developers.openai.com/codex/rules) in `~/.codex/rules/`. +Useful flags: `--json` (NDJSON event stream), `-o report.md` (writes the final message to a file), and `--sandbox read-only`. The `-a never` flag removes the approval prompts. Use it only with a read-only LimaCharlie key. For control of each command, see the Codex [execpolicy rules](https://developers.openai.com/codex/rules) in `~/.codex/rules/`. For example, you can allow `limacharlie search` with no prompt but gate all other commands. ## Common tasks -Each task below shows the **prompt** you'd give your agent, and **what's underneath** — the CLI commands and/or MCP tools the agent will (or should) reach for. Knowing the underlying calls helps you verify the agent did the right thing. Prompts work identically in Claude Code, Gemini CLI, and Codex. +Each task below shows the **prompt** that you give to your agent, and **what's underneath**: the CLI commands and the MCP tools that the agent uses. The underlying calls help you check that the agent did the correct operation. The prompts work the same way in Claude Code, Gemini CLI, and Codex. ### Fleet visibility @@ -389,11 +389,11 @@ limacharlie sensor list limacharlie sensor list --selector 'plat == windows' ``` -Or MCP `list_sensors` / `get_online_sensors`. For a sensor deep-dive (processes, network connections, autoruns), the MCP live-tasking tools `get_processes`, `get_network_connections`, and `get_autoruns` need the sensor online and a key with `sensor.task`. +Or MCP `list_sensors` / `get_online_sensors`. To examine one sensor in detail (processes, network connections, autoruns), use the MCP live-tasking tools `get_processes`, `get_network_connections`, and `get_autoruns`. These tools need the sensor to be online and a key with `sensor.task`. ### Querying telemetry (LCQL) -LCQL queries have four pipe-separated parts (plus optional projection) — see [Data & Queries](../4-data-queries/index.md) for the full reference and [LCQL Examples](../4-data-queries/lcql-examples.md) for more queries: +An LCQL query has four pipe-separated parts and an optional projection. See [Data & Queries](../4-data-queries/index.md) for the full reference and [LCQL Examples](../4-data-queries/lcql-examples.md) for more queries: ```text | | | [ | ] @@ -417,15 +417,15 @@ LCQL queries have four pipe-separated parts (plus optional projection) — see [ -24h | plat == windows | CODE_IDENTITY | event/SIGNATURE/FILE_IS_SIGNED != 1 | event/FILE_PATH as Path event/HASH as Hash COUNT_UNIQUE(Hash) as Count GROUP BY(Path Hash) ``` -Run these with `limacharlie search run` or MCP `run_lcql_query`; `generate_lcql_query` has the platform build the query for you. +Run these queries with `limacharlie search run` or MCP `run_lcql_query`. With `generate_lcql_query`, the platform builds the query for you. -> **Cost tip:** LCQL queries scan the data lake. Have the agent use `dryrun` in `limacharlie search` (or MCP `validate_lcql_query` / `estimate_lcql_query`) before running broad queries. +> **Cost tip:** LCQL queries scan the data lake. Tell the agent to use `dryrun` in `limacharlie search` (or MCP `validate_lcql_query` / `estimate_lcql_query`) before it runs broad queries. ### Detections > "Pull detections from the last 24 hours, group them by rule and severity, and tell me which ones look like real incidents vs noise. For anything interesting, pull the surrounding telemetry." -Underneath: MCP `get_historic_detections` → `get_historic_events` for context. The key needs `insight.det.get` / `insight.evt.get`. To watch live instead: +Underneath: MCP `get_historic_detections` → `get_historic_events` for context. The key needs `insight.det.get` / `insight.evt.get`. To watch the live stream instead: ```bash limacharlie stream detections # also: stream events --tag vip, stream audit @@ -437,7 +437,7 @@ For an IOC sweep ("search the whole org for this hash / domain / IP over the las > "Write a D&R rule that detects certutil.exe being used to download files, tags the sensor, and reports the detection. Validate it before showing me." -Underneath — the agent drafts the YAML and manages it with the CLI: +Underneath: the agent writes the YAML and manages it with the CLI: ```bash limacharlie dr list @@ -445,15 +445,15 @@ limacharlie dr set --key my-rule --input-file rule.yaml --enabled limacharlie dr disable --key my-rule ``` -With MCP connected, it can also use `generate_dr_rule_detection` + `generate_dr_rule_respond`, then `validate_dr_rule_components`, and deploy with `set_rule` (needs `dr.set`). Either way, keep deployment behind an approval prompt. Before deploying, test against history: `limacharlie replay --help` replays historical telemetry through a rule. +If MCP is connected, the agent can also use `generate_dr_rule_detection` and `generate_dr_rule_respond`, then `validate_dr_rule_components`, and deploy with `set_rule` (needs `dr.set`). In both methods, keep the deployment behind an approval prompt. Test against history before you deploy: `limacharlie replay --help` replays historical telemetry through a rule. ### Response actions ⚠️ -These change endpoint state. Keep them behind approval prompts (see the Gemini and Codex guardrail sections above), use a key with `sensor.task` only when needed, and have the agent confirm the exact sensor ID with you first. +These actions change the state of an endpoint. Keep them behind approval prompts (see the Gemini and Codex guardrail sections above). Use a key with `sensor.task` only when you need it. Tell the agent to confirm the exact sensor ID with you first. > "FINANCE-03 looks compromised. Confirm its sensor ID with me, then isolate it from the network." -Underneath: MCP `isolate_network` (verify with `is_isolated`, undo with `rejoin_network`). Isolation blocks all traffic except to the LimaCharlie cloud and persists across reboots. For evidence collection first: `get_processes`, `get_network_connections`, `get_autoruns`; for deeper forensics, `collect_velociraptor_artifact` and the artifacts API (`list_artifacts` / `get_artifact`, or `limacharlie artifact --help`). +Underneath: MCP `isolate_network` (check with `is_isolated`, undo with `rejoin_network`). Isolation blocks all traffic except traffic to the LimaCharlie cloud, and it stays active after a reboot. To collect evidence first, use `get_processes`, `get_network_connections`, and `get_autoruns`. For deeper forensics, use `collect_velociraptor_artifact` and the artifacts API (`list_artifacts` / `get_artifact`, or `limacharlie artifact --help`). ### Infrastructure-as-Code @@ -464,11 +464,11 @@ limacharlie sync pull --oid $LC_OID limacharlie sync push --dry-run --oid $LC_OID --config lc-config.yaml # always dry-run first ``` -This pairs well with a coding agent: keep your org config in a repo, let the agent edit the YAML, review the diff, `sync push --dry-run`, then apply. +A coding agent works well with this method. Keep your org config in a repo. Let the agent edit the YAML. Review the diff. Run `sync push --dry-run`. Then apply the config. ## Prompt library -Copy-paste starting points for the workflows above. +Copy these prompts as starting points for the workflows above. ### Orientation (start here on a new org) @@ -566,37 +566,37 @@ Edit the pulled config to add a new D&R rule (file: rules/encoded-powershell.yam ### Gemini CLI: `/mcp` shows `DISCONNECTED` -- Check the header format. It must be exactly `Authorization: Bearer YOUR_API_KEY:YOUR_ORG_ID` — API key first, then a colon, then the org ID (a UUID). Swapping them is the most common mistake. -- Make sure you used `httpUrl` (streamable HTTP), not `url` (SSE), in settings.json. -- Confirm the key still exists in **Access Management → REST API** and wasn't revoked. +- Check the header format. It must be exactly `Authorization: Bearer YOUR_API_KEY:YOUR_ORG_ID`: the API key first, then a colon, then the org ID (a UUID). The most common mistake is to reverse the two values. +- Make sure that you used `httpUrl` (streamable HTTP), not `url` (SSE), in settings.json. +- Confirm that the key is still in **Access Management → REST API** and that nobody revoked it. - Run `gemini` with `-d` (debug) for connection details. ### Codex: server missing from `/mcp` -- `codex mcp get limacharlie` — does the config parse and show what you expect? -- If you used `bearer_token_env_var`, the env var must be exported in the shell that launched Codex. Check with `echo $LC_MCP_TOKEN` — it should print `key:oid`. -- Raise `startup_timeout_sec` (default 10) if you're on a slow link. +- Run `codex mcp get limacharlie`. Check that the config parses and shows the expected values. +- If you used `bearer_token_env_var`, you must export the env var in the shell that started Codex. Check with `echo $LC_MCP_TOKEN`. It must print `key:oid`. +- If your link is slow, increase `startup_timeout_sec` (default 10). ### HTTP 401 on specific tool calls / REST endpoints -The key authenticated fine but lacks a permission. Match the failing operation to the permission tables in [Permission Requirements](mcp-server.md#permission-requirements) — for example, LCQL queries need `insight.evt.get` and live sensor commands need `sensor.task` — and add it to the key in the web app. Changes take effect immediately; reconnect the MCP server (or restart the CLI session) if results seem stale. +The key authenticated correctly but does not have a permission. Match the operation that failed to the permission tables in [Permission Requirements](mcp-server.md#permission-requirements). For example, LCQL queries need `insight.evt.get`, and live sensor commands need `sensor.task`. Add the permission to the key in the web app. The change takes effect immediately. If the results seem stale, reconnect the MCP server or restart the CLI session. ### JWT calls suddenly failing after working -JWTs expire after **one hour**. Re-exchange the API key for a fresh JWT (see [API Keys](../7-administration/access/api-keys.md)) or switch to the static `key:oid` bearer format for MCP, which doesn't expire. +JWTs expire after **one hour**. Exchange the API key for a new JWT (see [API Keys](../7-administration/access/api-keys.md)), or change to the static `key:oid` bearer format for MCP, which does not expire. ### `limacharlie` CLI says unauthenticated -- `limacharlie auth whoami` — what identity does it think you have? -- Precedence: `LC_OID`/`LC_API_KEY` env vars override `~/.limacharlie`. A stale env var in your profile silently wins over a fresh `auth login`. -- Multiple orgs: `limacharlie auth list-orgs` then `limacharlie auth use-org `, or set `LC_CURRENT_ENV` to a named environment from the credentials file. +- Run `limacharlie auth whoami` to see which identity the CLI uses. +- Precedence: the `LC_OID` and `LC_API_KEY` env vars override `~/.limacharlie`. An old env var in your profile wins over a new `auth login`, with no message. +- For multiple orgs, run `limacharlie auth list-orgs`, then `limacharlie auth use-org `. Or set `LC_CURRENT_ENV` to a named environment from the credentials file. ### Live-sensor tools return nothing / time out -Tools like `get_processes`, `get_network_connections`, and `yara_scan_process` task the actual endpoint — the sensor must be **online**. Check with `is_online` (MCP) or `limacharlie sensor list`. For offline sensors, queue commands via the Reliable Tasking extension (`reliable_tasking` MCP tool) instead. Historic-data tools (`run_lcql_query`, `get_historic_detections`, `get_historic_events`) work regardless of sensor state — they hit the data lake. +Tools such as `get_processes`, `get_network_connections`, and `yara_scan_process` task the endpoint, so the sensor must be **online**. Check with `is_online` (MCP) or `limacharlie sensor list`. For offline sensors, queue the commands with the Reliable Tasking extension (`reliable_tasking` MCP tool) instead. The historic-data tools (`run_lcql_query`, `get_historic_detections`, `get_historic_events`) work in any sensor state, because they read the data lake. ### The agent picks wrong tools or writes bad LCQL -- Make sure the [context file](#teach-the-model-the-platform) loaded: `/memory show` in Gemini; for Codex, verify `AGENTS.md` is in the repo root or `~/.codex/`. -- LCQL help: the platform can write queries for the agent — tell it to use `generate_lcql_query` and `validate_lcql_query` rather than free-handing syntax. +- Make sure that the agent loaded the [context file](#teach-the-model-the-platform). In Gemini, run `/memory show`. For Codex, check that `AGENTS.md` is in the repo root or in `~/.codex/`. +- LCQL help: the platform can write queries for the agent. Tell the agent to use `generate_lcql_query` and `validate_lcql_query` instead of manual syntax. - CLI usage: remind the agent that every `limacharlie` command supports `--ai-help`. diff --git a/docs/6-developer-guide/grant-program.md b/docs/6-developer-guide/grant-program.md index 0252f5961..6c53fcc16 100644 --- a/docs/6-developer-guide/grant-program.md +++ b/docs/6-developer-guide/grant-program.md @@ -1,7 +1,7 @@ # Developer Grant Program -The Developer Grant Program is designed to help fuel the growth of LimaCharlie add-ons and other projects that utilize the LimaCharlie platform. To help developers with their projects, we offer a $1,000 credit that can be applied towards using LimaCharlie to develop any kind of project you want. +The Developer Grant Program helps the growth of LimaCharlie add-ons and other projects that use the LimaCharlie platform. LimaCharlie gives developers a $1,000 credit. You can apply this credit to any project that you build with LimaCharlie. -If you are looking to commercialize an idea we can help you get it into our marketplace and if there is traction there, we can further support you in growing. +If you want to commercialize an idea, LimaCharlie can help you put it in the marketplace. If the idea gets traction there, LimaCharlie can give more support to grow it. -Interested parties can [apply for the grant program](https://limacharlie.io/grant-program). +To take part, [apply for the grant program](https://limacharlie.io/grant-program). diff --git a/docs/6-developer-guide/index.md b/docs/6-developer-guide/index.md index 6f6a7952a..337c7f2e1 100644 --- a/docs/6-developer-guide/index.md +++ b/docs/6-developer-guide/index.md @@ -17,7 +17,7 @@ Programmatic access to LimaCharlie: ## AI Assistants -Connect AI assistants to LimaCharlie via the Claude Code Plugin or MCP: +Connect AI assistants to LimaCharlie with the Claude Code Plugin or MCP: - [Connecting AI Assistants](mcp-server.md) diff --git a/docs/6-developer-guide/mcp-server.md b/docs/6-developer-guide/mcp-server.md index 66843ed8d..6003aead6 100644 --- a/docs/6-developer-guide/mcp-server.md +++ b/docs/6-developer-guide/mcp-server.md @@ -1,9 +1,9 @@ # Connecting AI Assistants -LimaCharlie can be accessed by AI assistants in three ways: +AI assistants can access LimaCharlie in three ways: - **Claude Code Plugin** — Uses the `limacharlie` CLI for all operations, with pre-built skills and workflows (recommended) -- **CLI with other Frontier Models** — The same `limacharlie` CLI driven by Gemini CLI, OpenAI Codex, or any shell-capable agent; the recommended path when you're not using Claude Code. See [Using the CLI with other Frontier Models](frontier-models.md) +- **CLI with other Frontier Models** — The same `limacharlie` CLI, driven by Gemini CLI, OpenAI Codex, or another agent that can run shell commands. Use this method if you do not use Claude Code. See [Using the CLI with other Frontier Models](frontier-models.md) - **MCP Server** — A [Model Context Protocol](https://modelcontextprotocol.io/) endpoint for any MCP-compatible AI client ## Setup Options @@ -12,18 +12,18 @@ Choose the setup method based on your AI client: | Method | Auth Type | Multi-Org | |--------|-----------|-----------| -| **Option 1:** Claude Code Plugin | OAuth via CLI (browser login) | Yes | +| **Option 1:** Claude Code Plugin | OAuth through the CLI (browser login) | Yes | | **Option 2:** HTTP MCP with OAuth | OAuth (browser login) | Yes | | **Option 3:** HTTP MCP with JWT | User API Key → JWT | Yes | | **Option 3:** HTTP MCP with API Key | Org API Key | No | -**Recommendation:** Use Option 1 if you're using Claude Code — it provides the richest experience with pre-built skills and workflows, and uses the `limacharlie` CLI for all operations. If not using Claude Code, check whether your MCP client supports OAuth and use Option 2. Fall back to Option 3 (JWT or API key) only if OAuth isn't available in your client. +**Recommendation:** Use Option 1 if you use Claude Code. Option 1 supplies pre-built skills and workflows, and uses the `limacharlie` CLI for all operations. If you do not use Claude Code, check if your MCP client supports OAuth, then use Option 2. Use Option 3 (JWT or API key) only if your client does not support OAuth. --- ## Option 1: Claude Code Plugin (Recommended) -The LimaCharlie plugin provides the richest experience with pre-built skills, workflows, and multi-org support. Unlike Options 2–3, this plugin does **not** use an MCP server—it uses the `limacharlie` CLI for all API operations, which is automatically installed on session start. +The LimaCharlie plugin supplies pre-built skills, workflows, and multi-org support. Unlike Options 2–3, this plugin does **not** use an MCP server. It uses the `limacharlie` CLI for all API operations, and it installs the CLI automatically when a session starts. ### Installation @@ -34,7 +34,7 @@ Run these commands in Claude Code: /plugin install lc-essentials@lc-marketplace ``` -The plugin automatically installs the `limacharlie` CLI when a session starts. If auto-installation fails, install it manually: +The plugin installs the `limacharlie` CLI automatically when a session starts. If the automatic installation fails, install the CLI manually: ```bash pipx install limacharlie # preferred (isolated environment) @@ -44,17 +44,17 @@ pip install --user limacharlie # fallback ### Authentication -Authenticate the CLI via OAuth: +Authenticate the CLI with OAuth: ```bash limacharlie auth login ``` -This opens your browser for LimaCharlie OAuth. Credentials persist across sessions automatically. +The command opens your browser for LimaCharlie OAuth. The CLI keeps the credentials for later sessions automatically. ### Verify Setup -Run the following to confirm authentication and list your organizations: +Run this command to confirm the authentication and to list your organizations: ```bash limacharlie org list --output yaml @@ -72,24 +72,24 @@ If your MCP client supports OAuth authentication, configure it to use the LimaCh https://mcp.limacharlie.io/mcp ``` -The client will handle the OAuth flow automatically, prompting you to authenticate via browser. This provides the same multi-org access as the Claude Code plugin. +The client does the OAuth flow automatically and asks you to authenticate in a browser. This method gives the same multi-org access as the Claude Code plugin. -Consult your MCP client's documentation to determine if OAuth is supported. +Read the documentation of your MCP client to find if it supports OAuth. --- ## Option 3: HTTP MCP with Keys -Use this method when your MCP client doesn't support OAuth. +Use this method when your MCP client does not support OAuth. ### Multi-Org Access (JWT) -To access all organizations associated with your user account, authenticate using a JWT generated from your **User API Key**. +To access all organizations of your user account, authenticate with a JWT that you generate from your **User API Key**. #### Step 1: Get your User API Key 1. Go to [app.limacharlie.io](https://app.limacharlie.io) → **User Profile** (top-right menu) -2. Navigate to **API Keys** +2. Go to **API Keys** 3. Generate a User API Key #### Step 2: Generate a JWT @@ -100,7 +100,7 @@ curl -X POST "https://jwt.limacharlie.io" \ -d "uid=YOUR_USER_ID&secret=YOUR_USER_API_KEY" ``` -This returns a JWT valid for 1 hour. See [API Keys](../7-administration/access/api-keys.md) for details. +The command returns a JWT that is valid for 1 hour. See [API Keys](../7-administration/access/api-keys.md) for details. #### Step 3: Configure your MCP client @@ -118,19 +118,19 @@ This returns a JWT valid for 1 hour. See [API Keys](../7-administration/access/a } ``` -> **Note:** JWTs expire after 1 hour. You'll need to regenerate and update your configuration periodically. +> **Note:** JWTs expire after 1 hour. Generate a new JWT and update your configuration at regular intervals. --- ### Single-Org Access (API Key) -For simpler single-organization access, use an Organization API Key directly. +For single-organization access, use an Organization API Key directly. **Get your credentials:** 1. Go to your organization in [app.limacharlie.io](https://app.limacharlie.io) → **Access Management** → **REST API** -2. Generate an API key with appropriate permissions -3. Note your Organization ID (OID) from the URL or org settings +2. Generate an API key with the necessary permissions +3. Get your Organization ID (OID) from the URL or from the org settings **Claude Code:** @@ -166,18 +166,18 @@ Ask your AI assistant: *"List my online sensors"* ## Permission Requirements -The MCP server enforces the same permission model as the LimaCharlie REST API. The operations available to the AI assistant depend on the permissions granted to the authenticated user or API key. +The MCP server enforces the same permission model as the LimaCharlie REST API. The permissions of the authenticated user or API key control which operations the AI assistant can do. ### How Permissions Work by Auth Method | Auth Method | Permission Source | |-------------|------------------| -| **OAuth / JWT** | Inherits your user permissions for each organization. You can only perform actions your user account is authorized for. | -| **Org API Key** | Uses the permissions assigned to the API key at creation time. Scoped to a single organization. | +| **OAuth / JWT** | Inherits your user permissions for each organization. You can do only the actions that your user account is authorized to do. | +| **Org API Key** | Uses the permissions that you assign to the API key when you create it. Scoped to one organization. | ### Permission Enforcement -The API enforces permissions strictly. Any operation attempted without the required permission will fail with a `401` error that specifies the missing privilege. The AI assistant will surface these errors and indicate which permission is needed. +The API enforces permissions strictly. An operation without the necessary permission fails with a `401` error that specifies the missing privilege. The AI assistant shows these errors and tells you which permission is necessary. ### Recommended Permissions by Use Case @@ -185,7 +185,7 @@ The MCP server organizes its tools into capability profiles. Grant permissions b #### Read-Only Investigation -For querying telemetry and reviewing configurations without making changes: +To query telemetry and review configurations without changes: | Permission | Purpose | |------------|---------| @@ -202,7 +202,7 @@ For querying telemetry and reviewing configurations without making changes: #### Threat Response -For investigating and responding to incidents (includes all read-only permissions above, plus): +To investigate and respond to incidents (includes all the read-only permissions above, plus): | Permission | Purpose | |------------|---------| @@ -212,28 +212,28 @@ For investigating and responding to incidents (includes all read-only permission #### Detection Engineering -For creating and managing detection rules (includes read-only permissions above, plus): +To create and manage detection rules (includes the read-only permissions above, plus): | Permission | Purpose | |------------|---------| -| `dr.set` | Create and modify D&R rules | +| `dr.set` | Create and change D&R rules | | `dr.del` | Delete D&R rules | | `fp.ctrl` | Create and manage false positive rules | -| `yara.set` | Create and modify YARA rules | +| `yara.set` | Create and change YARA rules | | `yara.del` | Delete YARA rules | -| `lookup.set` | Create and modify lookup tables | +| `lookup.set` | Create and change lookup tables | | `lookup.del` | Delete lookup tables | #### Platform Administration -For full platform management (includes all of the above, plus): +To manage the full platform (includes all of the above, plus): | Permission | Purpose | |------------|---------| | `output.list`, `output.set`, `output.del` | Manage output configurations | | `secret.get`, `secret.set`, `secret.del` | Manage secrets | | `ikey.list`, `ikey.set`, `ikey.del` | Manage installation keys | -| `org.conf.get`, `org.conf.set` | View and modify organization configuration | +| `org.conf.get`, `org.conf.set` | View and change organization configuration | | `ext.request`, `ext.conf.get`, `ext.conf.set` | Manage extensions | | `playbook.get`, `playbook.set`, `playbook.del` | Manage playbooks | | `cloudsensor.get`, `cloudsensor.set`, `cloudsensor.del` | Manage cloud sensor adapters | @@ -247,17 +247,17 @@ For full platform management (includes all of the above, plus): 2. Click the Edit icon next to the user 3. Assign permissions individually or select a pre-set permission scheme -Newly added users start with **Unset** privileges (basic org information only). Always configure appropriate permissions after adding a user. See [User Access](../7-administration/access/user-access.md) for details. +A new user starts with **Unset** privileges and sees only basic org information. Always configure the necessary permissions after you add a user. See [User Access](../7-administration/access/user-access.md) for details. **For Organization API keys:** 1. Go to **Access Management** → **REST API** 2. Create a new API key and select the required permissions -3. Use the tables above to determine which permissions to grant based on your intended use case +3. Use the tables above to find which permissions to grant for your use case -> **Tip:** Follow the principle of least privilege — grant only the permissions needed for your use case. For read-only investigation workflows, avoid granting write permissions like `dr.set` or `sensor.task`. +> **Tip:** Obey the principle of least privilege. Grant only the permissions that your use case needs. For read-only investigation workflows, do not grant write permissions such as `dr.set` or `sensor.task`. > -> **Note:** Permissions granted through [Organization Groups](../7-administration/access/user-access.md#access-via-organization-groups) are additive on top of per-organization permissions and cannot reduce existing access. +> **Note:** Permissions from [Organization Groups](../7-administration/access/user-access.md#access-via-organization-groups) add to the per-organization permissions. They cannot reduce existing access. For the full list of available permissions, see the [Permissions Reference](../8-reference/permissions.md). @@ -265,11 +265,11 @@ For the full list of available permissions, see the [Permissions Reference](../8 ## Capabilities -Once connected, AI assistants can: +After you connect an AI assistant, it can do these operations: -- **Query telemetry** — Search historical sensor data using LCQL +- **Query telemetry** — Search historical sensor data with LCQL - **Investigate endpoints** — Inspect processes, network connections, files, and more -- **Manage detections** — Create and modify D&R rules, YARA rules, and false positive rules +- **Manage detections** — Create and change D&R rules, YARA rules, and false positive rules - **Take response actions** — Isolate endpoints, kill processes, manage tags - **Search threat intelligence** — Query IOCs and map to MITRE ATT&CK - **Configure the platform** — Manage outputs, adapters, secrets, and playbooks @@ -280,13 +280,13 @@ Once connected, AI assistants can: | Issue | Solution | |-------|----------| -| "Unauthorized" error | Verify your API key and OID are correct. Ensure the API key has the required permissions for the operation — the error message will specify the missing privilege. | +| "Unauthorized" error | Check that your API key and OID are correct. Make sure that the API key has the necessary permissions for the operation. The error message specifies the missing privilege. | | Plugin not appearing | Restart Claude Code after installation. | | OAuth login fails | Clear browser cookies for limacharlie.io and try again. | | CLI not found (plugin) | The plugin auto-installs the `limacharlie` CLI on session start. If it fails, install manually: `pipx install limacharlie` | -| CLI not authenticated | Run `limacharlie auth login` to authenticate via browser OAuth. | -| MCP tools not loading (Options 2–3) | Verify the MCP server URL and authentication headers are correct. | -| "Missing privilege" on specific operations | The authenticated user or API key lacks the required permission. See [Permission Requirements](#permission-requirements) to identify which permissions to grant. | +| CLI not authenticated | Run `limacharlie auth login` to authenticate with browser OAuth. | +| MCP tools not loading (Options 2–3) | Check that the MCP server URL and the authentication headers are correct. | +| "Missing privilege" on specific operations | The authenticated user or API key does not have the necessary permission. See [Permission Requirements](#permission-requirements) to find which permissions to grant. | --- diff --git a/docs/6-developer-guide/sdk-overview.md b/docs/6-developer-guide/sdk-overview.md index ba52740cd..e9ca49c3f 100644 --- a/docs/6-developer-guide/sdk-overview.md +++ b/docs/6-developer-guide/sdk-overview.md @@ -1,6 +1,6 @@ # Command Line Interface -The LimaCharlie CLI is installed as part of the [Python SDK](sdks/python-sdk.md) package. +The [Python SDK](sdks/python-sdk.md) package installs the LimaCharlie CLI. ```bash pip install limacharlie @@ -10,33 +10,33 @@ The CLI uses a `limacharlie ` command pattern. Every command suppor ## Authentication -Authenticating the CLI can be done in a few ways. +You can authenticate the CLI in different ways. ### Option 1 - Logging In -The simplest is to login to an Organization using an [API key](../7-administration/access/api-keys.md). +The most simple method is to log in to an Organization with an [API key](../7-administration/access/api-keys.md). -Use `limacharlie auth login` to store credentials locally. You will need an `OID` (Organization ID) and an API key, and (optionally) a `UID` (User ID), all of which you can get from the Access Management --> REST API section of the web interface. +Use `limacharlie auth login` to store the credentials on your computer. You need an `OID` (Organization ID) and an API key. A `UID` (User ID) is optional. Get these values from the Access Management --> REST API section of the web interface. -The login interface supports named environments, or a default one used when no environment is selected. +The login interface supports named environments. It uses a default environment when you select no environment. -To list available organizations: +To list the available organizations: ```bash limacharlie auth list-orgs ``` -Setting a given organization in the current shell session can be done like this: +To set an organization for the current shell session, use this command: ```bash limacharlie auth use-org my-dev-org ``` -You can also specify a `UID` (User ID) during login to use a *user* API key representing the total set of permissions that user has (see User Profile in the web interface). +You can also give a `UID` (User ID) at login. The CLI then uses a *user* API key that has the full set of permissions of that user. See User Profile in the web interface. ### Option 2 - Environment Variables -You can use the `LC_OID` and `LC_API_KEY` and `LC_UID` environment variables to replace the values used logging in. The environment variables will be used if no other credentials are specified. +Use the `LC_OID`, `LC_API_KEY`, and `LC_UID` environment variables in place of the values from the login. The CLI uses these environment variables if you specify no other credentials. ## Docker Image @@ -56,7 +56,7 @@ docker run -v ${HOME}/.limacharlie:/root/.limacharlie:ro refractionpoint/limacha ### Search / Query -[LimaCharlie Query Language (LCQL)](../4-data-queries/lcql-examples.md) provides a flexible, intuitive and interactive way to explore your data in LimaCharlie. +[LimaCharlie Query Language (LCQL)](../4-data-queries/lcql-examples.md) gives you a flexible and interactive way to explore your data in LimaCharlie. ```bash limacharlie search --help @@ -64,11 +64,11 @@ limacharlie search --help ### ARLs -[Authenticated Resource Locators (ARLs)](../8-reference/authentication-resource-locator.md) describe a way to specify access to a remote resource, supporting many methods, including authentication data, and all that within a single string. +[Authenticated Resource Locators (ARLs)](../8-reference/authentication-resource-locator.md) specify access to a remote resource in one string. They support many access methods and can include authentication data. -ARLs can be used in the [YARA manager](../5-integrations/extensions/limacharlie/yara-manager.md) to import rules from GitHub repositories and other locations. +You can use ARLs in the [YARA manager](../5-integrations/extensions/limacharlie/yara-manager.md) to import rules from GitHub repositories and other locations. -Testing an ARL before applying it somewhere can be helpful to shake out access or authentication errors beforehand. You can test an ARL and see what files are fetched, and their contents, by running the following command: +Test an ARL before you use it somewhere. A test finds access errors and authentication errors early. This command tests an ARL and shows which files it gets, and their contents: ```bash limacharlie arl get -a [github,Yara-Rules/rules/email] @@ -76,7 +76,7 @@ limacharlie arl get -a [github,Yara-Rules/rules/email] ### Streaming -Stream events, detections, or audit logs in real-time. Uses pull-mode spouts (HTTPS) or push-mode firehose listeners (TLS). +Stream events, detections, or audit logs in real time. The command uses pull-mode spouts (HTTPS) or push-mode firehose listeners (TLS). ```bash # Stream events (pull-mode via stream.limacharlie.io, works through NATs and proxies) @@ -92,27 +92,27 @@ limacharlie stream audit ### Sync (Infrastructure as Code) -The `pull` command will fetch the organization configuration and write it to a local YAML file. +The `pull` command gets the organization configuration and writes it to a local YAML file. ```bash limacharlie sync pull --oid c82e5c17-d519-4ef5-a4ac-c454a95d31ca ``` -Then `push` can upload the configuration specified in the YAML file to your organization. The `--dry-run` simulates the sync and displays the changes that would occur. +The `push` command then uploads the configuration in the YAML file to your organization. The `--dry-run` flag simulates the sync and shows the changes that it would make. ```bash limacharlie sync push --dry-run --oid c82e5c17-d519-4ef5-a4ac-c454a95d31ca --config /path/to/template.yaml ``` -All these capabilities are also supported directly by the `Configs` SDK class (`limacharlie.sdk.configs`). +The `Configs` SDK class (`limacharlie.sdk.configs`) also supports all these capabilities. -The Sync functionality supports all common useful configurations. Use the hive flags (`--hive-dr-general`, `--hive-fp`, `--outputs`, etc.) to control which resource types are synced. See `limacharlie sync --help` for all options. +The Sync function supports all common useful configurations. Use the hive flags (`--hive-dr-general`, `--hive-fp`, `--outputs`, etc.) to control which resource types the CLI syncs. See `limacharlie sync --help` for all options. -To understand better the config format, do a `pull` from your organization. Notice the use of the `include` statement. Using this statement you can combine multiple config files together, making it ideal for the management of complex rule sets and their versioning. +To learn the config format, do a `pull` from your organization. Look at the `include` statement. This statement combines more than one config file into one configuration. Use it to manage complex rule sets and their versions. ### Spot Checks -Used to perform Organization-wide checks for specific indicators of compromise. Supports many types of IoCs like file names, directories, registry keys, file hashes and YARA signatures. +Do checks for specific indicators of compromise across the Organization. Spot checks support many types of IoC, such as file names, directories, registry keys, file hashes, and YARA signatures. ```bash limacharlie spotcheck --help @@ -144,7 +144,7 @@ limacharlie artifact --help ### Replay -Perform [Replay](../5-integrations/services/replay.md) jobs from the CLI. +Run [Replay](../5-integrations/services/replay.md) jobs from the CLI. ```bash limacharlie replay --help @@ -160,7 +160,7 @@ limacharlie dr --help ### Events & Detections -Print out to STDOUT events or detections matching the parameter. +Print the events or the detections that match the parameter to STDOUT. ```bash limacharlie event --help @@ -169,7 +169,7 @@ limacharlie detection --help ### List Sensors -Print out all basic sensor information for all sensors matching the [selector](../8-reference/sensor-selector-expressions.md). +Print the basic sensor information for all sensors that match the [selector](../8-reference/sensor-selector-expressions.md). ```bash limacharlie sensor list --selector 'plat == windows' @@ -177,9 +177,9 @@ limacharlie sensor list --selector 'plat == windows' ### Add Users -Add single or multiple users to a LimaCharlie organization. Added users will be sent an email to confirm their address, enable the account and create a new password. +Add one user or more users to a LimaCharlie organization. Each new user gets an email. The email asks the user to confirm the address, enable the account, and create a new password. -Keep in mind that this action operates in the user context which means you need to use a user scoped API key. For more information on how to obtain one, see +This action operates in the user context, so you must use a user scoped API key. To get one, see Add a single user: @@ -208,7 +208,7 @@ limacharlie user add --file users_to_add.txt ### AI Sessions -Create, inspect, and attach to [AI Sessions](../9-ai-sessions/index.md) directly from the terminal. The CLI exposes both ownership models the backend supports — **org-owned** sessions (started from an `ai_agent` Hive template, billed against the org's stored Anthropic key) and **user-owned** sessions (started fresh, billed against your personal Claude credential). +Create, inspect, and attach to [AI Sessions](../9-ai-sessions/index.md) from the terminal. The CLI exposes both ownership models that the cloud supports: **org-owned** sessions and **user-owned** sessions. An org-owned session starts from an `ai_agent` Hive template, and the cloud bills it against the org's stored Anthropic key. A user-owned session starts fresh, and the cloud bills it against your personal Claude credential. ```bash # --- Org-owned: run an ai_agent Hive record as a template, with overrides. @@ -228,6 +228,6 @@ limacharlie ai chats list --status running # list your chat sessions limacharlie ai chats terminate --id ``` -The `ai session attach --interactive` command works for either kind of session: it sends prompts when you own the session (user-owned), and falls back to read-only with a notice when the session is org-owned (the backend exposes only a read-only WebSocket for those by design). +The `ai session attach --interactive` command works with both kinds of session. It sends prompts when you own the session (user-owned). When the session is org-owned, it shows a notice and becomes read-only, because the cloud exposes only a read-only WebSocket for those sessions by design. See [AI Sessions — Command Line Interface](../9-ai-sessions/cli.md) for the full command reference, override semantics, the org-vs-user split, and stream output formatting. diff --git a/docs/6-developer-guide/sdks/go-sdk.md b/docs/6-developer-guide/sdks/go-sdk.md index fb30cdf8e..3950c1b57 100644 --- a/docs/6-developer-guide/sdks/go-sdk.md +++ b/docs/6-developer-guide/sdks/go-sdk.md @@ -2,7 +2,7 @@ ## Overview -The LimaCharlie Go SDK provides a comprehensive client library for interacting with the LimaCharlie security platform API. This SDK enables developers to programmatically manage sensors, detection rules, artifacts, organizational configurations, real-time event streaming, and more within the LimaCharlie ecosystem. +The LimaCharlie Go SDK is a client library for the API of the LimaCharlie security platform. With this SDK, developers can manage sensors, detection rules, artifacts, organization configurations, real-time event streams, and more. **Repository**: [github.com/refractionPOINT/go-limacharlie](https://github.com/refractionPOINT/go-limacharlie) @@ -45,7 +45,7 @@ go get github.com/refractionPOINT/go-limacharlie/firehose ## Authentication -The SDK supports multiple authentication methods for flexible integration. +The SDK supports several authentication methods. ### Environment Variables @@ -500,7 +500,7 @@ for _, resp := range newResponses { #### Device Association -Sensors may be associated with logical devices (when multiple sensors represent the same device): +A sensor can have an associated logical device. This occurs when more than one sensor represents the same device: ```go sensor := org.GetSensor("sensor-id") @@ -653,7 +653,7 @@ err = org.DRRuleDelete("rule-name", limacharlie.WithNamespace("custom")) ### Artifacts -Artifacts are files or data collected from sensors for analysis. +Artifacts are files or data that LimaCharlie collects from sensors for analysis. #### Creating Artifacts from Bytes @@ -808,11 +808,11 @@ err = org.ArtifactRuleDelete("collect-temp-executables") ### Events and Data Streaming -The SDK provides powerful real-time event streaming through the **Spout** system. +The SDK gives real-time event streaming through the **Spout** system. #### Spout - Real-Time Event Streaming -Spout provides WebSocket-based streaming of events, detections, audit logs, and more: +Spout streams events, detections, audit logs, and more over a WebSocket: ```go import "github.com/refractionPOINT/go-limacharlie/limacharlie" @@ -889,7 +889,7 @@ spout, err := limacharlie.NewSpout( #### Using Spout with FutureResults -The Spout system integrates with sensor tasking for request/response workflows: +The Spout system works with sensor tasking for request and response workflows: ```go // Organization with investigation ID enables interactive mode @@ -1128,7 +1128,7 @@ err = org.ExtensionRequest( ### Installation Keys -Installation keys are used for enrolling new sensors. +You use installation keys to enroll new sensors. #### List Installation Keys @@ -1190,11 +1190,11 @@ if err != nil { ### Outputs -Outputs define where LimaCharlie sends events, detections, and other data. The SDK provides comprehensive output management through the `output.go` module. +Outputs define where LimaCharlie sends events, detections, and other data. The `output.go` module of the SDK manages outputs. #### Supported Output Modules -The SDK supports numerous output types via the `OutputTypes` struct: +The SDK supports many output types through the `OutputTypes` struct: - **Cloud Storage**: `s3`, `gcs`, `azure_storage_blob` - **Messaging**: `pubsub`, `kafka`, `azure_event_hub` @@ -1206,7 +1206,7 @@ The SDK supports numerous output types via the `OutputTypes` struct: ### Billing -The SDK provides access to billing information and invoices through the billing service. +The SDK gives access to billing information and invoices through the billing service. #### Get Billing Status @@ -1309,7 +1309,7 @@ if reqs, ok := authReqs.Requirements["methods"].([]interface{}); ok { ### LCQL Queries -LCQL (LimaCharlie Query Language) allows querying historical events and detections. +With LCQL (LimaCharlie Query Language), you can query historical events and detections. #### Basic Query @@ -1439,7 +1439,7 @@ response, err = org.Query(limacharlie.QueryRequest{ ### Hive Configuration Management -Hive is LimaCharlie's configuration management system for storing structured data. +Hive is the LimaCharlie system that manages configuration. It stores structured data. #### Initialize Hive Client @@ -1670,16 +1670,16 @@ The SDK includes automatic retry for transient failures (401, 429, 504). ### 1. Authentication Security -- Store API keys in environment variables or secure vaults, never in code -- Use JWT tokens with minimal required permissions +- Store API keys in environment variables or in secure vaults, not in code +- Use JWT tokens that have only the necessary permissions - Rotate API keys regularly - Never commit credentials to version control ### 2. Resource Management -- Always call `org.Close()` when done -- Use `defer spout.Shutdown()` to ensure cleanup -- Close FutureResults when done: `defer future.Close()` +- Always call `org.Close()` when you are done +- Use `defer spout.Shutdown()` to make sure that cleanup occurs +- Close FutureResults when you are done: `defer future.Close()` ### 3. Performance Optimization @@ -1690,7 +1690,7 @@ The SDK includes automatic retry for transient failures (401, 429, 504). ## Firehose CLI Tool -The `firehose` module provides a standalone CLI tool for streaming LimaCharlie data to local applications via TCP. +The `firehose` module is a standalone CLI tool. It streams LimaCharlie data to local applications over TCP. ### Installation diff --git a/docs/6-developer-guide/sdks/index.md b/docs/6-developer-guide/sdks/index.md index 92c7a8edf..e9144724d 100644 --- a/docs/6-developer-guide/sdks/index.md +++ b/docs/6-developer-guide/sdks/index.md @@ -1,12 +1,12 @@ # SDK Documentation -Programmatic access to LimaCharlie via official SDKs. +Programmatic access to LimaCharlie through the official SDKs. ## Available SDKs ### [Python SDK](python-sdk.md) -The Python SDK offers a full-featured interface for security automation, data analysis, and rapid prototyping. It also includes the [command line interface](../sdk-overview.md). +The Python SDK gives a complete interface for security automation, data analysis, and rapid prototyping. It also includes the [command line interface](../sdk-overview.md). ```bash pip install limacharlie @@ -16,7 +16,7 @@ pip install limacharlie ### [Python SDK v4](python-sdk-v4.md) (Deprecated) -The previous major version of the Python SDK. Deprecated and slated for removal in a future release — kept for users maintaining existing v4 integrations. New code should use the v5 [Python SDK](python-sdk.md). +The previous major version of the Python SDK. It is deprecated and will be removed in a future release. It stays available for users that maintain existing v4 integrations. Use the v5 [Python SDK](python-sdk.md) for new code. ```bash pip install "limacharlie<5" @@ -26,7 +26,7 @@ pip install "limacharlie<5" ### [Go SDK](go-sdk.md) -The Go SDK provides a type-safe client library for building security automation, integrations, and custom tools. +The Go SDK is a type-safe client library. Use it to build security automation, integrations, and custom tools. ```bash go get github.com/refractionPOINT/go-limacharlie/limacharlie diff --git a/docs/6-developer-guide/sdks/python-sdk-v4.md b/docs/6-developer-guide/sdks/python-sdk-v4.md index 76bc2de16..ce35d6d93 100644 --- a/docs/6-developer-guide/sdks/python-sdk-v4.md +++ b/docs/6-developer-guide/sdks/python-sdk-v4.md @@ -2,18 +2,17 @@ !!! warning "Deprecated" Version 4 of the LimaCharlie Python SDK is deprecated and will be removed - in a future release. New code should use the - [Python SDK](python-sdk.md) (v5). This page is kept for users - maintaining existing v4 integrations. Both v4 and v5 target the same - LimaCharlie REST API, so the underlying capabilities available to your - code are unchanged. + in a future release. Use the [Python SDK](python-sdk.md) (v5) for new + code. This page stays available for users that maintain existing v4 + integrations. v4 and v5 use the same LimaCharlie REST API, so your code + has the same capabilities with each version. ## Overview -The v4 Python SDK is a thin abstraction over the LimaCharlie REST API, -centered on the `Manager` object. The REST API supports more functionality -than the SDK; if a REST endpoint you need is not exposed in v4, prefer -migrating to v5 rather than extending v4. +The v4 Python SDK is a thin abstraction of the LimaCharlie REST API. The +`Manager` object is at its center. The REST API supports more functions +than the SDK. If v4 does not expose a REST endpoint that you need, migrate +to v5 instead of an extension to v4. - Source (v4 branch): - REST API: @@ -48,23 +47,23 @@ Core dependencies (installed automatically): ## Authentication -The SDK and CLI support several ways of providing credentials. +The SDK and the CLI support several ways to give credentials. ### Logging In -The simplest path is to log in with an +The most direct method is to log in with an [API key](../../7-administration/access/api-keys.md): ```bash limacharlie login ``` -You will be prompted for an `OID` (Organization ID, in UUID format) and an -API key, both available from the **REST API** section of the web interface. +The CLI prompts you for an `OID` (Organization ID, in UUID format) and an +API key. You get both from the **REST API** section of the web interface. -The login flow supports named environments — credentials are stored under a -chosen name, with one set used as the default when no environment is -selected. +The login flow supports named environments. The CLI stores credentials +under a name that you choose. It uses one set as the default when you +select no environment. To list available environments: @@ -78,20 +77,20 @@ To activate a named environment in the current shell session: . <(limacharlie use dev-org) ``` -You can also provide a `UID` (User ID) at login to use a *user-scoped* API -key, which carries the full set of permissions assigned to that user (see -**User Profile** in the web interface). +You can also give a `UID` (User ID) at login to use a *user-scoped* API +key. This key has all the permissions of that user. See **User Profile** in +the web interface. ### Environment Variables -`LC_OID`, `LC_API_KEY`, and `LC_UID` can replace the values stored at login. -Environment variables are used when no other credentials are explicitly -provided. +`LC_OID`, `LC_API_KEY`, and `LC_UID` can replace the values that you store +at login. The SDK uses the environment variables when you give no other +credentials. ### Credentials File -When using `limacharlie login`, credentials are stored in plain text at -`~/.limacharlie`: +When you use `limacharlie login`, the CLI stores credentials in plain text +at `~/.limacharlie`: ```yaml # Top-level / default credentials @@ -112,14 +111,14 @@ env: # uid: xxx ``` -If you edit this file by hand, preserve the original ownership and `0600` -permissions so that other users cannot read it. If storing plain-text -credentials on disk is unacceptable for your environment, use environment -variables instead. +If you edit this file by hand, keep the original ownership and the `0600` +permissions. Other users then cannot read the file. If your environment +does not allow plain-text credentials on disk, use environment variables +instead. ## Docker -A Docker image with the latest tool is published at +The latest tool is available as a Docker image at : ```bash @@ -135,10 +134,10 @@ docker run -v "${HOME}/.limacharlie:/root/.limacharlie:ro" \ The entry point for the SDK is the `Manager` object. It holds credentials and is bound to a specific Organization. -You can authenticate `Manager` by passing an `oid` (and optionally a `uid`) -together with either a `secret_api_key` or a `jwt`. Alternatively, pass a -named `environment` from `limacharlie login`. If no credentials are -provided, `Manager` falls back to the default environment. +To authenticate `Manager`, give an `oid` (and optionally a `uid`) with +either a `secret_api_key` or a `jwt`. As an alternative, give a named +`environment` from `limacharlie login`. If you give no credentials, +`Manager` uses the default environment. ### Importing @@ -170,51 +169,50 @@ sensor.task('yara_scan -e *evil.exe ' + YARA_SIG) #### Manager -The general-purpose component for organization-level operations: querying -sensors, creating and removing Outputs, and so on. +The general-purpose component for operations at the organization level: +queries of sensors, creation and removal of Outputs, and more. #### Firehose -`Firehose` listens on a local port for LimaCharlie data. Internally it -creates a Syslog Output on LimaCharlie pointing at itself, and removes that -Output on shutdown. Incoming data is added to `firehose.queue` (a standard -`queue.Queue`) as it arrives. +`Firehose` listens on a local port for LimaCharlie data. It creates a +Syslog Output on LimaCharlie that points at itself, and it removes that +Output at shutdown. It adds incoming data to `firehose.queue` (a standard +`queue.Queue`) as the data arrives. -It is a basic building block for automation against LimaCharlie. +It is a basic component for automation with LimaCharlie. #### Spout -`Spout` plays a similar role to `Firehose`, but does not require an open -listening port. Instead it streams data over HTTPS from -`stream.limacharlie.io`, which makes it work behind NATs and proxies. +`Spout` has a similar function to `Firehose`, but it does not need an open +listening port. It streams data over HTTPS from `stream.limacharlie.io`. +Thus it works behind NATs and proxies. -A `Spout` is created automatically when `Manager` is instantiated with -`is_interactive=True` and an `inv_id`, in order to provide real-time -feedback from sensor tasking. +When you create a `Manager` with `is_interactive=True` and an `inv_id`, the +SDK creates a `Spout` automatically. The `Spout` gives real-time feedback +from sensor tasking. #### Sensor The object returned by `manager.sensor(sensor_id)`. It exposes `task`, `hostname`, `tag`, `untag`, `getTags`, and related -functions, and is the main way to interact with a specific sensor. +functions. It is the primary interface to a specific sensor. -`task` sends a one-way task to a sensor; the response (if any) is not -collected. To interact with a sensor in real time, instantiate `Manager` -with `is_interactive=True` and use either `request` (returns a -`FutureResults` object) or `simpleRequest` (blocks until the response is -available). +`task` sends a one-way task to a sensor. It does not collect the response. +To interact with a sensor in real time, create a `Manager` with +`is_interactive=True`. Then use `request` (it returns a `FutureResults` +object) or `simpleRequest` (it blocks until the response is available). #### Artifacts `Artifacts` uploads [Artifact Collection](../../5-integrations/extensions/limacharlie/artifact.md) -items to LimaCharlie without going through a sensor. +items to LimaCharlie without a sensor. #### Payloads `Payloads` manages the executable -[payloads](../../2-sensors-deployment/endpoint-agent/payloads.md) made +[payloads](../../2-sensors-deployment/endpoint-agent/payloads.md) that are available to sensors. #### Replay @@ -225,24 +223,24 @@ re-evaluate #### Search -`Search` performs an IOC search across multiple organizations. +`Search` does an IOC search across more than one organization. #### SpotCheck -`SpotCheck` (also called Fleet Check) performs an active search — querying -sensors directly rather than indexed history — for various IOCs across an -organization's sensors. +`SpotCheck` (also called Fleet Check) does an active search for IOCs across +the sensors of an organization. It queries the sensors directly and not the +indexed history. #### Configs -`Configs` retrieves an organization's configuration as a config file, or -applies a config file to an organization. This is the foundation of the +`Configs` gets the configuration of an organization as a config file. It +can also apply a config file to an organization. It is the base of the Infrastructure-as-Code workflow in v4. #### Webhook -`Webhook` is a reference implementation for handling webhooks emitted by -LimaCharlie, including verification of the shared-secret signature. +`Webhook` is a reference implementation that handles the webhooks that +LimaCharlie sends. It also checks the shared-secret signature. ### Examples @@ -432,8 +430,8 @@ python -m limacharlie.Firehose 1.2.3.4:9424 event \ --oid c82e5c17-d519-4ef5-a4ac-caa4a95d31ca ``` -Listens on `1.2.3.4:9424` for incoming connections from LimaCharlie. -Receives only events from hosts tagged `fh_test`. +This command listens on `1.2.3.4:9424` for incoming connections from +LimaCharlie. It receives only events from hosts with the `fh_test` tag. ### Spout @@ -442,10 +440,11 @@ python -m limacharlie.Spout event \ --oid c82e5c17-d519-4ef5-a4ac-caa4a95d31ca ``` -Behaves like Firehose, but instead of accepting an incoming connection it -streams data from `stream.limacharlie.io` over HTTPS. This means Spout -works through NATs and proxies and is more convenient for short-lived -ad-hoc output, though less reliable than a Firehose for very large volumes. +Spout operates like Firehose, but it does not accept an incoming +connection. It streams data from `stream.limacharlie.io` over HTTPS. Thus +Spout works through NATs and proxies, and it is more convenient for +short-lived ad-hoc output. But it is less reliable than a Firehose for very +large volumes. ### Configs @@ -455,13 +454,13 @@ limacharlie configs fetch --oid c82e5c17-d519-4ef5-a4ac-c454a95d31ca limacharlie configs push --dry-run --oid c82e5c17-d519-4ef5-a4ac-c454a95d31ca ``` -`fetch` writes the organization's configuration to a config file (default -`lc_conf.yaml`) in YAML format. +`fetch` writes the configuration of the organization to a config file in +YAML format. The default file is `lc_conf.yaml`. `push` uploads the rules in the config file to the organization. The `--force` flag also removes active rules that are not present in the config -file. `--dry-run` simulates the sync and prints the changes that would be -made. +file. `--dry-run` simulates the sync and prints the changes that the sync +will make. `--config` selects an alternate config file. `--api-key` reads the API key from a file on disk (or from STDIN if `-` is given). @@ -470,10 +469,9 @@ These capabilities are also available directly through the `limacharlie.Configs` object. The sync covers the common configurable surfaces. Flags such as -`--no-rules` and `--no-outputs` exclude individual sections; see -`limacharlie configs --help` for the full list. The `include` directive -lets you compose multiple config files together, which is convenient for -managing large rule sets. +`--no-rules` and `--no-outputs` exclude single sections. For the full list, +see `limacharlie configs --help`. The `include` directive combines more +than one config file. This is convenient for large rule sets. ### Spot Checks @@ -482,10 +480,10 @@ python -m limacharlie.SpotCheck \ --no-macos --no-linux --tags vip --file 'c:\\evil.exe' ``` -Performs an organization-wide check for specific indicators of compromise. -Available as the `SpotCheck` object or as a CLI module. Supports many IOC -types including file names, directories, registry keys, file hashes, and -YARA signatures. +This command checks all of an organization for specific indicators of +compromise. It is available as the `SpotCheck` object or as a CLI module. +It supports many IOC types: file names, directories, registry keys, file +hashes, and YARA signatures. For full usage: @@ -499,7 +497,7 @@ python -m limacharlie.SpotCheck --help limacharlie search --help ``` -Performs IOC searches across all locally configured organizations. +Does IOC searches across all organizations that you configured locally. ### Artifact Upload @@ -509,7 +507,7 @@ limacharlie artifacts upload --help Uploads [Artifact Collection](../../5-integrations/extensions/limacharlie/artifact.md) -items directly to LimaCharlie from the CLI (no agent required). +items directly to LimaCharlie from the CLI. No sensor is necessary. ### Artifact Download @@ -544,7 +542,7 @@ limacharlie events --help limacharlie detections --help ``` -Prints events or detections matching the given parameters to STDOUT. +Prints the events or detections that match the given parameters to STDOUT. ### List Sensors @@ -552,7 +550,7 @@ Prints events or detections matching the given parameters to STDOUT. limacharlie sensors --selector '*' ``` -Prints basic sensor information for all sensors matching the selector. +Prints basic sensor information for each sensor that matches the selector. ### Extension @@ -560,7 +558,7 @@ Prints basic sensor information for all sensors matching the selector. limacharlie extension --help ``` -Performs actions against +Does actions on [Extensions](../../5-integrations/extensions/index.md) from the CLI. ### ARLs @@ -569,8 +567,8 @@ Performs actions against limacharlie get-arl --help ``` -Prints the data returned from the given -[ARL](../../8-reference/authentication-resource-locator.md). Example: +Prints the data that the given +[ARL](../../8-reference/authentication-resource-locator.md) returns. Example: ```bash limacharlie get-arl -a [github,Yara-Rules/rules/email] diff --git a/docs/6-developer-guide/sdks/python-sdk.md b/docs/6-developer-guide/sdks/python-sdk.md index 76804affe..f8380b7f0 100644 --- a/docs/6-developer-guide/sdks/python-sdk.md +++ b/docs/6-developer-guide/sdks/python-sdk.md @@ -20,7 +20,7 @@ ## Overview -The LimaCharlie Python SDK provides a comprehensive interface for interacting with the LimaCharlie Agentic SecOps Workspace. This SDK enables programmatic access to all platform features including sensor management, detection and response rules, real-time event streaming, and artifact collection. +The LimaCharlie Python SDK is a complete interface to the LimaCharlie Agentic SecOps Workspace. This SDK gives programmatic access to all platform features. These features include sensor management, detection and response rules, real-time event streaming, and artifact collection. ### Key Features @@ -81,7 +81,7 @@ The LimaCharlie SDK supports multiple authentication methods: ### Credential Resolution Order -Credentials are resolved in priority order (highest first): +The SDK resolves credentials in this priority order (highest first): 1. Explicit parameters passed to `Client()` 2. `LC_OID`, `LC_API_KEY`, `LC_UID` environment variables @@ -123,7 +123,7 @@ org = Organization(client) ### Configuration File Format -Create a file at `~/.limacharlie` or specify with `LC_CREDS_FILE` environment variable: +Create a file at `~/.limacharlie`, or give the path in the `LC_CREDS_FILE` environment variable: ```yaml # Default credentials @@ -196,7 +196,7 @@ with Client(oid='ORG_ID', api_key='API_KEY') as client: ## Organization -The `Organization` class is the primary entry point for interacting with a LimaCharlie organization. +The `Organization` class is the primary entry point to a LimaCharlie organization. ### Core Methods @@ -288,7 +288,7 @@ new_org = Organization.create_org(client, 'my-new-org', location='us') ## Sensor Management -The `Sensor` class provides detailed control over individual sensors. +The `Sensor` class gives detailed control of each sensor. ### Listing and Getting Sensors @@ -412,7 +412,7 @@ sensor.delete() ## Detection and Response Rules -D&R rules can be managed through the Hive system or the `DRRules` convenience class. +You can manage D&R rules through the Hive system or through the `DRRules` convenience class. ### Using Hive (Recommended) @@ -526,7 +526,7 @@ result = replay.scan_events( ### Spout (Pull-based Streaming) -The `Spout` pulls data from `stream.limacharlie.io` over HTTPS. Works through NATs and proxies. Best for short-term ad-hoc streaming. +The `Spout` pulls data from `stream.limacharlie.io` over HTTPS. It works through NATs and proxies. Use it for short-term ad-hoc streaming. ```python from limacharlie.client import Client @@ -550,7 +550,7 @@ finally: ### Firehose (Push-based Streaming) -The `Firehose` creates a TLS server that LimaCharlie connects to and pushes data. Best for large-scale, long-running streaming. +The `Firehose` creates a TLS server. LimaCharlie connects to this server and pushes data to it. Use it for large-scale streaming that runs for a long time. ```python from limacharlie.sdk.firehose import Firehose @@ -593,7 +593,7 @@ url = artifacts.get_url('ARTIFACT_ID') ## Hive Operations -The Hive is LimaCharlie's key-value storage system used for D&R rules, secrets, playbooks, SOPs, lookups, and more. +The Hive is the LimaCharlie key-value storage system. It holds D&R rules, secrets, playbooks, SOPs, lookups, and more. ```python from limacharlie.sdk.hive import Hive, HiveRecord @@ -779,7 +779,7 @@ except LimaCharlieError as e: ### Built-in Retry Logic -The `Client` automatically retries on HTTP 429 (rate limit) and 504 (gateway timeout) with exponential backoff. No manual retry logic is needed for transient errors. +The `Client` automatically retries on HTTP 429 (rate limit) and 504 (gateway timeout) with exponential backoff. You do not need your own retry logic for transient errors. ## Complete Examples diff --git a/docs/7-administration/access/api-keys.md b/docs/7-administration/access/api-keys.md index ee17a3342..dc1b66b4b 100644 --- a/docs/7-administration/access/api-keys.md +++ b/docs/7-administration/access/api-keys.md @@ -1,18 +1,18 @@ # API Keys -LimaCharlie Cloud has a concept of API keys. Those are secret keys that can be created and named, and then in turn be used to retrieve a JWT that can be associated with the LC REST API at . +The cloud uses API keys. An API key is a named secret key. You use an API key to get a JWT for the LC REST API at . -This allows construction of headless applications able to securely acquire time-restricted REST authentication tokens it can then use. +A headless application can use this method to get REST authentication tokens that expire. -The list of available permissions can be programmatically retrieved from this URL: +To get the list of available permissions programmatically, use this URL: ## Managing -The API Keys are managed through the Organization view of the web interface. +You manage the API keys in the Organization view of the web app at . ## Getting a JWT -Issue an HTTP POST to `https://jwt.limacharlie.io` with the Organization ID and API key. The returned JWT is valid for one hour. +Send an HTTP POST to `https://jwt.limacharlie.io` with the Organization ID and the API key. The JWT is valid for one hour. === "REST API" @@ -54,77 +54,77 @@ Issue an HTTP POST to `https://jwt.limacharlie.io` with the Organization ID and ### User API Keys -User API keys are to generate JSON web tokens (JWTs) for the REST API. In contrast to Organization API keys, the User API keys are associated with a specific user and provide the exact same access across all organizations. +User API keys generate JSON web tokens (JWTs) for the REST API. Unlike Organization API keys, a User API key belongs to one specific user. It gives the same access in all organizations. -This makes User API Keys very powerful but also riskier to manage. Therefore we recommend using Organization API keys whenever possible. +This access makes User API Keys harder to manage safely. Use Organization API keys when possible. -The User API keys can be used through all the same interfaces as the Organization API keys. The only difference is how you get the JWT. Instead of giving an `oid` parameter to `https://jwt.limacharlie.io/`, provide it with a `uid` parameter available through the LimaCharlie web interface. +User API keys work with the same interfaces as Organization API keys. Only the method to get the JWT is different. Give `https://jwt.limacharlie.io/` a `uid` parameter instead of an `oid` parameter. The LimaCharlie web app shows the `uid` value. `curl -X POST "https://jwt.limacharlie.io" -H "Content-Type: application/x-www-form-urlencoded" -d "uid=&secret="` -In some instances, the JWT resulting from a User API key may be to large for normal API use, in which case you will get an `HTTP 413 Payload too large` from the API gateway. In those instances, also provide an `oid` (on top of the `uid`) to the `jwt.limacharlie.io` REST endpoint to get a JWT valid only for that organization. +Sometimes the JWT from a User API key is too large for normal API use. The API gateway then returns `HTTP 413 Payload too large`. If this happens, also give an `oid` with the `uid` to the `jwt.limacharlie.io` REST endpoint. The endpoint returns a JWT that is valid only for that organization. `curl -X POST "https://jwt.limacharlie.io" -H "Content-Type: application/x-www-form-urlencoded" -d "oid=&uid=&secret="` -You may also use a User API Key to get the list of organizations available to it by querying the following REST endpoint: +You can also use a User API Key to get the list of organizations that it can access. Query this REST endpoint: `https://app.limacharlie.io/user_key_info?secret=&uid=&with_names=true` #### Ingestion Keys -The [artifact collection](../../5-integrations/extensions/limacharlie/artifact.md) in LC requires Ingestion Keys, which can be managed through the REST API section of the LC web interface. Access to manage these Ingestion Keys requires the `ingestkey.ctrl` permission. +[Artifact collection](../../5-integrations/extensions/limacharlie/artifact.md) in LC needs Ingestion Keys. You manage these keys in the REST API section of the LC web app. To manage Ingestion Keys, you need the `ingestkey.ctrl` permission. ## SDKs -The [Python SDK](../../6-developer-guide/sdks/python-sdk.md) and [Go SDK](../../6-developer-guide/sdks/go-sdk.md) handle the API Key to JWT exchange automatically and wrap the REST API into convenient objects. +The [Python SDK](../../6-developer-guide/sdks/python-sdk.md) and the [Go SDK](../../6-developer-guide/sdks/go-sdk.md) exchange the API Key for a JWT automatically. They also wrap the REST API in objects. ## Privileges -API Keys have several on-off privileges available. +API Keys have on-off privileges. -To see a full list, see the "REST API" section of your organization. +For the full list, see the "REST API" section of your organization. -Making a REST call will fail with a `401` if your API Key / token is missing some privileges and the missing privilege will be specified in the error. +A REST call fails with a `401` if your API Key or token does not have all the necessary privileges. The error names the missing privilege. ## Required Privileges -Below is a list of privileges required for some common tasks. +This is a list of the privileges that some common tasks need. ### Go Live -When "going Live" through the web UI, the following is required by the user: +To "go Live" in the web app, the user needs these privileges: -- `output.*`: for the creation of the real-time output via HTTP to the browser. -- `sensor.task`: to send the commands (both manually for the console and to populate the various tabs) to the Sensor. +- `output.*`: to create the real-time output to the browser through HTTP. +- `sensor.task`: to send commands to the Sensor. This includes manual commands for the console and the commands that fill the tabs. ## Flair -API Keys may have "flair" as part of the key name. A flair is like a tag surrounded by `[]`. Although it is not required, we advise to put the flair at the end of the API key name for readability. +An API Key name can contain "flair". A flair is a tag inside `[]`. The flair is optional. Put the flair at the end of the API key name to keep the name readable. For example: `orchestration-key[bulk]` is a key with a `bulk` flair. -Flairs are used to modify the behavior of an API key or provide some usage hints to various systems in LimaCharlie. +A flair changes the behavior of an API key. It can also give usage hints to systems in LimaCharlie. -The following flairs are currently supported: +LimaCharlie supports these flairs: -- `bulk`: indicates to the REST API that this key is meant to do a large amount of calls, the API gateway tweaks the API call limits accordingly. -- `segment`: indicates that only resources created by this key will be visible by this key. This is useful to provide access to a 3rd party in a limited fashion. +- `bulk`: tells the REST API that this key makes many calls. The API gateway changes the API call limits for the key. +- `segment`: makes only the resources that this key created visible to this key. Use this flair to give limited access to a third party. ## Allowed IP Range -When creating an API key, you can optionally include an `allowed_ip_range`, which should be a [CIDR notation](https://aws.amazon.com/what-is/cidr/) IP range from which the API key can be used. Any use of the API key from a different IP address will fail. This is currently only configurable when creating an API key via the API and not in the UI. +When you create an API key, you can add an `allowed_ip_range`. This value is an IP range in [CIDR notation](https://aws.amazon.com/what-is/cidr/). The API key works only from an IP address in that range. Use of the key from a different IP address fails. You can set this value only when you create an API key with the API, not in the web app. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment for security data, configurations, and assets. Each Organization has its own sensors, detection rules, data sources, and outputs. This structure supports multi-tenant setups for managed security providers, and for enterprises with many departments or clients. -In LimaCharlie, an Organization ID is a unique identifier assigned to each tenant or customer account. It distinguishes different organizations within the platform, enabling LimaCharlie to manage resources, permissions, and data segregation securely. The Organization ID ensures that all telemetry, configurations, and operations are kept isolated and specific to each organization, allowing for multi-tenant support and clear separation between different customer environments. +In LimaCharlie, an Organization ID is a unique identifier for each tenant or customer account. It separates the organizations in the platform. LimaCharlie uses it to manage resources, permissions, and the separation of data. The Organization ID keeps the telemetry, the configurations, and the operations of each organization isolated from other customer environments. -Similar to agents, Sensors send telemetry to the LimaCharlie platform in the form of EDR telemetry or forwarded logs. Sensors are offered as a scalable, serverless solution for securely connecting endpoints of an organization to the cloud. +Sensors send telemetry to the LimaCharlie platform as EDR telemetry or as forwarded logs. A sensor is a scalable, serverless method to connect the endpoints of an organization to the cloud. ## Programmatic Management !!! info "Prerequisites" - Managing API keys programmatically requires an existing API key with the `apikey.ctrl` permission. See [Managing](#managing) for initial setup through the web interface. + To manage API keys programmatically, you need an API key with the `apikey.ctrl` permission. For the first setup in the web app, see [Managing](#managing). ### List API Keys @@ -209,13 +209,13 @@ Similar to agents, Sensors send telemetry to the LimaCharlie platform in the for limacharlie api-key create --name ci-key --permissions "dr.list,dr.set" ``` - To mint the key and store its value in the [secret hive](../config-hive/secrets.md) in a single step, add `--store-secret`: + To create the key and store its value in the [secret hive](../config-hive/secrets.md) in one step, add `--store-secret`: ```bash limacharlie api-key create --name --permissions "..." --store-secret [--store-secret-tag ] ``` - This creates the key and writes its value to `hive://secret/`. The value is shown only once at creation, so storing it directly avoids having to capture and re-pipe it. If a secret with that name already exists, it is updated in place via its etag. The identity running this command needs the `secret.set` permission (to write the secret) in addition to the permission to create API keys. + This command creates the key and writes its value to `hive://secret/`. The value is shown only one time, when you create the key. Direct storage removes the need to capture the value and pipe it again. If a secret with that name exists, the command updates it in place with its etag. The identity that runs this command needs the `secret.set` permission to write the secret, and also the permission to create API keys. ### Delete an API Key diff --git a/docs/7-administration/access/designing-access.md b/docs/7-administration/access/designing-access.md index e779914f2..896dea914 100644 --- a/docs/7-administration/access/designing-access.md +++ b/docs/7-administration/access/designing-access.md @@ -1,32 +1,32 @@ # Designing Access for Multi-Org Deployments -This guide is written for administrators who operate more than a single organization — typically MSSPs, MDRs, or enterprises with multiple business units — and who need to give access to two distinct populations: +This guide is for administrators who operate more than one organization. These administrators are usually MSSPs, MDRs, or enterprises with many business units. They must give access to two different groups of people: -- **Internal staff** (analysts, engineers, managers) who need access across *many* organizations. -- **End customers** (or business-unit owners) who should only see their *own* organization. +- **Internal staff** (analysts, engineers, managers) who need access to *many* organizations. +- **End customers** (or business-unit owners) who must see only their *own* organization. -The mechanics of granting and verifying access are documented in [User Access](user-access.md). This page focuses on the architectural decisions that happen *before* you start clicking "Add user" — so that the access model stays safe and manageable as you grow from one customer to fifty. +[User Access](user-access.md) documents how to grant and check access. This page describes the architectural decisions that you make *before* you add the first user. These decisions keep the access model safe and manageable when you grow from one customer to fifty. ## Building blocks -Three LimaCharlie primitives combine to form every access model: +Three LimaCharlie primitives make every access model: | Primitive | Scope | Typical use | | --- | --- | --- | -| **Organization** | Single tenant (isolated data, sensors, billing) | One per customer / business unit | -| **Direct user** | One user ↔ one organization | A user who should see only that single org (e.g. an end-customer contact) | -| **Organization Group** | Set of orgs × set of users × set of permissions | A job-function bundle: everyone in the group gets the same permissions on every org in the group | +| **Organization** | Single tenant (isolated data, sensors, billing) | One for each customer or business unit | +| **Direct user** | One user ↔ one organization | A user who must see only that one org, for example an end-customer contact | +| **Organization Group** | Set of orgs × set of users × set of permissions | A bundle for one job function. Each user in the group gets the same permissions on each org in the group | -Supporting primitives that reinforce the model: +These primitives support the model: -- **Predefined roles** (`Owner`, `Administrator`, `Operator`, `Viewer`, `Basic`) — apply a whole permission preset in one step. See [Reference: Permissions](../../8-reference/permissions.md). -- **Organization API keys** — machine access, scoped to a specific set of permissions on a specific org. See [API Keys](api-keys.md). -- **SSO / Strict SSO** — force users on your domain to authenticate via your IdP only. See [SSO](sso.md). -- **Group owners vs. group members** — owners manage a group (add users, add orgs, change permissions) but the group's permissions do **not** apply to them. Members receive the permissions but cannot modify the group. +- **Predefined roles** (`Owner`, `Administrator`, `Operator`, `Viewer`, `Basic`) — apply a full permission preset in one step. See [Reference: Permissions](../../8-reference/permissions.md). +- **Organization API keys** — machine access, scoped to a set of permissions on one org. See [API Keys](api-keys.md). +- **SSO / Strict SSO** — force users on your domain to authenticate through your IdP only. See [SSO](sso.md). +- **Group owners vs. group members** — owners manage a group. They add users, add orgs, and change permissions, but the group's permissions do **not** apply to them. Members get the permissions but cannot change the group. ## Recommended architecture for an MSSP -The pattern below scales from two customers to several hundred without restructuring. Use it as the starting point and adapt as needed. +This pattern scales from two customers to several hundred, and you do not need to restructure it. Use it as the starting point and change it for your needs. ```mermaid flowchart LR @@ -67,17 +67,17 @@ flowchart LR Three rules keep this architecture coherent: -1. **One organization per customer tenant.** Data, sensors, billing and configuration are self-contained in an organization. A customer *is* an organization. Do not mix customers inside a single org. -2. **Your staff get access through Organization Groups, by job function.** Never add internal staff directly to a customer org — that does not scale and silently drifts over time. -3. **Your customers get access directly on their own organization.** Never add an end-customer user to a group that spans multiple customer orgs — groups are additive, and a group that touches other customers would leak access to data the user must not see. +1. **Use one organization for each customer tenant.** An organization contains its own data, sensors, billing, and configuration. A customer *is* an organization. Do not mix customers in one org. +2. **Give your staff access through Organization Groups, by job function.** Do not add internal staff directly to a customer org. Direct access does not scale, and the permissions drift over time. +3. **Give your customers access directly on their own organization.** Do not add an end-customer user to a group that contains more than one customer org. Groups are additive, and such a group gives the user access to data that the user must not see. ### Optional: an internal "management" organization -Many MSSPs also create a dedicated organization used only internally (templates, IaC source of truth, demo / training work). It is not a customer tenant. You can include it in a staff group, but do **not** enrol customer users in it. +Many MSSPs also create an organization for internal use only. It holds templates, the IaC source of truth, and demo or training work. It is not a customer tenant. You can include it in a staff group, but do **not** enrol customer users in it. ## Granting access to your internal staff -Design the groups around job functions, not around customers. A typical starting set — the right-most column is the permission level you want each group to grant (matching the predefined roles you use for direct users makes the overall model easier to reason about): +Design the groups around job functions, not around customers. This table shows a typical starting set. The last column is the permission level that each group grants. Use the same permission levels as the predefined roles for direct users. The model is then easier to understand. | Group | Members | Permission level | | --- | --- | --- | @@ -86,75 +86,75 @@ Design the groups around job functions, not around customers. A typical starting | `analysts-l1` | Front-line SOC | Operator-equivalent | | `read-only` | Leadership, auditors | Viewer-equivalent | -Workflow once the groups exist: +Workflow after the groups exist: -1. **Create each group once.** `limacharlie group create --name ` (or via the **Groups** page). +1. **Create each group one time.** `limacharlie group create --name `, or use the **Groups** page. 2. **Add every customer org** to each relevant group. `limacharlie group org-add --gid --oid `. -3. **Set the group's permissions.** In the **Groups** page of the web app, select the permissions that match the intended permission level. Via the CLI, pass the explicit permission list: `limacharlie group permissions-set --gid --permissions 'sensor.list,sensor.get,dr.list,...'`. Note that the group CLI takes a raw permission list — unlike `limacharlie user permissions set-role` for direct users, there is no single role-preset flag. Keep the list aligned with the direct-user role of the same name so effective permissions stay easy to reason about. -4. **Add a user to exactly the group(s) matching their job.** `limacharlie group member-add --gid --email
`. -5. **When you onboard a new customer**, simply add the new org to each staff group (step 2). Every staff member instantly gets the right level of access on the new tenant, with no per-user work. +3. **Set the group's permissions.** In the **Groups** page of the web app, select the permissions for the intended permission level. With the CLI, give the full permission list: `limacharlie group permissions-set --gid --permissions 'sensor.list,sensor.get,dr.list,...'`. The group CLI accepts a raw permission list only. It has no role-preset flag, unlike `limacharlie user permissions set-role` for direct users. Keep the list the same as the direct-user role with the same name. The effective permissions are then easier to understand. +4. **Add a user only to the groups that match their job.** `limacharlie group member-add --gid --email
`. +5. **When you onboard a new customer, add the new org to each staff group** (step 2). Each staff member then gets the correct level of access on the new tenant, with no work for each user. ### Separating production from non-production -A very common refinement is to split a sensitive group (e.g. `engineers`) into two: +A common refinement is to split a sensitive group, for example `engineers`, into two groups: -- `engineers-nonprod` — includes sandbox / demo / pre-prod customer orgs. -- `engineers-prod` — includes live customer orgs, restricted to senior staff who have signed off on your production change-control process. +- `engineers-nonprod` — includes sandbox, demo, and pre-prod customer orgs. +- `engineers-prod` — includes live customer orgs. It is limited to senior staff who accepted your change-control process for production. -Membership in `engineers-prod` becomes the formal gate to production access, and is easy to audit (`limacharlie group get --id ` lists members, orgs, and permissions in one response). +Membership in `engineers-prod` is then the formal control for access to production. It is also easy to audit: `limacharlie group get --id ` lists the members, the orgs, and the permissions in one response. ## Granting access to your end customers -End customers must stay confined to their own organization. The safe pattern is always the same: +End customers must stay inside their own organization. The safe pattern is always the same: -1. **Add the customer's email directly to their own org only.** `limacharlie --oid user invite --email
`, or the **Users** page of that org. -2. **Assign a predefined role** that matches what you agreed to in your service agreement. `limacharlie --oid user permissions set-role --email
--role Viewer` (or `Operator`, `Administrator`, etc.). -3. **Do not add customer users to any staff Organization Group.** A group that contains other customers' orgs would silently grant the user access to data belonging to those other customers. +1. **Add the customer's email directly to their own org only.** `limacharlie --oid user invite --email
`, or use the **Users** page of that org. +2. **Assign a predefined role** that matches your service agreement. `limacharlie --oid user permissions set-role --email
--role Viewer` (or `Operator`, `Administrator`, etc.). +3. **Do not add customer users to a staff Organization Group.** A group that contains the orgs of other customers gives the user access to the data of those other customers. !!! warning "Groups are additive only" - Permissions granted through a group are **added** to the user's direct permissions on each included organization. A group cannot be used to *reduce* or *restrict* what a user can see. Treat "membership in a group" as "give every permission in that group, on every org in that group." + A group **adds** its permissions to the user's direct permissions on each organization in the group. A group cannot *reduce* or *restrict* what a user can see. Read "membership in a group" as "give every permission in that group, on every org in that group." -If you want to give a customer access to *multiple* of their own organizations (for example, a customer with several business units), you have two clean options: +A customer can have more than one of their own organizations, for example one org for each business unit. To give the customer access to all of them, use one of two options: -- **Direct users on each org.** Simple, auditable, fine if the customer only has a handful of orgs. -- **A customer-specific Organization Group** that contains *only* that customer's orgs and *only* that customer's users. Do not mix tenants inside a single group. +- **Direct users on each org.** This option is easy to audit, and it works well if the customer has few orgs. +- **A customer-specific Organization Group** that contains *only* that customer's orgs and *only* that customer's users. Do not mix tenants in one group. ## Hardening -A few controls sharply reduce the risk of an access-control mistake: +These controls reduce the risk of a mistake in access control: -- **Strict SSO Enforcement on your own domain.** Forces every user authenticating as `@yourcompany.com` to go through your identity provider. Offboarding in your IdP immediately locks the user out of LimaCharlie. See [Strict SSO Enforcement](sso.md#strict-sso-enforcement). -- **Organization API keys over user API keys.** An Organization API key is scoped to a single organization and to the minimum permissions needed by the integration. User API keys grant the same access as the user themselves across *every* organization they can reach — reserve them for interactive work only, never for production automation. See [User API Keys](api-keys.md#user-api-keys). -- **Separate group owners from members.** An engineering manager can be an *owner* of a staff group (to add/remove members) without being a member themselves — they gain the ability to manage access without automatically having access to customer data. This is a useful separation-of-duties control. -- **Review access on a cadence.** The companion section [Verifying and Reviewing Access](user-access.md#verifying-and-reviewing-access) shows how to enumerate every user, group, and effective permission on an organization, plus how to pull the audit trail of access changes. +- **Strict SSO Enforcement on your own domain.** This control forces each user who authenticates as `@yourcompany.com` to go through your identity provider. When you offboard the user in your IdP, the user loses access to LimaCharlie immediately. See [Strict SSO Enforcement](sso.md#strict-sso-enforcement). +- **Organization API keys instead of user API keys.** An Organization API key is scoped to one organization and to the minimum permissions that the integration needs. A User API key gives the same access as the user, in *every* organization that the user can reach. Use User API keys for interactive work only, never for production automation. See [User API Keys](api-keys.md#user-api-keys). +- **Separate group owners from members.** An engineering manager can be an *owner* of a staff group and add or remove members, but not be a member. The manager can then manage access without access to customer data. This is a separation-of-duties control. +- **Review access at regular intervals.** The companion section [Verifying and Reviewing Access](user-access.md#verifying-and-reviewing-access) shows how to list every user, group, and effective permission on an organization. It also shows how to get the audit trail of access changes. ## New-customer onboarding checklist -Once you have the architecture above in place, adding a new customer is a short, repeatable list: +After the architecture above is in place, you add a new customer with a short, repeatable list of steps: -1. **Create the customer's organization.** The creator automatically holds the `Owner` role on it. -2. **Grant `Owner` to a shared internal account as well,** so administrative access does not depend on the creator's personal account being available. `limacharlie --oid user permissions set-role --email --role Owner`. A full billing/legal ownership transfer is a separate support request; see [Can I Transfer Ownership of an Organization?](../../8-reference/faq/account-management.md#can-i-transfer-ownership-of-an-organization). -3. **Add the new org to each staff Organization Group** that should cover it (e.g. `engineers-prod`, `analysts-l1`, `read-only`). Staff access is now complete — no per-user work. -4. **Invite the customer's designated contacts directly on the new org,** using a predefined role. Do not add them to any group. -5. **Configure the rest of the tenant** (installation keys, adapters, D&R rules, outputs) — often from Infrastructure-as-Code templates if you have them; see [Infrastructure Extension](../../5-integrations/extensions/limacharlie/infrastructure.md). -6. **Run the [verification checklist](user-access.md#suggested-validation-checklist-for-a-new-production-organization)** before declaring the tenant live. +1. **Create the customer's organization.** The user who creates the org gets the `Owner` role on it. +2. **Grant `Owner` to a shared internal account also.** Administrative access must not depend on the personal account of the creator. `limacharlie --oid user permissions set-role --email --role Owner`. A full transfer of billing and legal ownership is a separate support request. See [Can I Transfer Ownership of an Organization?](../../8-reference/faq/account-management.md#can-i-transfer-ownership-of-an-organization). +3. **Add the new org to each staff Organization Group** that must cover it, for example `engineers-prod`, `analysts-l1`, and `read-only`. Staff access is then complete, with no work for each user. +4. **Invite the designated contacts of the customer directly on the new org.** Give them a predefined role. Do not add them to a group. +5. **Configure the rest of the tenant**: installation keys, adapters, D&R rules, and outputs. You can build this configuration from Infrastructure-as-Code templates. See [Infrastructure Extension](../../5-integrations/extensions/limacharlie/infrastructure.md). +6. **Run the [verification checklist](user-access.md#suggested-validation-checklist-for-a-new-production-organization)** before the tenant goes live. ## Anti-patterns to avoid | Anti-pattern | Why it breaks | What to do instead | | --- | --- | --- | -| Adding staff directly to each customer org | Does not scale, drifts, permissions diverge across orgs | Staff access only via Organization Groups, by job function | -| Putting customer users in a multi-tenant group | Groups are additive — the user now sees every other org in the group | Direct users on the customer's own org only | -| One huge "everyone" staff group with every permission | No separation of duties, no prod gate | Split groups by role (`Viewer`, `Operator`, `Administrator`) and by blast radius (`nonprod` vs `prod`) | -| Using a user API key for an integration | Scopes to every org the user can reach; breaks when the user leaves | Organization API key scoped to the minimum permissions on that single org | -| Hand-picking permissions for every user | Hard to audit, easy to drift | Use predefined roles (`set-role`) and refine only when a role genuinely does not fit | +| Adding staff directly to each customer org | Does not scale. The permissions drift and become different in each org | Give staff access only through Organization Groups, by job function | +| Putting customer users in a multi-tenant group | Groups are additive. The user then sees every other org in the group | Direct users on the customer's own org only | +| One huge "everyone" staff group with every permission | No separation of duties, and no control for production access | Split groups by role (`Viewer`, `Operator`, `Administrator`) and by scope of impact (`nonprod` and `prod`) | +| Using a user API key for an integration | Gives access to every org that the user can reach. The integration fails when the user leaves | Organization API key scoped to the minimum permissions on that single org | +| Hand-picking permissions for every user | Hard to audit. The permissions drift | Use predefined roles (`set-role`) and change the permissions only when no role fits | --- ## Related -- [User Access](user-access.md) — mechanics of adding users, groups, and verifying access. +- [User Access](user-access.md) — how to add users and groups, and how to check access. - [Reference: Permissions](../../8-reference/permissions.md) — full permission catalogue and predefined roles. -- [API Keys](api-keys.md) — machine access, Organization vs. User API keys. +- [API Keys](api-keys.md) — machine access, Organization API keys and User API keys. - [SSO](sso.md) — federated authentication and strict SSO enforcement. -- [Security Service Providers (MSSP, MSP, MDR)](../../1-getting-started/use-cases/mssp-msp-mdr.md) — broader MSSP platform use cases. +- [Security Service Providers (MSSP, MSP, MDR)](../../1-getting-started/use-cases/mssp-msp-mdr.md) — wider MSSP platform use cases. diff --git a/docs/7-administration/access/sso.md b/docs/7-administration/access/sso.md index 933f1ef6e..07e665e61 100644 --- a/docs/7-administration/access/sso.md +++ b/docs/7-administration/access/sso.md @@ -1,32 +1,32 @@ # Single Sign-On -Single sign-on (SSO) is available at no extra cost for customers that leverage LimaCharlie's custom branded offering. If this applies to your Organization, and if you are interested in using the SSO, please submit a [Custom Branding / SSO Request](https://limacharlie.io/custom-branding). +Single sign-on (SSO) has no extra cost for customers who use the custom branded offering of LimaCharlie. If this applies to your Organization and you want to use SSO, submit a [Custom Branding / SSO Request](https://limacharlie.io/custom-branding). -If your organization does not currently have a custom branded site with LimaCharlie, you can learn about the requirements, costs & get started here. +If your organization does not have a custom branded site with LimaCharlie, you can learn the requirements and the costs before you start. ## Strict SSO Enforcement -LimaCharlie offers the ability to implement strict SSO enforcement. This means that SSO can be configured as the only authentication option. +LimaCharlie can enforce SSO strictly. You can configure SSO as the only authentication option. -With this capability, you may say that any user with your email domain @example.com must authenticate via Google. This way you can disable the login + password, GitHub, and Microsoft login options for users with your email domain (@example.com) - regardless if they are logging in via your custom branded site, or via app.limacharlie.io +For example, you can declare that each user with your email domain @example.com must authenticate through Google. You can then disable the login and password option, the GitHub option, and the Microsoft option for users with your email domain (@example.com). This applies to your custom branded site and to app.limacharlie.io. ## How It Works -LimaCharlie's single sign-on functionality lets companies add their own SSO option that goes through their authentication server instead of through Google or something else. Identity Platform acts as the coordinator here. After configuring new Providers in Identity Platform, the app only needs to specify a provider ID, and then Identity Platform will handle talking to the company's auth server. +Single sign-on lets a company add its own SSO option. The option uses the authentication server of the company instead of Google or another provider. Identity Platform coordinates this exchange. After you configure new Providers in Identity Platform, the app gives only a provider ID. Identity Platform then communicates with the auth server of the company. ## User Experience -The high-level user experience is as follows: +The user experience is as follows: -- For organizations that choose to use SSO, the SSO will be enforced. Users going to custom branded versions of the LimaCharlie site will be presented with only the option to login through SSO, if their domain has the SSO configuration. +- LimaCharlie enforces SSO for the organizations that select it. A user who opens a custom branded version of the LimaCharlie site sees only the SSO login option, if the domain of the user has the SSO configuration. -![sso 1](../../assets/images/sso-1.png) + ![sso 1](../../assets/images/sso-1.png) -- The same user going to the non-branded site would still be presented with all other authentication options. However, a user would only be able to use the authentification option approved for their domain. +- The same user on the non-branded site still sees all the other authentication options. But the user can use only the authentication option that is approved for their domain. -![sso 2](../../assets/images/sso-2.png) + ![sso 2](../../assets/images/sso-2.png) -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment for security data, configurations, and assets. Each Organization has its own sensors, detection rules, data sources, and outputs. This structure supports multi-tenant setups for managed security providers, and for enterprises with many departments or clients. ## Related Articles diff --git a/docs/7-administration/access/user-access.md b/docs/7-administration/access/user-access.md index 380c66d00..a278c802d 100644 --- a/docs/7-administration/access/user-access.md +++ b/docs/7-administration/access/user-access.md @@ -1,41 +1,41 @@ # User Access !!! tip "Running more than one organization?" - If you operate multiple organizations — for example as an MSSP, MDR, or an enterprise with several business units — read [Designing Access for Multi-Org Deployments](designing-access.md) first. It explains how to structure organizations, groups, and roles so that the individual steps below compose into a safe, maintainable access model. + If you operate more than one organization, for example as an MSSP, MDR, or an enterprise with several business units, read [Designing Access for Multi-Org Deployments](designing-access.md) first. It explains how to structure organizations, groups, and roles. The steps below then make a safe access model that you can maintain. -To control who has access to an Organization, and what they have access to, go to the "Users" section of the web application. +To control who has access to an Organization, and what they can access, go to the "Users" section of the web app. -Adding users is done by email address and requires the user to already have a limacharlie.io account. +You add a user by email address. The user must have a limacharlie.io account. -The first user of an organization is added with Owner permissions at creation time. Owner permissions give full access to everything. +The first user of an organization gets Owner permissions when you create the organization. Owner permissions give full access to everything. -New users added after the creation of an organization are added with Unset privileges, which means the user is only able to get the most basic information on the organization. +A user that you add after the creation of an organization gets Unset privileges. Such a user can get only the most basic information about the organization. -Therefore, the first step after adding a new user should always be to change their permissions by clicking the Edit icon beside their name. +After you add a new user, always change their permissions first. Click the Edit icon beside the name of the user. -Permissions can be controlled individually, or you can apply pre-set permission schemes by selecting it at the top of the dialog box, clicking Apply, and then clicking the Save button at the bottom. +You can set each permission individually. You can also apply a pre-set permission scheme: select the scheme at the top of the dialog box, click Apply, then click the Save button at the bottom. User Permissions -We offer granular user permissions, allowing you to customize what roles and how much access users should have. For a full list of permissions, see [Reference: Permissions](../../8-reference/permissions.md). +LimaCharlie has granular user permissions. You control the roles and the level of access of each user. For the full list of permissions, see [Reference: Permissions](../../8-reference/permissions.md). ## Access on a per-organization basis -To add a user to an Organization, the new user needs to first create their own LimaCharlie account. +Before you add a user to an Organization, the new user must create their own LimaCharlie account. -After the new user has created their LimaCharlie account, you can add them by inputting their email account to your Organization. +After the new user creates the LimaCharlie account, add the email address of the user to your Organization. -After adding the user, you have the ability to control what permissions they get in this tenant. To do so, click on their email and adjust their permissions in the modal that opens. (See information about user permissions above). +After you add the user, you control the permissions that the user gets in this tenant. Click the email address of the user and change the permissions in the modal that opens. (See the information about user permissions above.) ![NewSS 1](../../assets/images/NewSS_1.png) ## Access via Organization Groups -Groups allow you to grant permissions to a set of users on a group of organizations. To get started, navigate to the upper right section of the web app and select groups. +Groups let you grant permissions to a set of users on a group of organizations. To start, go to the upper right section of the web app and select groups. ![NewSS 2](../../assets/images/NewSS_2.png) -From there, create a new group or click to edit an existing one. +Then create a new group, or click an existing group to edit it. ![NewSS 3](../../assets/images/NewSS_3.png) @@ -45,43 +45,43 @@ You can add multiple group owners. ![NewSS4](../../assets/images/NewSS4.png) -In the **Users** section (left panel), you can add all existing users who should receive access to the organizations included in this group. Note that if you are a Group Owner and you want the permissions of this group to apply to yourself, you will need to add your email here as well. +In the **Users** section (left panel), add each existing user that needs access to the organizations in this group. If you are a Group Owner and you want the permissions of this group to apply to you, add your email address here also. Adding Accounts -Note that all accounts will need to be *existing* LimaCharlie users. +All accounts must be *existing* LimaCharlie users. ![NewSS 5](../../assets/images/NewSS_5.png) -Group owners are allowed to manage the group, but are not affected by the permissions. Members are affected by the permissions but cannot modify the group. +Group owners can manage the group, but the permissions do not apply to them. The permissions apply to members, but members cannot change the group. -Under **Organizations** (left panel), select a list of organizations you have access to. Note that in order to add an organization to the group, you need to have the user.ctrl permission enabled for that organization. +Under **Organizations** (left panel), select a list of organizations that you can access. To add an organization to the group, you must have the user.ctrl permission enabled for that organization. ![NewSS 6](../../assets/images/NewSS_6.png) -Last, select the permissions you want members of the group to have in the organizations included in this group. +Last, select the permissions for the members of the group in the organizations of this group. -Permissions granted through the group are applied on top of permissions granted at the organization level. The permissions are additive, and a group cannot be used to subtract permissions granted at the organization level. +The group adds its permissions to the permissions at the organization level. The permissions are additive. A group cannot subtract the permissions that the organization grants. ![NewSS 7](../../assets/images/NewSS_7.png) To finish, click `Update Permissions` at the top right corner. -To review activity that has occurred in this group, click on **Activity Logs** (left panel). +To review the activity in this group, click **Activity Logs** (left panel). ![To finish, click Update Permissions at the top right corner](../../assets/images/image(343).png) ## Verifying and Reviewing Access -After creating a new organization — especially a production tenant — you will typically want to confirm, to yourself or to a system administrator, exactly who can reach the org and with which permissions. Access to an organization comes from two sources: users added **directly** to the organization, and users added via an **Organization Group** that includes the organization. A complete review must cover both. +After you create a new organization, and especially a production tenant, confirm to yourself or to a system administrator who can reach the org and with which permissions. Access to an organization comes from two sources: users added **directly** to the organization, and users added through an **Organization Group** that includes the organization. A complete review must cover both sources. -The sections below show how to answer the common questions using the web app, the `limacharlie` CLI, or both. All CLI examples assume you have selected the organization you want to inspect (either via `--oid ` or through `limacharlie auth use-org`). +The sections below answer the common questions with the web app, the `limacharlie` CLI, or both. Each CLI example assumes that you selected the organization to inspect, with `--oid ` or with `limacharlie auth use-org`. ### 1. Who has direct access to this organization? -**Web app:** open the organization and go to the **Users** section. Every account listed there has been added directly to the organization. Click an email to see the exact permissions granted to that user. +**Web app:** open the organization and go to the **Users** section. Each account in that list is added directly to the organization. Click an email address to see the exact permissions of that user. -**CLI:** list the users directly on the organization, and pull the full per-user permission map: +**CLI:** list the users that are directly on the organization, and get the full permission map for each user: ```bash # Users added directly to the org @@ -91,15 +91,15 @@ limacharlie user list limacharlie user permissions list ``` -Cross-reference the list against the people who are *supposed* to have access. Any user who should not be there can be removed with `limacharlie user remove --email
` or from the **Users** section of the web app. +Compare the list with the people that must have access. To remove a user who must not be there, use `limacharlie user remove --email
` or the **Users** section of the web app. ### 2. Which groups grant access to this organization? -Users can also reach the organization through Organization Groups. An org-level user review alone will not show those users — you need to review the groups as well. +Users can also reach the organization through Organization Groups. A review of the users at the org level does not show those users. You must review the groups also. -**Web app:** open **Groups** from the upper-right menu. Open each group you own or manage and look at the **Organizations** panel: if your new production organization appears there, every user listed in the **Users** panel of that group inherits the group's permissions on it. +**Web app:** open **Groups** from the upper-right menu. Open each group that you own or manage and look at the **Organizations** panel. If your new production organization is in that panel, each user in the **Users** panel of that group gets the permissions of the group on it. -**CLI:** list your groups, then inspect each group's organizations, members, owners, and permissions: +**CLI:** list your groups, then inspect the organizations, members, owners, and permissions of each group: ```bash # List all groups visible to you @@ -109,28 +109,28 @@ limacharlie group list limacharlie group get --id ``` -If the production organization appears under `orgs` for a group, every email under `members` has the permissions listed under `perms` on that organization (in addition to any direct permissions they hold). +If the production organization is under `orgs` for a group, each email under `members` has the permissions under `perms` on that organization. These permissions are additional to the direct permissions of the user. !!! note - The permissions granted by a group are **added** to any permissions the user already has on the organization directly. Groups can only *add* access, never subtract it — so a user who is directly over-privileged cannot be "downgraded" by a group. + A group **adds** its permissions to the permissions that the user already has directly on the organization. A group can only *add* access, it can never subtract access. A group cannot reduce the access of a user who has too many direct permissions. ### 3. What effective permissions does a given user have? -To confirm the final, effective permission set for a single user on a production org: +To confirm the effective permission set of one user on a production org: -1. Start with the user's direct permissions: in the web app, open **Users**, click the user, and note the checked permissions — or use `limacharlie user permissions list` and look up the user's email in the output. -2. Then walk every group that includes this organization (see step 2 above) and note each group whose **Users** panel contains this user. Add the group's permissions to the user's direct permissions. -3. The union of those sets is the effective access the user has on the organization. +1. Start with the direct permissions of the user. In the web app, open **Users**, click the user, and record the checked permissions. You can also run `limacharlie user permissions list` and find the email address of the user in the output. +2. Examine every group that includes this organization (see step 2 above). Record each group whose **Users** panel contains this user. Add the permissions of the group to the direct permissions of the user. +3. The union of those sets is the effective access of the user on the organization. -For a cleaner starting point on a new production org, assign a [predefined role](../../8-reference/permissions.md) with `limacharlie user permissions set-role --email
--role ` — this replaces any prior direct permissions for the user on that org. +For a clear starting point on a new production org, assign a [predefined role](../../8-reference/permissions.md) with `limacharlie user permissions set-role --email
--role `. This command replaces the previous direct permissions of the user on that org. ### 4. What access-related changes have been made, and by whom? -Both the organization and every group maintain an audit trail you can use to verify that the access posture you see today is the result of intended changes. For long-term compliance, consider also forwarding the `audit` stream to separate, append-only storage via an [Output](../../5-integrations/outputs/stream-structures.md#3-audit-stream-structure). +The organization and each group keep an audit trail. Use the audit trail to check that the current access is the result of intended changes. For long-term compliance, you can also send the `audit` stream to separate, append-only storage with an [Output](../../5-integrations/outputs/stream-structures.md#3-audit-stream-structure). -**Organization audit log (web app):** open **Audit Logs** in the organization. Filter for user-management events to see when users were invited, removed, or had their permissions changed, and by which account. +**Organization audit log (web app):** open **Audit Logs** in the organization. Filter for user-management events. These events show when an account invited a user, removed a user, or changed the permissions of a user. -**Organization audit log (CLI):** the `limacharlie audit list` command returns administrative events for the organization. Each entry includes `ident` (the account that performed the action), `etype` (event type), `msg`, and `ts`: +**Organization audit log (CLI):** the `limacharlie audit list` command returns administrative events for the organization. Each entry includes `ident` (the account that did the action), `etype` (event type), `msg`, and `ts`: ```bash # Last 24 hours (default window) @@ -140,23 +140,23 @@ limacharlie audit list limacharlie audit list --start $(date -d '2026-04-01' +%s) --end $(date +%s) ``` -**Group audit log:** each Organization Group has its own activity log, reachable from **Activity Logs** in the group's left panel in the web app, or via: +**Group audit log:** each Organization Group has its own activity log. Open it from **Activity Logs** in the left panel of the group in the web app, or use this command: ```bash limacharlie group logs --gid ``` -Use the group log to verify who added the production org to the group, who added members, and when permissions on the group were last changed. +Use the group log to check who added the production org to the group, who added members, and when the permissions of the group changed last. ### Suggested validation checklist for a new production organization -A practical sequence to hand to a system administrator when standing up a production tenant: +Give this sequence to a system administrator when you set up a production tenant: -1. **Confirm the direct user list.** `limacharlie user list` (or the **Users** page) should match the agreed list of production operators exactly. Remove anyone unexpected. -2. **Confirm each user's permissions are intentional.** Inspect `limacharlie user permissions list` or the per-user permission modal in the web app. Prefer applying a [predefined role](../../8-reference/permissions.md) over hand-picked permissions unless you have a specific reason. -3. **Enumerate every group the org belongs to.** Run `limacharlie group list` and `limacharlie group get --id ` for each group, and record every group whose `orgs` array contains the new org. Confirm each group's `members` and `perms` are expected. -4. **Compute effective access per user.** For each operator, union direct permissions with permissions from every group containing the org. Confirm the result matches the documented access policy. -5. **Review the audit trail.** Walk `limacharlie audit list` since the org was created, plus `limacharlie group logs --gid ` for each group granting access, to confirm that every user addition and permission grant was performed by an authorized administrator. -6. **Re-run this checklist on a cadence.** Access drifts as people join and leave. The same commands can be scripted into a periodic review for ongoing compliance. +1. **Confirm the direct user list.** The output of `limacharlie user list`, or the **Users** page, must match the agreed list of production operators exactly. Remove each unexpected user. +2. **Confirm that the permissions of each user are intentional.** Inspect the output of `limacharlie user permissions list`, or the permission modal for each user in the web app. Apply a [predefined role](../../8-reference/permissions.md) instead of hand-picked permissions, unless you have a specific reason. +3. **Enumerate every group that contains the org.** Run `limacharlie group list` and `limacharlie group get --id ` for each group. Record every group whose `orgs` array contains the new org. Confirm that the `members` and the `perms` of each group are correct. +4. **Compute the effective access of each user.** For each operator, add the permissions from every group that contains the org to the direct permissions. Confirm that the result matches the documented access policy. +5. **Review the audit trail.** Examine `limacharlie audit list` for the period after the creation of the org. Also examine `limacharlie group logs --gid ` for each group that grants access. Confirm that an authorized administrator did each addition of a user and each grant of a permission. +6. **Run this checklist again at regular intervals.** Access drifts when people join and leave. You can put the same commands in a script for a periodic review. -In LimaCharlie, an Organization represents a tenant within the Agentic SecOps Workspace, providing a self-contained environment to manage security data, configurations, and assets independently. Each Organization has its own sensors, detection rules, data sources, and outputs, offering complete control over security operations. This structure enables flexible, multi-tenant setups, ideal for managed security providers or enterprises managing multiple departments or clients. +In LimaCharlie, an Organization is a tenant in the Agentic SecOps Workspace. It is a self-contained environment for security data, configurations, and assets. Each Organization has its own sensors, detection rules, data sources, and outputs. This structure supports multi-tenant setups for managed security providers, and for enterprises with many departments or clients. diff --git a/docs/7-administration/billing/custom-plans.md b/docs/7-administration/billing/custom-plans.md index b4286b019..b46a020bb 100644 --- a/docs/7-administration/billing/custom-plans.md +++ b/docs/7-administration/billing/custom-plans.md @@ -2,15 +2,15 @@ > Applicability > -> This page only applies to Organizations with a contracted custom billing plan. +> This page applies only to Organizations with a contracted custom billing plan. -If your organization has a custom pricing plan, follow these steps to ensure it's correctly applied when creating your organization. You will need to know the exact plan ID that's been allocated for your organization. If you're unsure about your plan details or need assistance, please reach out. +If your organization has a custom pricing plan, obey these steps. The steps make sure that the plan applies when you create your organization. You must know the exact plan ID for your organization. If you do not know the details of your plan, or if you need help, contact LimaCharlie. -How to apply your custom billing plan to newly created organizations: +To apply your custom billing plan to a new organization: -- Web UI: When creating your organization, select your assigned plan from the drop-down menu. -- API Users: If using the API, specify your plan using the appropriate `loc` parameter. -- REST API: Use the `loc` parameter (general location). If you need to specify a custom plan, provide the exact plan ID. [API Documentation](https://api.limacharlie.io/static/swagger/#/Organizations/requestCreateOrg) +- Web UI: When you create your organization, select your assigned plan in the drop-down menu. +- API Users: With the API, give your plan in the correct `loc` parameter. +- REST API: Use the `loc` parameter (general location). For a custom plan, give the exact plan ID. [API Documentation](https://api.limacharlie.io/static/swagger/#/Organizations/requestCreateOrg) - Python SDK: Use the `location` parameter for the same purpose. [Python SDK Reference](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Manager.py#L1197) -Note: If you do not specify your custom plan at the time your organization is created, you will be put on standard pricing and will not receive discounted pricing. +Note: If you do not give your custom plan when you create the organization, you get standard pricing. You do not get the discounted pricing. diff --git a/docs/7-administration/billing/data-estimation.md b/docs/7-administration/billing/data-estimation.md index 35bc17024..f28105525 100644 --- a/docs/7-administration/billing/data-estimation.md +++ b/docs/7-administration/billing/data-estimation.md @@ -1,20 +1,20 @@ # Estimating Data Ingestion -This guide helps you estimate how much data your organization might ingest into LimaCharlie, so you can plan costs before deploying. +This guide helps you estimate how much data your organization ingests into LimaCharlie. Use the estimate to plan your costs before you deploy. ## How LimaCharlie Bills for Data -LimaCharlie has two billing models depending on the data source: +LimaCharlie has two billing models. The model depends on the data source: -**EDR endpoints** (Windows, macOS, Linux, Chrome) are billed **per endpoint per month** at a flat rate. This includes all telemetry generated by the endpoint agent and 1 year of full telemetry retention. You do not need to estimate data volume for EDR endpoints — it is already included in the per-endpoint price regardless of how much telemetry they generate. +LimaCharlie bills **EDR endpoints** (Windows, macOS, Linux, Chrome) at a flat rate, **per endpoint per month**. The price includes all the telemetry from the sensor and 1 year of full telemetry retention. You do not need to estimate the data volume for EDR endpoints. The price for each endpoint includes all the telemetry that the endpoint generates. -**External telemetry** (data ingested via [Adapters](../../2-sensors-deployment/adapters/index.md)) is billed **per GB ingested**. This covers third-party log sources like cloud providers, identity platforms, SaaS applications, network devices, and other security tools. These sources also include 1 year of telemetry retention. +LimaCharlie bills **external telemetry** (data ingested through [Adapters](../../2-sensors-deployment/adapters/index.md)) **per GB ingested**. This model covers third-party log sources: cloud providers, identity platforms, SaaS applications, network devices, and other security tools. These sources also include 1 year of telemetry retention. For current pricing details, see [limacharlie.io/pricing](https://limacharlie.io/pricing). ## Company Size Definitions -The estimates in this guide use the following size brackets, defined by the number of employees and the typical infrastructure that comes with each: +The estimates in this guide use the size brackets below. Each bracket has a number of employees and the typical infrastructure for that number: | Size | Employees | Typical Endpoints | Typical Servers | |------|-----------|-------------------|-----------------| @@ -23,20 +23,20 @@ The estimates in this guide use the following size brackets, defined by the numb | Large | 1,000–5,000 | 1,000–5,000 | 100–500 | > [!NOTE] -> These are rough guidelines. Your actual numbers depend on your industry, infrastructure maturity, and which data sources you choose to ingest. Use these estimates as a starting point and refine based on your environment. +> These values are guidelines. Your actual numbers depend on your industry, the maturity of your infrastructure, and the data sources that you ingest. Use these estimates as a starting point, then adjust them for your environment. ## External Telemetry Sources -The tables below estimate **daily ingestion volumes** for common categories of external data sources. All values are in GB/day. +The tables below give estimates of the **daily ingestion volumes** for common categories of external data sources. All values are in GB/day. ### Cloud Infrastructure Logs -Logs from cloud providers (AWS CloudTrail, Azure Monitor, GCP Audit Logs) covering API calls, resource changes, and access events. +Logs from cloud providers (AWS CloudTrail, Azure Monitor, GCP Audit Logs). These logs cover API calls, resource changes, and access events. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| -| AWS CloudTrail | 0.5–2 GB | 2–10 GB | 10–50 GB | Scales with number of AWS accounts and API call volume | -| AWS GuardDuty | 0.1–0.5 GB | 0.5–2 GB | 2–8 GB | Finding volume depends on threat activity | +| AWS CloudTrail | 0.5–2 GB | 2–10 GB | 10–50 GB | Scales with the number of AWS accounts and the volume of API calls | +| AWS GuardDuty | 0.1–0.5 GB | 0.5–2 GB | 2–8 GB | The volume of findings depends on the threat activity | | Azure Monitor / Activity Logs | 0.5–2 GB | 2–8 GB | 8–40 GB | Includes sign-in, audit, and resource logs | | GCP Audit Logs | 0.5–1 GB | 1–5 GB | 5–25 GB | Admin activity + data access logs | @@ -44,7 +44,7 @@ Logs from cloud providers (AWS CloudTrail, Azure Monitor, GCP Audit Logs) coveri ### Identity & Access Management -Logs from identity providers tracking authentications, MFA events, directory changes, and access policies. +Logs from identity providers. These logs track authentications, MFA events, directory changes, and access policies. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| @@ -57,41 +57,41 @@ Logs from identity providers tracking authentications, MFA events, directory cha ### Email & Collaboration -Audit logs from email and collaboration platforms covering user activity, admin actions, and compliance events. +Audit logs from email and collaboration platforms. These logs cover user activity, admin actions, and compliance events. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| -| Microsoft 365 Audit | 0.2–1 GB | 1–5 GB | 5–20 GB | 50–200 audit records per active user per day; SharePoint and Teams users generate more | +| Microsoft 365 Audit | 0.2–1 GB | 1–5 GB | 5–20 GB | 50–200 audit records for each active user each day. SharePoint and Teams users generate more | | Google Workspace | 0.1–0.5 GB | 0.5–3 GB | 3–12 GB | Admin, Drive, Login, and Token activity | -| Slack Audit Log | < 0.1 GB | 0.1–0.5 GB | 0.5–2 GB | Enterprise Grid only; tracks workspace access and admin events | +| Slack Audit Log | < 0.1 GB | 0.1–0.5 GB | 0.5–2 GB | Enterprise Grid only. Tracks workspace access and admin events | **Typical total — Collaboration:** 0.3–1.5 GB/day (small), 1.5–8 GB/day (medium), 8–35 GB/day (large) ### Network Security -Logs from firewalls, IDS/IPS, VPN concentrators, and network proxies. These are often the highest-volume log sources. +Logs from firewalls, IDS/IPS, VPN concentrators, and network proxies. These log sources often have the highest volume. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| -| Firewalls (Palo Alto, Fortinet, etc.) | 1–5 GB | 5–30 GB | 30–150 GB | Connection/traffic logs are very high volume; threat-only logs are 10–50x smaller | -| IDS/IPS | 0.5–2 GB | 2–10 GB | 10–50 GB | Alert volume depends on rule tuning | +| Firewalls (Palo Alto, Fortinet, etc.) | 1–5 GB | 5–30 GB | 30–150 GB | Connection and traffic logs have a very high volume. Threat-only logs are 10–50x smaller | +| IDS/IPS | 0.5–2 GB | 2–10 GB | 10–50 GB | The volume of alerts depends on the tuning of the rules | | VPN / ZTNA | 0.1–0.5 GB | 0.5–2 GB | 2–10 GB | Session and authentication events | -| Web Proxy / DNS | 0.5–3 GB | 3–15 GB | 15–80 GB | Per-request logging is very high volume | +| Web Proxy / DNS | 0.5–3 GB | 3–15 GB | 15–80 GB | Logging for each request has a very high volume | > [!WARNING] -> Network security devices are typically the largest source of log data. Firewall traffic logs alone can dwarf all other sources combined. Consider ingesting only threat events and denied connections rather than full connection logs to manage volume. +> Network security devices are usually the largest source of log data. Firewall traffic logs alone can be larger than all the other sources together. To control the volume, ingest only threat events and denied connections, not the full connection logs. **Typical total — Network:** 2–10 GB/day (small), 10–55 GB/day (medium), 55–290 GB/day (large) ### Third-Party Security Tools -Logs from other EDR, endpoint protection, or security detection platforms forwarded into LimaCharlie for centralized analysis. +Logs from other EDR, endpoint protection, or security detection platforms. You forward these logs into LimaCharlie for central analysis. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| -| CrowdStrike | 0.5–2 GB | 2–8 GB | 8–40 GB | Event volume scales with endpoint count and detection verbosity | +| CrowdStrike | 0.5–2 GB | 2–8 GB | 8–40 GB | The event volume scales with the number of endpoints and the detection verbosity | | Microsoft Defender | 0.5–2 GB | 2–8 GB | 8–30 GB | Alerts, incidents, and raw detection events | -| SentinelOne | 0.5–2 GB | 2–8 GB | 8–30 GB | Deep Visibility data is high volume | +| SentinelOne | 0.5–2 GB | 2–8 GB | 8–30 GB | Deep Visibility data has a high volume | | Sophos | 0.2–1 GB | 1–4 GB | 4–15 GB | Endpoint and network protection events | **Typical total — Security Tools:** 1–5 GB/day (small), 5–25 GB/day (medium), 25–100 GB/day (large) @@ -102,13 +102,13 @@ Audit and activity logs from business applications. | Source | Small | Medium | Large | Notes | |--------|-------|--------|-------|-------| -| GitHub Audit | < 0.1 GB | 0.1–0.5 GB | 0.5–2 GB | Scales with number of repos and developers | -| Kubernetes (pods/audit) | 0.5–2 GB | 2–10 GB | 10–50 GB | Highly variable; depends on cluster size and logging level | -| Custom Syslog sources | 0.1–1 GB | 1–5 GB | 5–20 GB | Varies widely by application | +| GitHub Audit | < 0.1 GB | 0.1–0.5 GB | 0.5–2 GB | Scales with the number of repos and developers | +| Kubernetes (pods/audit) | 0.5–2 GB | 2–10 GB | 10–50 GB | Very variable. Depends on the cluster size and the logging level | +| Custom Syslog sources | 0.1–1 GB | 1–5 GB | 5–20 GB | Changes by a large amount for each application | ## Putting It All Together -The table below shows estimated **total daily external ingestion** based on a typical set of data sources for each company size. Most organizations will not ingest every source listed above. +The table below shows the estimated **total daily external ingestion** for a typical set of data sources at each company size. Most organizations do not ingest every source in the tables above. | Scenario | Small | Medium | Large | |----------|-------|--------|-------| @@ -117,15 +117,15 @@ The table below shows estimated **total daily external ingestion** based on a ty | **Comprehensive** — Above + Network + multiple security tools | 5–25 GB/day | 25–140 GB/day | 140–500+ GB/day | > [!NOTE] -> These estimates assume typical logging verbosity. Enabling verbose or debug logging on any source can increase volumes by 2–10x. Conversely, filtering to only security-relevant events can reduce volumes significantly. +> These estimates assume normal logging verbosity. Verbose logging or debug logging on a source can increase the volumes by 2–10x. A filter that keeps only security-relevant events reduces the volumes by a large amount. ## Tips for Managing Ingestion Costs -1. **Start with high-value, low-volume sources.** Identity logs and cloud audit trails provide excellent security visibility at relatively low data volumes. -2. **Filter at the source.** Many adapters support filtering to reduce noise. For firewalls, ingesting only threat events and denied connections rather than all traffic logs can reduce volume by 90% or more. -3. **Use the LimaCharlie [Usage Alerts](../../5-integrations/extensions/limacharlie/usage-alerts.md) extension** to set thresholds and get notified before unexpected spikes impact your bill. -4. **Monitor your actual usage** in the Billing & Usage section of your organization's settings to compare against these estimates and adjust your ingestion strategy. -5. **Remember that EDR endpoints are flat-rate.** If you're choosing between ingesting a third-party EDR's telemetry versus deploying LimaCharlie's own endpoint agent, the agent's flat per-endpoint pricing is often more cost-effective and provides richer telemetry. +1. **Start with high-value, low-volume sources.** Identity logs and cloud audit trails give good security visibility at low data volumes. +2. **Filter at the source.** Many adapters can filter data to reduce noise. For firewalls, ingest only threat events and denied connections, not all the traffic logs. This filter can reduce the volume by 90% or more. +3. **Use the LimaCharlie [Usage Alerts](../../5-integrations/extensions/limacharlie/usage-alerts.md) extension** to set thresholds. The extension tells you about an unexpected increase before it changes your bill. +4. **Monitor your actual usage** in the Billing & Usage section of the settings of your organization. Compare your usage with these estimates and adjust your ingestion strategy. +5. **Remember that EDR endpoints are flat-rate.** You can ingest the telemetry of a third-party EDR, or deploy the LimaCharlie sensor. The flat rate for each endpoint is often less expensive, and the sensor gives more telemetry. --- diff --git a/docs/7-administration/billing/options.md b/docs/7-administration/billing/options.md index 75afc2c32..4cb85dfed 100644 --- a/docs/7-administration/billing/options.md +++ b/docs/7-administration/billing/options.md @@ -1,34 +1,34 @@ # Billing Options -LimaCharlie users have multiple billing options available to them, depending on their unique needs. We'll walk through these two options, *Default Billing* and *Unified Billing*, below. +LimaCharlie has more than one billing option for the different needs of its users. This page describes the two options, *Default Billing* and *Unified Billing*. ## Default Billing -By default, every Organization is billed using a credit card set at the individual organization level. The billing cycle for each organization starts at the time the organization goes from the free tier into a paid tier. The invoices go to the email address of the user who initially created the organization. +By default, LimaCharlie bills each Organization with a credit card that you set on that organization. The billing cycle of an organization starts when the organization moves from the free tier to a paid tier. The invoices go to the email address of the user who created the organization. ## Unified Billing -For customers that require flexibility managing multiple organizations, LimaCharlie offers unified billing - the ability to customize billing to satisfy their needs. +Unified billing is for customers who need flexibility when they manage many organizations. It lets the customer change the billing configuration for their needs. -All the options described below apply based on the "billing domain", which is the domain name of the email address of a user. For example, the users `ceo@mycorp.com` and `sales@mycorp.com` both belong to the `mycorp.com` billing domain. +All the options below apply to a "billing domain". A billing domain is the domain name in the email address of a user. For example, the users `ceo@mycorp.com` and `sales@mycorp.com` both belong to the `mycorp.com` billing domain. -All organizations under the same billing domain will have their billing cycles on the same day, regardless of the creation time or the time the organization first exits free tier. Instead of receiving one invoice per organization, all invoices for a billing domain will be aggregated together under a single invoice sent manually monthly. +All the organizations in the same billing domain have their billing cycle on the same day. The creation time of the organization, and the time when it exits the free tier, do not change this day. LimaCharlie aggregates all the invoices for a billing domain into one invoice, and sends this invoice manually each month. -The following are the options you can customize as a part of the Unified Billing: +You can configure these options as part of Unified Billing: -- Override the email where each individual organization's invoice goes to. Instead of the email of the creator, a central email address (like ) is used. Billing domains with unified billing enabled will receive a monthly report summarizing all organizations under the domain and their respective billing. -- Choose to be invoiced manually. Organizations in a billing domain can have their invoices sent manually by email without the use of a credit card. This will then allow the recipient to pay invoices using ACH or credit card, but this will have to be done manually each month. +- Override the email address for the invoice of each organization. LimaCharlie then uses a central email address, for example , instead of the email address of the creator. A billing domain with unified billing gets a monthly report. The report summarizes all the organizations in the domain and their billing. +- Select manual invoices. LimaCharlie sends the invoices of the organizations in a billing domain manually by email, without a credit card. The recipient can then pay the invoices with ACH or with a credit card. The recipient must do this payment manually each month. ## Default Billing Setup vs Unified Billing | | Default Billing Setup | Unified Billing | | --- | --- | --- | -| **Can be used by** | Anyone | Customers that have their users share a custom domain name of the email address (for example, the users `ceo@mycorp.com` and `sales@mycorp.com` both belong to the `mycorp.com` domain). | -| **Best suited for** | *Customers that have one or a few (1-3) tenants to manage* Enterprise clients that want to manage billing at the department level (billed to different cards) | *Service providers (MSP, MSSP, DFIR) who manage multiple tenants* Enterprise clients that want to manage billing at the company level (billed to one card) | -| **Payment method used** | Billed using a credit card set at the individual organization level. | One payment method will be used for all organizations under the same billing domain. | -| **Manual invoicing** | Not available | Available Organizations in a billing domain can have their invoices sent manually by email without the use of a credit card. This will then allow the recipient to pay invoices using ACH or credit card, but this will have to be done manually each month. | -| **Billing cycle** | Starts at the time the organization goes from the free tier into a paying tier (different billing cycle for each tenant). | All organizations under the same billing domain will have their billing cycles on the same day. | -| **Invoicing** | Users will receive one invoice per organization. | All invoices for a billing domain will be aggregated together under a single invoice sent manually monthly. | -| **Email invoices go to** | Email address of the user who initially created the organization. | Instead of the email of the creator, a central email address (like `billing@mycorp.com`) is used. Billing domains with unified billing enabled will receive a monthly report summarizing all organizations under the domain and their respective billing. | - -To learn more or to get setup with Unified Billing, [contact us](https://limacharlie.io/contact). +| **Can be used by** | Anyone | Customers whose users share a custom domain name in the email address (for example, the users `ceo@mycorp.com` and `sales@mycorp.com` both belong to the `mycorp.com` domain). | +| **Best suited for** | *Customers that have one to three tenants to manage* Enterprise clients that want to manage billing at the department level (billed to different cards) | *Service providers (MSP, MSSP, DFIR) who manage many tenants* Enterprise clients that want to manage billing at the company level (billed to one card) | +| **Payment method used** | LimaCharlie bills with a credit card that you set on each organization. | One payment method applies to all the organizations in the same billing domain. | +| **Manual invoicing** | Not available | Available LimaCharlie sends the invoices of the organizations in a billing domain manually by email, without a credit card. The recipient can then pay the invoices with ACH or with a credit card, manually each month. | +| **Billing cycle** | Starts when the organization moves from the free tier to a paying tier (a different billing cycle for each tenant). | All the organizations in the same billing domain have their billing cycle on the same day. | +| **Invoicing** | Users get one invoice for each organization. | LimaCharlie aggregates all the invoices for a billing domain into one invoice, and sends it manually each month. | +| **Email invoices go to** | The email address of the user who created the organization. | LimaCharlie uses a central email address (like `billing@mycorp.com`) instead of the email address of the creator. A billing domain with unified billing gets a monthly report. The report summarizes all the organizations in the domain and their billing. | + +To learn more about Unified Billing, or to set it up, [contact LimaCharlie](https://limacharlie.io/contact). diff --git a/docs/7-administration/config-hive/apps.md b/docs/7-administration/config-hive/apps.md index eb6502c04..78eda95b5 100644 --- a/docs/7-administration/config-hive/apps.md +++ b/docs/7-administration/config-hive/apps.md @@ -1,27 +1,27 @@ # Config Hive: Apps -The `app` hive stores user-authored, AI-generated mini web applications. Each record holds a single, self-contained HTML document (HTML plus inline JavaScript and CSS) that the LimaCharlie web UI renders inside a sandboxed `