<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Is it safe to expose JWT in Databricks Job? in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/is-it-safe-to-expose-jwt-in-databricks-job/m-p/165230#M55402</link>
    <description>&lt;P&gt;Hello !&lt;/P&gt;&lt;P&gt;What I can say is that your conclusion is correct since DBKS&amp;nbsp;does not currently expose the identity of the principal that called run-now to the running job through the Jobs API or notebook context and the audit event is the authoritative source but it is not designed for synchronous runtime identity resolution.&lt;/P&gt;&lt;P&gt;I would not pass the Databricks/Entra OAuth JWT access token itself as a job parameter.&lt;/P&gt;&lt;P&gt;DBKS explicitly shows resolved parameters on the job run details page. &lt;A title="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" href="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" target="_self"&gt;https://docs.databricks.com/aws/en/jobs/dynamic-value-references&lt;/A&gt;&amp;nbsp;more importantly the runNow audit event includes job_parameters, notebook_params, python_params...&amp;nbsp;in its request params and you can check this doc link to better understand the situation&amp;nbsp;&lt;A title="https://docs.databricks.com/aws/en/admin/account-settings/audit-logs" href="https://docs.databricks.com/aws/en/admin/account-settings/audit-logs" target="_self"&gt;https://docs.databricks.com/aws/en/admin/account-settings/audit-logs&lt;/A&gt;)&lt;/P&gt;&lt;P&gt;which means something like:&lt;/P&gt;&lt;PRE&gt;{
  "job_id": 123,
  "job_parameters": {
    "jwt": "eyJhbGciOi..."
  }
}&lt;/PRE&gt;&lt;P&gt;can potentially make a bearer credential persist in places where you don't want credentials to exist like in job run metadata, audit records, logs or parameter inspection.&lt;/P&gt;&lt;P&gt;So what you need to do is simply treat tokens as secrets and avoid putting credentials directly into notebooks or jobs or logging them.&lt;/P&gt;&lt;P&gt;If that JWT is the token SPN B used to call:&lt;/P&gt;&lt;PRE&gt;POST /api/2.2/jobs/run-now
Authorization: Bearer &amp;lt;token&amp;gt;&lt;/PRE&gt;&lt;P&gt;then anybody obtaining it before expiration could potentially replay it with the permissions of SPN B.&lt;/P&gt;&lt;P&gt;Interestingly, what I really find amazing is that&amp;nbsp;does know the caller since the jobs&amp;nbsp;audit event represents an on demand invocation and every audit record has:&lt;/P&gt;&lt;PRE&gt;user_identity&lt;/PRE&gt;&lt;P&gt;which DBKS defines as the identity of the user initiating the request.&amp;nbsp;&lt;/P&gt;&lt;P&gt;The problem is that DBKS does not propagate that audit user_identity into the job runtime and the documented dynamic values provide job.id, job.run_id, job.trigger.type, timestamps... but no triggered_by/caller identity&amp;nbsp;&lt;A href="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" target="_blank"&gt;https://docs.databricks.com/aws/en/jobs/dynamic-value-references&lt;/A&gt;&lt;/P&gt;&lt;P&gt;and unfortunately the system tables are explicitly not intended for realtime monitoring because in DBKS&amp;nbsp;recent events may not appear immediately and Azure diagnostic log delivery isn't a reliable workaround either (auditable events typically arrive within about 15 minutes)&lt;/P&gt;&lt;P&gt;What I would recommend is if the caller identity is required inside the job immediately you can&amp;nbsp;use a purpose built signed identity assertion&amp;nbsp;rather than forwarding the OAuth access token.&lt;/P&gt;&lt;P&gt;for example SPN B (or preferably a trusted issuer) sends:&lt;/P&gt;&lt;PRE&gt;{
  "caller_assertion": "&amp;lt;signed-JWT&amp;gt;",
  "request_id": "8d6835..."
}&lt;/PRE&gt;&lt;P&gt;with claims such as:&lt;/P&gt;&lt;PRE&gt;{
  "sub": "SPN-B-application-id",
  "aud": "databricks-job-123",
  "iat": 1786352400,
  "exp": 1786352700,
  "jti": "8d6835..."
}&lt;/PRE&gt;&lt;P&gt;the job verifies:&lt;/P&gt;&lt;PRE&gt;signature
aud == expected job
exp &amp;lt; = 5 minutes
jti not previously used
issuer is trusted&lt;/PRE&gt;&lt;P&gt;so a JWT as a format is not inherently the problem. Passing a bearer/access JWT is.&lt;/P&gt;&lt;P&gt;For a prod security sensitive use case, I would go for :&lt;/P&gt;&lt;PRE&gt;SPN B
  │
  │ authenticated request
  ▼
thin trigger service or DBKS app
  │
  ├── validates caller = SPN B
  │
  ├── generates request_id
  │
  ├── creates short-lived signed assertion
  │
  ▼
