# On-Premise SQL

## On-Premise SQL

Use this connector to scan on-prem database hosts.

Supported engines:

* MySQL (includes MariaDB)
* PostgreSQL
* SQL Server

Teleskope runs two operations:

* **Crawling** for metadata discovery
* **Scanning** for data inspection and classification

### Requirements

* You have a Teleskope Account with the Admin role
* Network access from the Teleskope Application or Outpost to the database server
* A valid database user with read-only permissions on all target databases
* Required database grants (see below)

{% stepper %}
{% step %}
**Step 1: Connection details**

**Database type**

Pick the database engine.

**Display Name**

A friendly name for this host in Teleskope.

Example:

```
Production MySQL Server
```

**Server Hostname or IP**

The hostname or IP address of the database server.

Example:

```
db.example.corp
```

**Port**

Default ports by database type:

* **MySQL/MariaDB: 3306**
* **PostgreSQL: 5432**
* **SQL Server: 1433**

Override this value only if your database server is exposed over a non-standard port.
{% endstep %}

{% step %}
**Step 2: Authentication**

Enter the database credentials Teleskope will use to connect:

**Username**

The database user Teleskope should use to authenticate.

Example:

```
teleskope_ro
```

**Password**

The password associated with the database user.

Example:

```
SecurePassword123!
```

**Domain (SQL Server only, optional)**

For **SQL Server** with **Windows / Active Directory authentication**, enter the AD domain of the service account. Teleskope will connect using `DOMAIN\username` and the password above.

* Leave blank for SQL Server authentication (login + password).
* Only shown when the database type is SQL Server.

Example:

```
CORP
```

If you use an AD service account (e.g. `svc_teleskope_sql`), enter the domain (e.g. `CORP`), the username (e.g. `svc_teleskope_sql`), and the account password. Ensure the SQL Server is configured to accept Windows authentication and that the AD account has the required database permissions (see Step 3).
{% endstep %}

{% step %}
**Step 3: Create a read-only user and grant permissions**

Create a dedicated read-only user. Grant only what you need.

**Create the database user**

**MySQL or MariaDB**

```sql
CREATE USER 'teleskope_ro'@'%' IDENTIFIED BY '****PASSWORD****';
```

**PostgreSQL**

```sql
CREATE USER teleskope_ro WITH PASSWORD '****PASSWORD****';
```

**SQL Server** (SQL authentication)

```sql
CREATE LOGIN teleskope_ro WITH PASSWORD = '****PASSWORD****';
```

**SQL Server** (Windows / Active Directory authentication)

If you use an AD service account, create a login from the Windows account instead:

```sql
CREATE LOGIN [DOMAIN\svc_teleskope_sql] FROM WINDOWS;
```

Replace `DOMAIN` and `svc_teleskope_sql` with your domain and service account name. Then grant permissions as below.

**Grant database user permissions**

***Read Access***

**MySQL or MariaDB**

```sql
GRANT SHOW DATABASES, SELECT ON *.* TO 'teleskope_ro'@'%'; 
FLUSH PRIVILEGES;
```

**PostgreSQL versions 14+**

```sql
GRANT pg_read_all_data TO teleskope_ro;
```

**PostgreSQL versions < 14**

Run these commands in `psql`.

```sql
SELECT format('GRANT CONNECT ON DATABASE %I TO teleskope_ro;', datname) 
FROM pg_database 
WHERE datname NOT IN ('template0', 'template1', 'postgres') 
\gexec

SELECT format('GRANT USAGE ON SCHEMA %I TO teleskope_ro;', nspname) 
FROM pg_namespace 
WHERE nspname NOT IN ('pg_toast', 'pg_catalog', 'information_schema') 
\gexec

SELECT format('GRANT SELECT ON ALL TABLES IN SCHEMA %I TO teleskope_ro;', nspname) 
FROM pg_namespace 
WHERE nspname NOT IN ('pg_toast', 'pg_catalog', 'information_schema') 
\gexec
```

**SQL Server**

For SQL authentication, use `teleskope_ro` in the script below. For Windows/AD authentication, use your Windows login name (e.g. `DOMAIN\svc_teleskope_sql`) in place of `teleskope_ro`.

```sql
-- Allow the login to discover databases
GRANT VIEW ANY DATABASE TO teleskope_ro;

-- Grant read access across databases
DECLARE @sql NVARCHAR(MAX);
SET @sql = '';
SELECT @sql += 
    'USE [' + name + ']; 
    IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = ''teleskope_ro'')
        CREATE USER teleskope_ro FOR LOGIN teleskope_ro;
    ALTER ROLE [db_datareader] ADD MEMBER [teleskope_ro];' + CHAR(13)
FROM sys.databases
WHERE state = 0 AND name NOT IN ('tempdb', 'model', 'msdb');
EXEC sp_executesql @sql;
```

<details>

<summary>SQL Server: add permissions only if you hit metadata permission errors</summary>

Start with the minimal grants above. Add more only if a crawl or scan fails.

Common additions:

```sql
-- Some environments require this for metadata queries
GRANT VIEW SERVER STATE TO teleskope_ro;
```

```sql
-- Run per user database when needed
GRANT VIEW DEFINITION TO teleskope_ro;
GRANT VIEW DATABASE STATE TO teleskope_ro;
```

</details>
{% endstep %}

{% step %}
**Step 4: Enroll the database host**

Save the host using the connection details and credentials. Then run your first crawl and scan.
{% endstep %}

{% step %}
**Step 5: Scheduling (per host)**

Scheduling is configured **per host**. This gives you control per SQL server.

A single schedule controls both:

* **Crawling** (metadata discovery)
* **Scanning** (data inspection)

**Run frequency (cron, UTC)**

Set frequency using a standard 5-part cron expression. Cron is evaluated in **UTC**.

Example:

* `0 2 * * *` runs at **02:00 UTC** daily.

If you do not set a custom schedule, Teleskope falls back to:

* The connector’s configured scan frequency, or
* A default daily run at **23:59 UTC**

**Optional execution window (UTC)**

You can restrict jobs to a UTC time window. Cross-midnight windows are supported.

Example:

* Range start time: `22:00 UTC`
* Range end time: `04:00 UTC`

If no window is set, jobs may run at any time.

To enforce the window:

* Teleskope validates the window before starting a job.
* Jobs will not start outside the allowed window.

**Enable / disable scheduling**

You can turn scheduling on or off per host.

**Built-in protections**

Teleskope limits concurrent work to avoid overload. Crawl and scan jobs are queued independently for stability.
{% endstep %}
{% endstepper %}


---

# 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.teleskope.ai/connectors/on-premise-sql.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.
