Skip to main content
Bag of words connects to Microsoft SQL Server over ODBC, reads the tables, views, and columns in the schemas you point it at, and runs read-only T-SQL. Beyond the usual SQL login it supports Kerberos (Windows Integrated) authentication as the app’s service account, and Kerberos SSO, where every query runs under the signed-in user’s own Active Directory identity through constrained delegation. The connector’s registry type is the uppercase string MSSQL. You will see it under Microsoft SQL Server in the data source picker.

How it works

Bag of words connects with the Microsoft ODBC Driver for SQL Server (version 18 by default, 17 available for older servers), reads table and column metadata from the database’s catalog views, and issues SELECT statements at query time. If the enriched metadata read fails on your server it falls back to a basic table and column listing. Scope the connection with database and, optionally, schema — which accepts a comma-separated list, so one connection can cover several schemas. Authentication happens in one of three shapes:
Per-user authentication on a database connector requires an Enterprise license. See Authentication.

Connect in Bag of words

Go to Data Sources → Add data source → Microsoft SQL Server.
additional_params cannot weaken the connection. Security-relevant keywords are owned by Bag of words and any attempt to set them here is silently ignored: Driver, Server, Database, UID, PWD, Encrypt, TrustServerCertificate, Trusted_Connection, Authentication, Integrated Security, and APP. Use it for behavioral hints like read-intent routing, not to change how the connection authenticates or encrypts.
Under either Kerberos mode the ODBC driver derives the target service principal name as MSSQLSvc/<host>:<port> from what you type in host, and this cannot be overridden. Connect by the exact FQDN the SPN is registered for — an IP address or an unregistered CNAME produces Cannot generate SSPI context.

Option A — SQL login (userpass)

The default. Nothing to configure outside the product. This mode can be used as one shared credential for the whole workspace, or per-user, where each person saves their own SQL login. Grant the login read-only rights — db_datareader on the target database, or explicit GRANT SELECT on the approved schemas.

Option B — Kerberos (Windows Integrated)

All queries authenticate as one Active Directory service account. Bag of words still enforces its own access control on top; SQL Server sees a single Windows login. This mode requires setup by both your AD/DBA team and whoever operates the Bag of words host.

Before you start

  • An AD service account for the app, for example [email protected], with AES key types enabled (“This account supports Kerberos AES 128/256 bit encryption”).
  • SQL Server’s own SPN registered — setspn -L <sql service account> should list MSSQLSvc/<fqdn>:1433. This is usually automatic.
  • The ability to mount files and set environment variables on the Bag of words host.
  • NTP or chrony running on the host. Kerberos fails above 5 minutes of clock skew.

Step 1 — Create the keytab (AD team)

On a domain controller or admin workstation:

Step 2 — Create the SQL Server login (DBA)

Bag of words only ever issues SELECT, so read-only rights are sufficient.

Step 3 — Configure Kerberos on the Bag of words host

The Docker image already ships krb5-user, libgssapi-krb5-2, and msodbcsql18. You mount two files and set one environment variable.
A minimal /etc/krb5.conf:
Keep forwardable = true. It is required for per-user SSO (Option C), and harmless otherwise.
Smoke-test from inside the container before touching the app:

Step 4 — Configure the connection

Create or edit the SQL Server connection and pick Kerberos (Windows Integrated) as the authentication method. Verify from SQL Server that the connection really is Kerberos:

Option C — Kerberos SSO (per-user delegation)

With per-user SSO, queries run as the signed-in user’s AD identity. No password or token is collected from the user. Bag of words performs protocol transition (S4U2Self — “issue me a ticket for user X to myself”, which needs only the user’s UPN) and constrained delegation (S4U2Proxy — exchange that ticket for one to the SQL Server SPN). SQL-side permissions, row-level security, and auditing all resolve per user. This builds on top of Option B: the service-account Kerberos setup must already be working, because the service identity is still used for schema indexing.

Additional AD prerequisites

Delegation is configured on the app’s service account. This is the part your AD team has to approve.
1

Give the service account its own SPN

The KDC only issues an S4U2Self evidence ticket to an account that is itself a service — that is, one that has an SPN.
2

Enable constrained delegation with protocol transition

Classic KCD (single domain) — in Active Directory Users and Computers → svc-bow → the Delegation tab:
  1. Select “Trust this user for delegation to specified services only”.
  2. Select “Use any authentication protocol”.
  3. Add the SQL Server’s MSSQLSvc/<fqdn>:1433 SPN(s) to the allowed list (this writes msDS-AllowedToDelegateTo).
“Use any authentication protocol” is required. With “Kerberos only” selected, delegation fails with KDC_ERR_BADOPTION — protocol transition is exactly what that setting disables.
Or resource-based constrained delegation, which works across domains. On the SQL Server’s service account:
3

Create SQL Server logins for the end users

Per user or, more practically, per AD group:
The SQL Server host must be domain-joined (SSSD or winbind) so it can resolve AD users to SIDs. Verify with id DOMAIN\user before creating logins.
4

Check for accounts that cannot be delegated

Members of Protected Users, and accounts flagged “Account is sensitive and cannot be delegated”, cannot be impersonated at all. Those people need a personal SQL login (Option A) instead.
Smoke-test the whole AD chain from the container before enabling anything in the app:
If kvno succeeds, delegation is correctly configured.

Configure the connection

1

Confirm the image has the Kerberos extra

Per-user delegation needs the gssapi Python bindings. The default Dockerfile installs them (uv sync --extra kerberos). Service-account Kerberos (Option B) does not need them — the ODBC driver talks to libgssapi directly — so a build without the extra will pass Option B and fail here.
2

Set up the connection with Kerberos system auth

Follow Option B first. The system identity is still what indexes the schema.
3

Enable Require user authentication

On a Kerberos system-auth connection this defaults the allowed per-user modes to Kerberos SSO, so per-user delegation becomes automatic with no action from users — nobody has to click Connect or enter anything.
The per-user mode’s fields: The UPN is taken from the user’s Bag of words login identity — Entra ID / OIDC preferred_username or upn, LDAP, or the local email address. If someone’s email is not their AD UPN, they can save an explicit principal in kerberos_impersonate under the data source’s user credentials.

Optional environment variables

Operational notes

  • Ticket renewal is automatic. Delegated tickets are cached per user and re-acquired from the keytab as they near expiry. There is nothing to schedule.
  • Indexing always runs as the service account, since schema refresh has no user in context.
  • KRB5CCNAME is process-global on Linux, so the credential-cache switch is serialized around the driver’s connect handshake. Concurrent connects by different users queue for milliseconds; established connections are unaffected.
  • Under integrated auth every user’s ODBC connection string would otherwise be identical, since the identity comes from the credential cache rather than the string — which would let a shared pool hand user B a connection authenticated as user A. Bag of words binds a per-identity APP=BagOfWords-<principal> token into the string so each impersonated user gets its own pool bucket. Leaving unixODBC pooling off is still worth doing as defence in depth.
  • If your SQL Server is 2022 or newer and Azure Arc-enabled, Entra token authentication is an alternative to constrained delegation and may be easier to get approved than AD delegation changes.

Troubleshooting