# Deploying HQ

To install the HQ from the archive you must:

1. Extract the archive
2. Configure the HQ
3. Start the HQ

***

## Extracting the archive

{% hint style="success" %}
**Installation link**

Link to archives can be found here: [**https://archive.lenses.io/lenses/6.1/**](https://archive.lenses.io/lenses/6.1/)
{% endhint %}

Extract the archive using the following command

{% code title="terminal" %}

```sh
tar -xvf lenses-hq-linux-amd64-latest.tar.gz -C lenses-hq
```

{% endcode %}

Inside the extract archive, you will find.

{% code title="terminal" %}

```bash
   lenses-hq
   ├── lenses-hq
```

{% endcode %}

***

## Configuring the HQ

In order to properly configure HQ, one core components is necessary as prerequirement:

* [x] Postgres database

{% stepper %}
{% step %}
**Configure Authentication**

To set up authentication, there are multiple methods available.

You can choose between:

* password-based authentication, which requires users to provide a username and password;
* and SAML/SSO (Single Sign-On) authentication, which allows users to authenticate through an external identity provider for a seamless and secure login experience.

{% hint style="success" %}
Both password based and SAML / SSO authentication methods can be used alongside each other.
{% endhint %}

**First** to cover is users property.

**Users Property:** The `users` property is defined as an array, where each entry includes a `username` and a `password`. The passwords are hashed using bcrypt for security purposes, ensuring that they are stored securely.

**Second** to cover will be ***administrators**.* It serves as definition of user emails which will have highest level of permissions upon authentication to HQ.

{% hint style="info" %}
Assertion Consumer Service endpoint is following

```
/api/v2/auth/saml/callback?client_name=SAML2Client
```

{% endhint %}

{% code title="config.yaml" %}

```yaml
auth:
  users:
    - username: admin
      password: $2a$10$F66cb6ZhnJjGCZuxlvKP1e84eytTpT1MDJcpBblHaZgsqp1/Aa0LG # bcrypt("correcthorsebatterystaple").
  administrators:
    - admin
    - admin@example.com
  saml:
    enabled: true
    metadata: |-
      <?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor>
      ...
      ...
      </md:EntityDescriptor>
    # Defines base URL of HQ for IdP redirects
    baseURL: https://changeme.com # <--- Change this
    # Defines  globally unique identifier for the SAML entity 
    # — either the Service Provider (SP) or Identity Provider (IdP)
    # It's often a URL, but it doesn't necessarily need to resolve to anything
    entityID: https://example.com # <--- Change this
    userCreationMode: sso
    groupMembershipMode: sso
```

{% endcode %}

Full auth configuration spec can be found in the [Configuration Reference](https://docs.lenses.io/latest/configuration/hq/configuration-reference#authconfig).
{% endstep %}

{% step %}
**Configure HTTP endpoint**

Another part which has to be set in order to successfully run HQ is the *`http`* definition. As previously mentioned, this parameter defines everything around HTTP endpoint of the HQ itself and how users will interact with.

Definition of HTTP object is as follows:

{% tabs %}
{% tab title="TLS enabled" %}
{% code title="config.yaml" %}

```yaml
http:
  address: :8080
  accessControlAllowOrigin:
    - https://example.com
  accessControlAllowCredentials: false
  secureSessionCookies: false
  tls:
    enabled: true
    cert: |
      -----BEGIN CERTIFICATE-----
      MIIDXTCCAkWgAwIBAgIJALkNfT3d1N8tMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
      BAYTAlVTMRYwFAYDVQQKEw1FeGFtcGxlIENlcnQwHhcNMjUwMzI2MDAwMDAwWhcN
      MzUwMzIzMDAwMDAwWjBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNZXhhbXBsZS5j
      b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5D3jXq5JnE9NnRJ8N
      ...
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
      ...
      -----END PRIVATE KEY-----
```

{% endcode %}
{% endtab %}

{% tab title="TLS disabled" %}
{% code title="config.yaml" %}

```yaml
http:
  address: :8080
  accessControlAllowOrigin:
    - https://example.com
  accessControlAllowCredentials: false
  secureSessionCookies: false
  tls:
    enabled: false
```

{% endcode %}
{% endtab %}
{% endtabs %}

More about setting up TLS can be read in [HQ](https://docs.lenses.io/latest/configuration/hq#tlsconfig). Full HTTP configuration spec can be found in the [Configuration Reference](https://docs.lenses.io/latest/configuration/hq/configuration-reference#httpconfig).
{% endstep %}

{% step %}
**Configure Agent endpoint**

After correctly configuring authentication strategy and connection endpoint , agent handling is the last most important box to tick.

The Agent's object is defined as follows:

{% tabs %}
{% tab title="TLS enabled" %}
{% code title="config.yaml" %}

```yaml
agents:
  address: :10000
  tls:
    enabled: true
    cert: |
      -----BEGIN CERTIFICATE-----
      MIIDXTCCAkWgAwIBAgIJALkNfT3d1N8tMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
      BAYTAlVTMRYwFAYDVQQKEw1FeGFtcGxlIENlcnQwHhcNMjUwMzI2MDAwMDAwWhcN
      MzUwMzIzMDAwMDAwWjBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNZXhhbXBsZS5j
      b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5D3jXq5JnE9NnRJ8N
      ...
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
      ...
      -----END PRIVATE KEY-----
```

{% endcode %}
{% endtab %}

{% tab title="TLS disabled" %}
{% code title="config.yaml" %}

```yaml
agents:
  address: :10000
  tls:
    enabled: false
```

{% endcode %}
{% endtab %}
{% endtabs %}

More about setting up TLS can be read in [HQ](https://docs.lenses.io/latest/configuration/hq#tlsconfig).
{% endstep %}

{% step %}
**Configure database**

Prerequisite:

* Running Postgres instance;
* Created database for HQ;
* Username (and password) which has access to created database;

In order to successfully run HQ, ***storage*** within *config.yaml* has to be defined first.

Definition of *storage* object is as follows:

{% code title="config.yaml" %}

```yaml
database:
  host: postgres:5432
  username: panoptes
  password: password
  database: panoptes
  schema: insert-schema-here
  # Params example - not required and it depends on your PG requirements
  params:
    sslmode: require
```

{% endcode %}

Full database configuration spec can be found in the [Configuration Reference](https://docs.lenses.io/latest/configuration/hq/configuration-reference#databaseconfig).
{% endstep %}

{% step %}
**Configure monitoring**

{% code title="config.yaml" %}

```yaml
metrics:
  prometheusAddress: :9090
```

{% endcode %}
{% endstep %}

{% step %}
**Configure license and accept EULA**

{% hint style="success" %}
In demo purposes and testing the product you can use our community license

```yaml
license_key_2SFZ0BesCNu6NFv0-EOSIvY22ChSzNWXa5nSds2l4z3y7aBgRPKCVnaeMlS57hHNVboR2kKaQ8Mtv1LFt0MPBBACGhDT5If8PmTraUM5xXLz4MYv
```

{% endhint %}

{% code title="config.yaml" %}

```yaml
license:
  key: license_key_*
  acceptEULA: true
```

{% endcode %}
{% endstep %}
{% endstepper %}

***

## Final Configuration File

If you have meticulously followed all the outlined steps, your *config.yaml* file should mirror the example provided below, fully configured and ready for deployment. This ensures your system is set up correctly with all necessary settings for authentication, database connection, and other configurations optimally defined.

{% code title="config.yaml" %}

```yaml
auth:
  users:
    - username: admin
      password: $2a$10$F66cb6ZhnJjGCZuxlvKP1e84eytTpT1MDJcpBblHaZgsqp1/Aa0LG # bcrypt("correcthorsebatterystaple").
  administrators:
    - admin
    - admin@example.com
  saml:
    enabled: true
    metadata: |-
      <?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor>
      ...
      ...
      </md:EntityDescriptor>
    baseURL: https://example.com
    entityID: https://example.com
    userCreationMode: sso
    groupMembershipMode: sso
http:
  address: ":8080"
  accessControlAllowOrigin:
    - https://example.com
agents:
  address: ":10000"
database:
  host: postgres:5432
  username: panoptes
  password: password
  database: panoptes
  schema: insert-schema-here
  params:
    sslmode: require
license:
  key: license_key_*
  acceptEULA: true
logger:
  mode: text
  level: debug
metrics:
  prometheusAddress: :9090

```

{% endcode %}

***

## Starting the HQ

Start Lenses by running:

{% code title="terminal" %}

```sh
./lenses-hq
```

{% endcode %}

or pass the location of the config file:

{% code title="terminal" %}

```sh
./lenses-hq config.yaml
```

{% endcode %}

If you do not pass the location of the config file, the HQ will look for it inside the current (runtime) directory. If it does not exist, it will try its installation directory.

Once HQ starts, it will be listening on the <https://localhost:8080>

To stop HQ, press **CTRL+C**.

***

## SystemD example <a href="#systemd-example" id="systemd-example"></a>

If your server uses systemd as a Service Manager, then manage the Agent (start upon system boot, stop, restart). Below is a simple unit file that starts the Agent automatically on system boot.

{% code fullWidth="false" %}

```systemd
[Unit]
Description=Run HQ service

[Service]
Restart=always
User=[LENSES-USER]
Group=[LENSES-GROUP]
LimitNOFILE=4096
WorkingDirectory=/opt/lenses-hq
ExecStart=/opt/lenses-hq /etc/lenses-hq/config.yaml

[Install]
WantedBy=multi-user.target
```

{% endcode %}

***

## What's next?

After the successful configuration and installation of HQ, the next steps would be:

1. [**Deploying an Agent**](https://docs.lenses.io/latest/deployment/installation/linux/agent)
2. [**Example Policies**](https://docs.lenses.io/latest/deployment/installation/linux/broken-reference)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lenses.io/latest/deployment/installation/linux/hq.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