DBKS run-now
  │
  │ caller_assertion + request_id
  ▼
Job running as SPN A
  │
  ├── verifies assertion
  └── knows caller = SPN B&lt;/PRE&gt;&lt;P&gt;this proxy does not need to be a large additional system since it can be a very thin authenticated endpoint whose only responsibility is identity propagation. A DBKS app is also worth considering because DBKS apps support OAuth for users or SP and explicitly recommend recording the original identity when performing actions on behalf of callers so if immediate caller identification is not required for authorization and is needed only for auditing or reporting, I would avoid all of this complexity and continue using:&lt;/P&gt;&lt;PRE&gt;SELECT
    event_time,
    user_identity,
    request_params['job_id'] AS job_id
FROM system.access.audit
WHERE service_name = 'jobs'
  AND action_name = 'runNow'&lt;/PRE&gt;&lt;P&gt;the audit table is actually the correct source of truth user_identity is the initiating identity while run_as is the execution identity.&lt;/P&gt;</description>
    <pubDate>Mon, 10 Aug 2026 09:45:32 GMT</pubDate>
    <dc:creator>amirabedhiafi</dc:creator>
    <dc:date>2026-08-10T09:45:32Z</dc:date>
    <item>
      <title>Is it safe to expose JWT in Databricks Job?</title>
      <link>https://community.databricks.com/t5/data-engineering/is-it-safe-to-expose-jwt-in-databricks-job/m-p/165141#M55399</link>
      <description>&lt;P&gt;There is an usecase where I want to verify/extract the job caller identity in the job runtime of databricks. The job run_as and creator parameter seems to be fixed at the job configuration and doesn't reflect/update who actually triggered a job run.&lt;/P&gt;&lt;P&gt;Approaches tried till now:&amp;nbsp;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;&lt;STRONG&gt;Notebook Context – dbutils.notebook.entry_point.getDbutils().notebook().getContext() - userName().get()&lt;/STRONG&gt; → Returns the job owner identity (the user/SP that created the job), NOT the SP that called run-now.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Jobs API – GET /api/2.1/jobs/runs/get and /api/2.2/jobs/runs/get creator_user_name&lt;/STRONG&gt; → Returns the job owner/creator, not the run trigger. I verified this by triggering a job owned by SPN A using a different SPN B. The creator_user_name remained SPN A in both cases. No trigger_info, triggered_by, submitter, initiator, or similar field exists in the response. Result: Triggering SP identity is NOT available via the Jobs API.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Audit tables from system.access.audit&lt;/STRONG&gt; does return job caller details but there is a big delay(10mins+) for audit table to populate the job runs.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;So I am thinking to pass the jwt in the job itself and then&amp;nbsp; verify this jwt for the job caller identity with the valid signature. Any better way to actually identify who has triggered the databricks job? If passing&amp;nbsp; jwt token is a no-go, only option left is a proxy service in between the databricks jobs and the clients just for this user identification usecase which is another system overhead.&lt;/P&gt;</description>
      <pubDate>Sat, 08 Aug 2026 12:50:39 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/is-it-safe-to-expose-jwt-in-databricks-job/m-p/165141#M55399</guid>
      <dc:creator>ayushpattnaik</dc:creator>
      <dc:date>2026-08-08T12:50:39Z</dc:date>
    </item>
    <item>
      <title>Re: Is it safe to expose JWT in Databricks Job?</title>
      <link>https://community.databricks.com/t5/data-engineering/is-it-safe-to-expose-jwt-in-databricks-job/m-p/165230#M55402</link>
      <description>&lt;P&gt;Hello !&lt;/P&gt;&lt;P&gt;What I can say is that your conclusion is correct since DBKS&amp;nbsp;does not currently expose the identity of the principal that called run-now to the running job through the Jobs API or notebook context and the audit event is the authoritative source but it is not designed for synchronous runtime identity resolution.&lt;/P&gt;&lt;P&gt;I would not pass the Databricks/Entra OAuth JWT access token itself as a job parameter.&lt;/P&gt;&lt;P&gt;DBKS explicitly shows resolved parameters on the job run details page. &lt;A title="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" href="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" target="_self"&gt;https://docs.databricks.com/aws/en/jobs/dynamic-value-references&lt;/A&gt;&amp;nbsp;more importantly the runNow audit event includes job_parameters, notebook_params, python_params...&amp;nbsp;in its request params and you can check this doc link to better understand the situation&amp;nbsp;&lt;A title="https://docs.databricks.com/aws/en/admin/account-settings/audit-logs" href="https://docs.databricks.com/aws/en/admin/account-settings/audit-logs" target="_self"&gt;https://docs.databricks.com/aws/en/admin/account-settings/audit-logs&lt;/A&gt;)&lt;/P&gt;&lt;P&gt;which means something like:&lt;/P&gt;&lt;PRE&gt;{
  "job_id": 123,
  "job_parameters": {
    "jwt": "eyJhbGciOi..."
  }
}&lt;/PRE&gt;&lt;P&gt;can potentially make a bearer credential persist in places where you don't want credentials to exist like in job run metadata, audit records, logs or parameter inspection.&lt;/P&gt;&lt;P&gt;So what you need to do is simply treat tokens as secrets and avoid putting credentials directly into notebooks or jobs or logging them.&lt;/P&gt;&lt;P&gt;If that JWT is the token SPN B used to call:&lt;/P&gt;&lt;PRE&gt;POST /api/2.2/jobs/run-now
Authorization: Bearer &amp;lt;token&amp;gt;&lt;/PRE&gt;&lt;P&gt;then anybody obtaining it before expiration could potentially replay it with the permissions of SPN B.&lt;/P&gt;&lt;P&gt;Interestingly, what I really find amazing is that&amp;nbsp;does know the caller since the jobs&amp;nbsp;audit event represents an on demand invocation and every audit record has:&lt;/P&gt;&lt;PRE&gt;user_identity&lt;/PRE&gt;&lt;P&gt;which DBKS defines as the identity of the user initiating the request.&amp;nbsp;&lt;/P&gt;&lt;P&gt;The problem is that DBKS does not propagate that audit user_identity into the job runtime and the documented dynamic values provide job.id, job.run_id, job.trigger.type, timestamps... but no triggered_by/caller identity&amp;nbsp;&lt;A href="https://docs.databricks.com/aws/en/jobs/dynamic-value-references" target="_blank"&gt;https://docs.databricks.com/aws/en/jobs/dynamic-value-references&lt;/A&gt;&lt;/P&gt;&lt;P&gt;and unfortunately the system tables are explicitly not intended for realtime monitoring because in DBKS&amp;nbsp;recent events may not appear immediately and Azure diagnostic log delivery isn't a reliable workaround either (auditable events typically arrive within about 15 minutes)&lt;/P&gt;&lt;P&gt;What I would recommend is if the caller identity is required inside the job immediately you can&amp;nbsp;use a purpose built signed identity assertion&amp;nbsp;rather than forwarding the OAuth access token.&lt;/P&gt;&lt;P&gt;for example SPN B (or preferably a trusted issuer) sends:&lt;/P&gt;&lt;PRE&gt;{
  "caller_assertion": "&amp;lt;signed-JWT&amp;gt;",
  "request_id": "8d6835..."
}&lt;/PRE&gt;&lt;P&gt;with claims such as:&lt;/P&gt;&lt;PRE&gt;{
  "sub": "SPN-B-application-id",
  "aud": "databricks-job-123",
  "iat": 1786352400,
  "exp": 1786352700,
  "jti": "8d6835..."
}&lt;/PRE&gt;&lt;P&gt;the job verifies:&lt;/P&gt;&lt;PRE&gt;signature
aud == expected job
exp &amp;lt; = 5 minutes
jti not previously used
issuer is trusted&lt;/PRE&gt;&lt;P&gt;so a JWT as a format is not inherently the problem. Passing a bearer/access JWT is.&lt;/P&gt;&lt;P&gt;For a prod security sensitive use case, I would go for :&lt;/P&gt;&lt;PRE&gt;SPN B
  │
  │ authenticated request
  ▼
