> For the complete documentation index, see [llms.txt](https://docs.teleskope.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.teleskope.ai/connectors/on-premise-sql.md).

# 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](/setup/deployment/outpost.md) 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 %}