thin trigger service or DBKS app
  │
  ├── validates caller = SPN B
  │
  ├── generates request_id
  │
  ├── creates short-lived signed assertion
  │
  ▼
DBKS run-now
  │
  │ caller_assertion + request_id
  ▼
Job running as SPN A
  │
  ├── verifies assertion
  └── knows caller = SPN B&lt;/PRE&gt;&lt;P&gt;this proxy does not need to be a large additional system since it can be a very thin authenticated endpoint whose only responsibility is identity propagation. A DBKS app is also worth considering because DBKS apps support OAuth for users or SP and explicitly recommend recording the original identity when performing actions on behalf of callers so if immediate caller identification is not required for authorization and is needed only for auditing or reporting, I would avoid all of this complexity and continue using:&lt;/P&gt;&lt;PRE&gt;SELECT
    event_time,
    user_identity,
    request_params['job_id'] AS job_id
FROM system.access.audit
WHERE service_name = 'jobs'
  AND action_name = 'runNow'&lt;/PRE&gt;&lt;P&gt;the audit table is actually the correct source of truth user_identity is the initiating identity while run_as is the execution identity.&lt;/P&gt;</description>
      <pubDate>Mon, 10 Aug 2026 09:45:32 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/is-it-safe-to-expose-jwt-in-databricks-job/m-p/165230#M55402</guid>
      <dc:creator>amirabedhiafi</dc:creator>
      <dc:date>2026-08-10T09:45:32Z</dc:date>
    </item>
  </channel>
</rss>

