-
Notifications
You must be signed in to change notification settings - Fork 515
feat(o365): add support for configurable oauth2 endpoint params #14924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(o365): add support for configurable oauth2 endpoint params #14924
Conversation
Added configurable `oauth_endpoint_params` for greater flexibility. An example use case is to allow overriding the default grant_type to support using providing a static refresh_token.
bc71970 to
5517605
Compare
🚀 Benchmarks reportTo see the full report comment with |
efd6
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit and query, otherwise LGTM
| # Refresh token to get access token: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#refresh-the-access-token | ||
| - path: /test-cel-tenant-id/oauth2/v2.0/token | ||
| methods: [ POST ] | ||
| query_params: | ||
| scope: 'https://manage.office.com/.default' | ||
| refresh_token: refresh_token_123 | ||
| grant_type: refresh_token | ||
| request_headers: | ||
| Authorization: | ||
| - "Basic dGVzdC1jZWwtY2xpZW50LWlkOnRlc3QtY2VsLWNsaWVudC1zZWNyZXQ=" | ||
| Content-Type: | ||
| - "application/x-www-form-urlencoded" | ||
| responses: | ||
| - status_code: 200 | ||
| headers: | ||
| Content-Type: | ||
| - "application/json" | ||
| body: |- | ||
| {{ minify_json ` | ||
| { | ||
| "access_token": "CELtoken", | ||
| "token_type": "Bearer", | ||
| "expires_in": 2, | ||
| "scope": "https%3A%2F%2Fgraph.microsoft.com%2Fmail.read", | ||
| "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...", | ||
| "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..." | ||
| } | ||
| ` }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this down below the default /test-cel-tenant-id/oauth2/v2.0/token rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When order matters we have the more general cases later, out of necessity.
Here order doesn't matter for matching. I think it makes sense have this new one at the top with the other odd case (the o365audit input) then have the main cases together underneath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw Chris's comments after I addressed Dan's first round of comments. Will leave this as it is.
| default: | | ||
| grant_type: client_credentials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this get picked up on upgrade?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the upgrade works well.
When I added a policy for the old version, then upgraded the package, the policy was unchanged.
Then upgrading the policy did pick up the new setting and default value and generated the same endpoint_params settings.
Diff from before policy upgrade to after policy upgrade:
--- elastic-agent.yml 2025-08-14 15:41:19.496659216 +0200
+++ elastic-agent(1).yml 2025-08-14 15:42:11.519298684 +0200
@@ -1,22 +1,22 @@
id: elastic-agent-managed-ep
-revision: 2
+revision: 3
outputs:
default:
type: elasticsearch
hosts:
- 'https://elasticsearch:9200'
ssl.ca_trusted_fingerprint: 1055FA6AFC9C3459CAC7B743130935B3B96D04019D291F833B2C9A44934F5EF1
preset: latency
fleet:
hosts:
- 'https://fleet-server:8220'
output_permissions:
default:
_elastic_agent_monitoring:
indices: []
_elastic_agent_checks:
cluster:
- monitor
0e4eb51a-bf09-4f59-8336-bb7acf268a97:
indices:
- names:
@@ -24,47 +24,47 @@
privileges:
- auto_configure
- create_doc
agent:
download:
sourceURI: 'https://artifacts.elastic.co/downloads/'
monitoring:
enabled: false
logs: false
metrics: false
traces: false
features: {}
protection:
enabled: false
uninstall_token_hash: GN9RlDrrdlgGuTzSIKwi4Tb1dPPl8q7MuKh34xdgeVo=
signing_key: >-
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpJjCJPBpxIXkk5txcGxVJ4JPguzHOGTnnjd8+Ts/ntxhWUaeOrrH/BkQ7CjytKjcDACT6V1+HQ8CpONpCn3KMA==
inputs:
- id: cel-o365-0e4eb51a-bf09-4f59-8336-bb7acf268a97
name: o365-1
- revision: 1
+ revision: 2
type: cel
use_output: default
meta:
package:
name: o365
- version: 2.21.1
+ version: 2.22.0
data_stream:
namespace: default
package_policy_id: 0e4eb51a-bf09-4f59-8336-bb7acf268a97
streams:
- id: cel-o365.audit-0e4eb51a-bf09-4f59-8336-bb7acf268a97
data_stream:
dataset: o365.audit
type: logs
interval: 3m
auth.oauth2:
client.id: testclientid
client.secret: '${SECRET_0}'
provider: azure
scopes:
- 'https://manage.office.com/.default'
endpoint_params:
grant_type: client_credentials
token_url: 'https://token.example.com/testtenantid/oauth2/v2.0/token'
resource.url: 'https://manage.office.com'
resource.timeout: 60s
@@ -77,26 +77,26 @@
want_more: false
base:
tenant_id: testtenantid
list_contents_start_time: 1h
batch_interval: 1h
maximum_age: 167h55m
content_types: >-
Audit.AzureActiveDirectory, Audit.Exchange, Audit.SharePoint,
Audit.General, DLP.All
redact:
fields:
- base.tenant_id
program: "state.base.content_types.split(\",\").map(content_type_raw,\n\tcontent_type_raw.trim_space()\n).map(content_type,\n\trequest(\n\t\t\"POST\",\n\t\tstate.url.trim_right(\"/\") + \"/api/v1.0/\" + state.base.tenant_id + \"/activity/feed/subscriptions/start?\" +\n\t\t{\n\t\t\t\"contentType\": [content_type],\n\t\t\t\"PublisherIdentifier\": [state.base.tenant_id],\n\t\t}.format_query()\n\t).do_request().as(start_subs_resp,\n\t\tstart_subs_resp.Body.decode_json().as(start_subs_resp_body,\n\t\t\t(\n\t\t\t\thas(start_subs_resp_body.status) && start_subs_resp_body.status == \"enabled\" ||\n\t\t\t\thas(start_subs_resp_body.error) && has(start_subs_resp_body.error.code) &&\n\t\t\t\tstart_subs_resp_body.error.code == \"AF20024\"\n\t\t\t) ?\n\t\t\t\t// When start-subscription API returns success or if already started subscription,\n\t\t\t\tduration(state.base.batch_interval).as(batch_interval,\n\t\t\t\t\tmin(duration(\"24h\"), batch_interval).as(batch_interval,\n\t\t\t\t\t\trequest(\n\t\t\t\t\t\t\t\"GET\",\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tstate.want_more && has(state.?cursor.content_types_state_as_list) &&\n\t\t\t\t\t\t\t\tsize(state.cursor.content_types_state_as_list.filter(e, e.content_type == content_type)) > 0 &&\n\t\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e, e.content_type == content_type)[0].next_page != \"\"\n\t\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t\t// if NextPageUri exists\n\t\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e, e.content_type == content_type)[0].next_page\n\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\thas(state.?cursor.content_types_state_as_list) &&\n\t\t\t\t\t\t\t\tsize(state.cursor.content_types_state_as_list.filter(e, e.content_type == content_type)) > 0\n\t\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t\t// if NextPageUri does not exist, but content_type_state_created_at exists in state\n\t\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e, e.content_type == content_type).as(content_type_state,\n\t\t\t\t\t\t\t\t\tcontent_type_state[0].content_created_at.as(content_type_state_created_at,\n\t\t\t\t\t\t\t\t\t\t// if saved time inside state is more than 7 days old, then change it to 7 days.\n\t\t\t\t\t\t\t\t\t\tmax(\n // Enforce the maximum age limit.\n\t\t\t\t\t\t\t\t\t\t\tnow() - duration(state.base.maximum_age),\n\t\t\t\t\t\t\t\t\t\t\tcontent_type_state_created_at.parse_time(time_layout.RFC3339)\n\t\t\t\t\t\t\t\t\t\t).as(state_created_at_calc,\n\t\t\t\t\t\t\t\t\t\t\tstate.url.trim_right(\"/\") + \"/api/v1.0/\" + state.base.tenant_id + \"/activity/feed/subscriptions/content?\" +\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"contentType\": [content_type],\n\t\t\t\t\t\t\t\t\t\t\t\t\"PublisherIdentifier\": [state.base.tenant_id],\n\t\t\t\t\t\t\t\t\t\t\t\t\"startTime\": [string(min(now() - duration(\"1s\"), state_created_at_calc + duration(\"1s\")))],\n\t\t\t\t\t\t\t\t\t\t\t\t\"endTime\": [string(min(now(), state_created_at_calc + batch_interval))],\n\t\t\t\t\t\t\t\t\t\t\t}.format_query()\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t// initial run when no cursor state exists i.e., polling from initial_interval\n\t\t\t\t\t\t\t\tstate.url.trim_right(\"/\") + \"/api/v1.0/\" + state.base.tenant_id + \"/activity/feed/subscriptions/content?\" +\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"contentType\": [content_type],\n\t\t\t\t\t\t\t\t\t\"PublisherIdentifier\": [state.base.tenant_id],\n\t\t\t\t\t\t\t\t\t\"startTime\": [string(min(now() - duration(\"1s\"), now() - duration(state.base.list_contents_start_time)))],\n\t\t\t\t\t\t\t\t\t\"endTime\": [string(min(now(), now() - duration(state.base.list_contents_start_time) + batch_interval))],\n\t\t\t\t\t\t\t\t}.format_query()\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t).do_request().as(list_contents_resp,\n\t\t\t\t\tlist_contents_resp.Body.decode_json().as(list_contents_resp_body,\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\ttype(list_contents_resp_body) != map && size(list_contents_resp_body) > 0 &&\n\t\t\t\t\t\t\thas(list_contents_resp_body[0].contentUri) && list_contents_resp_body[0].contentUri != \"\" &&\n\t\t\t\t\t\t\thas(list_contents_resp_body[0].contentCreated) && list_contents_resp_body[0].contentCreated != \"\"\n\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t// contents exist to consume\n\t\t\t\t\t\t\tlist_contents_resp_body.map(l1,\n\t\t\t\t\t\t\t\t(has(l1.contentExpiration) && l1.contentExpiration.parse_time(time_layout.RFC3339) >= now()) ?\n\t\t\t\t\t\t\t\t\trequest(\"GET\", l1.contentUri).do_request().as(content_resp,\n\t\t\t\t\t\t\t\t\t\t(has(content_resp.StatusCode) && content_resp.StatusCode == 200 && size(content_resp.Body) > 0) ?\n\t\t\t\t\t\t\t\t\t\t\tcontent_resp.Body.decode_json().map(content_resp_body,\n\t\t\t\t\t\t\t\t\t\t\t\tcontent_resp_body.with({\"copy\": {\"o365audit\": content_resp_body}})\n\t\t\t\t\t\t\t\t\t\t\t).map(content_resp_body_with_copy,\n\t\t\t\t\t\t\t\t\t\t\t\tcontent_resp_body_with_copy.copy\n\t\t\t\t\t\t\t\t\t\t\t).flatten().drop_empty().as(contents,\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"events_per_content_type\": contents,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"content_type\": content_type,\n\t\t\t\t\t\t\t\t\t\t\t\t\t// if 'contentCreated' is older than the maximum age, change it to the maximum age.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"content_created_at\": {\"temp\": list_contents_resp_body}.collate(\"temp.contentCreated\").max().as(temp_max,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(temp_max.parse_time(time_layout.RFC3339) > now() - duration(state.base.maximum_age)) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttemp_max\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(now() - duration(state.base.maximum_age)).format(time_layout.RFC3339)\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"next_page\": (has(list_contents_resp.?Header.NextPageUri) && list_contents_resp.Header.NextPageUri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.NextPageUri[0])\n\t\t\t\t\t\t\t\t\t\t\t\t\t: (has(list_contents_resp.?Header.Nextpageuri) && list_contents_resp.Header.Nextpageuri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.Nextpageuri[0])\n\t\t\t\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t// keep fetching more if (nextpageuri exists) or\n\t\t\t\t\t\t\t\t\t\t\t\t\t// (the end of the request range is one batch interval or longer before the current time)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"want_more_content\": has(list_contents_resp.Header) &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thas(list_contents_resp.Header.NextPageUri) && list_contents_resp.Header.NextPageUri.size() > 0 ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thas(list_contents_resp.Header.Nextpageuri) && list_contents_resp.Header.Nextpageuri.size() > 0 ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tlist_contents_resp.Request.URL.parse_url().RawQuery.parse_query().?endTime[0].optMap(endTime,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (now() - endTime.parse_time(time_layout.RFC3339)) >= duration(state.base.batch_interval)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t).orValue(false)\n\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\"events_per_content_type\": [],\n\t\t\t\t\t\t\t\t\t\t\t\t\"content_type\": content_type,\n\t\t\t\t\t\t\t\t\t\t\t\t\"content_created_at\": {\"temp\": list_contents_resp_body}.collate(\"temp.contentCreated\").max().as(temp_max,\n\t\t\t\t\t\t\t\t\t\t\t\t\t(temp_max.parse_time(time_layout.RFC3339) > now() - duration(state.base.maximum_age)) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttemp_max\n\t\t\t\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(now() - duration(state.base.maximum_age)).format(time_layout.RFC3339)\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\"next_page\": (has(list_contents_resp.?Header.NextPageUri) && list_contents_resp.Header.NextPageUri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.NextPageUri[0])\n\t\t\t\t\t\t\t\t\t\t\t\t: (has(list_contents_resp.?Header.Nextpageuri) && list_contents_resp.Header.Nextpageuri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.Nextpageuri[0])\n\t\t\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"events_per_content_type\": [],\n\t\t\t\t\t\t\t\t\t\t\"content_type\": content_type,\n\t\t\t\t\t\t\t\t\t\t\"content_created_at\": {\"temp\": list_contents_resp_body}.collate(\"temp.contentCreated\").max().as(temp_max,\n\t\t\t\t\t\t\t\t\t\t\t(temp_max.parse_time(time_layout.RFC3339) > now() - duration(state.base.maximum_age)) ?\n\t\t\t\t\t\t\t\t\t\t\t\ttemp_max\n\t\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\t(now() - duration(state.base.maximum_age)).format(time_layout.RFC3339)\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\"next_page\": (has(list_contents_resp.?Header.NextPageUri) && list_contents_resp.Header.NextPageUri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.NextPageUri[0])\n\t\t\t\t\t\t\t\t\t\t: (has(list_contents_resp.?Header.Nextpageuri) && list_contents_resp.Header.Nextpageuri.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t(list_contents_resp.Header.Nextpageuri[0])\n\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\t// contents does not exist, or is empty array\n\t\t\t\t\t\t\tlist_contents_resp.Request.URL.parse_url().RawQuery.parse_query().as(reqQuery,\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"events_per_content_type\": (size(list_contents_resp_body) == 0) ? [] : [list_contents_resp_body],\n\t\t\t\t\t\t\t\t\t\t\"content_type\": content_type,\n\t\t\t\t\t\t\t\t\t\t\"content_created_at\": (\n\t\t\t\t\t\t\t\t\t\t\thas(list_contents_resp.StatusCode) && has(reqQuery.endTime) &&\n\t\t\t\t\t\t\t\t\t\t\tlist_contents_resp.StatusCode == 200 && reqQuery.endTime.size() > 0\n\t\t\t\t\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t\t\t\t\t(reqQuery.endTime[0])\n\t\t\t\t\t\t\t\t\t\t: (has(reqQuery.startTime) && reqQuery.startTime.size() > 0) ?\n\t\t\t\t\t\t\t\t\t\t\t(reqQuery.startTime[0])\n\t\t\t\t\t\t\t\t\t\t: has(\n\t\t\t\t\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e,\n\t\t\t\t\t\t\t\t\t\t\t\te.content_type == content_type\n\t\t\t\t\t\t\t\t\t\t\t)[0].content_created_at\n\t\t\t\t\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e,\n\t\t\t\t\t\t\t\t\t\t\t\te.content_type == content_type\n\t\t\t\t\t\t\t\t\t\t\t)[0].content_created_at\n\t\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\t\tstring(now() - duration(state.base.list_contents_start_time)),\n\t\t\t\t\t\t\t\t\t\t\"next_page\": \"\",\n\t\t\t\t\t\t\t\t\t\t\"want_more_content\": (\n\t\t\t\t\t\t\t\t\t\t\thas(list_contents_resp.StatusCode) && has(reqQuery.endTime) &&\n\t\t\t\t\t\t\t\t\t\t\tlist_contents_resp.StatusCode == 200 && reqQuery.endTime.size() > 0 &&\n\t\t\t\t\t\t\t\t\t\t\treqQuery.endTime[0].parse_time(time_layout.RFC3339).as(endTime,\n\t\t\t\t\t\t\t\t\t\t\t (now() - endTime) >= duration(state.base.batch_interval)\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t:\n\t\t\t\t// When start-subscription API produces error, such as Authentication error.\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\t\"events_per_content_type\": [{\n\t\t\t\t\t\t \"error\": {\n\t\t\t\t\t\t \"code\": string(start_subs_resp.StatusCode),\n\t\t\t\t\t\t \"id\": string(start_subs_resp.Status),\n\t\t\t\t\t\t \"message\": content_type + \": \" + start_subs_resp_body.?error.code.optFlatMap(code,\n\t\t\t\t\t\t start_subs_resp_body.?error.message.optMap(message,\n\t\t\t\t\t\t code + \" \" + message\n\t\t\t\t\t\t )\n\t\t\t\t\t\t ).orValue(start_subs_resp_body)\n\t\t\t\t\t\t }\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"content_type\": content_type,\n\t\t\t\t\t\t\"content_created_at\": (has(state.cursor) && has(state.cursor.content_types_state_as_list)) ?\n\t\t\t\t\t\t\tstate.cursor.content_types_state_as_list.filter(e, e.content_type == content_type)[0].content_created_at\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\tstring(now() - duration(state.base.list_contents_start_time)),\n\t\t\t\t\t\t\"next_page\": \"\",\n\t\t\t\t\t\t\"want_more_content\": false,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t)\n\t)\n).flatten().drop_empty().as(events_list,\n\tevents_list.collate(\"events_per_content_type\").as(events,\n\t events.filter(e, has(e.?error.message)).as(error_events,\n\t error_events.size() > 0 ?\n\t // If there are errors, return a single merged error event and discard any other results\n\t {\n\t \"url\": state.url,\n\t \"base\": state.base,\n\t \"events\": {\n\t \"error\": {\n\t \"code\": error_events.collate(\"error.code\").as(codes, codes.zip(codes)).keys().as(codes, codes.size() == 1 ? codes[0] : dyn(codes)),\n\t \"id\": error_events.collate(\"error.id\").as(ids, ids.zip(ids)).keys().as(ids, ids.size() == 1 ? ids[0] : dyn(ids)),\n\t \"message\": error_events.collate(\"error.message\").join(\"; \"),\n\t },\n\t },\n\t \"want_more\": false,\n\t ?\"cursor\": state.?cursor,\n\t }\n\t :\n\t {\n\t \"url\": state.url,\n\t \"base\": state.base,\n\t \"events\": events,\n\t \"want_more\": events_list.collate(\"want_more_content\").filter(e, e == true).size() > 0,\n\t \"cursor\": {\n\t \"content_types_state_as_list\": events_list.drop([\"events_per_content_type\"]),\n\t },\n\t }\n\t )\n\t)\n)"
tags:
- preserve_original_event
- forwarded
- o365-cel
publisher_pipeline.disable_host: true
signed:
data: >-
- eyJpZCI6ImVsYXN0aWMtYWdlbnQtbWFuYWdlZC1lcCIsImFnZW50Ijp7ImZlYXR1cmVzIjp7fSwicHJvdGVjdGlvbiI6eyJlbmFibGVkIjpmYWxzZSwidW5pbnN0YWxsX3Rva2VuX2hhc2giOiJHTjlSbERycmRsZ0d1VHpTSUt3aTRUYjFkUFBsOHE3TXVLaDM0eGRnZVZvPSIsInNpZ25pbmdfa2V5IjoiTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFcEpqQ0pQQnB4SVhrazV0eGNHeFZKNEpQZ3V6SE9HVG5uamQ4K1RzL250eGhXVWFlT3JySC9Ca1E3Q2p5dEtqY0RBQ1Q2VjErSFE4Q3BPTnBDbjNLTUE9PSJ9fSwiaW5wdXRzIjpbeyJpZCI6ImNlbC1vMzY1LTBlNGViNTFhLWJmMDktNGY1OS04MzM2LWJiN2FjZjI2OGE5NyIsIm5hbWUiOiJvMzY1LTEiLCJyZXZpc2lvbiI6MSwidHlwZSI6ImNlbCJ9XX0=
+ eyJpZCI6ImVsYXN0aWMtYWdlbnQtbWFuYWdlZC1lcCIsImFnZW50Ijp7ImZlYXR1cmVzIjp7fSwicHJvdGVjdGlvbiI6eyJlbmFibGVkIjpmYWxzZSwidW5pbnN0YWxsX3Rva2VuX2hhc2giOiJHTjlSbERycmRsZ0d1VHpTSUt3aTRUYjFkUFBsOHE3TXVLaDM0eGRnZVZvPSIsInNpZ25pbmdfa2V5IjoiTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFcEpqQ0pQQnB4SVhrazV0eGNHeFZKNEpQZ3V6SE9HVG5uamQ4K1RzL250eGhXVWFlT3JySC9Ca1E3Q2p5dEtqY0RBQ1Q2VjErSFE4Q3BPTnBDbjNLTUE9PSJ9fSwiaW5wdXRzIjpbeyJpZCI6ImNlbC1vMzY1LTBlNGViNTFhLWJmMDktNGY1OS04MzM2LWJiN2FjZjI2OGE5NyIsIm5hbWUiOiJvMzY1LTEiLCJyZXZpc2lvbiI6MiwidHlwZSI6ImNlbCJ9XX0=
signature: >-
- MEYCIQClOWUzH0+o4RJRE2G+p7bOqGS8i83VzQtpkTfiol2ScQIhAOteM98FDe4uljczqdF895gmLC1tx3zbIZLPu/kzbmkK
+ MEYCIQDOfHRC6t93mFQWhUQFk+g+3JilN4lGFCfrbWhl3KpwAQIhAIggITS9TqSi1NAEVLhKEYgjc1+YT7HxA12RXMfPbn1q
secret_references:
- id: PyrOqJgBmkat5LOAnC-h
namespaces: []There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I tested a 2.21.0 -> 2.22.0 upgrade. The agent policy received the default value upon upgrade.
chrisberkhout
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This is working in production.
|
Pinging @elastic/security-service-integrations (Team:Security-Service Integrations) |
…oauth2/v2.0/token rule" This reverts commit 6df4cc6. chrisberkhout said: > Here order doesn't matter for matching. I think it makes sense have this > new one at the top with the other odd case (the o365audit input) then > have the main cases together underneath.
💚 Build Succeeded
History
|
|
|
Package o365 - 2.22.0 containing this change is available at https://epr.elastic.co/package/o365/2.22.0/ |
…tic#14924) Added configurable `oauth_endpoint_params` for greater flexibility. An example use case is to allow overriding the default grant_type to support using providing a static refresh_token.
…tic#14924) Added configurable `oauth_endpoint_params` for greater flexibility. An example use case is to allow overriding the default grant_type to support using providing a static refresh_token.




Proposed commit message
Added configurable
oauth_endpoint_paramsfor greater flexibility. Anexample use case is to allow overriding the default grant_type to
support using providing a static refresh_token.
Checklist
changelog.ymlfile.Related issues
Screenshots
Note
The above configuration treats the
refresh_tokenas static configuration. If the server returns a newrefresh_tokenit a response the oauth client will not use it.Request tracer log showing the oauth request.
{ "log.level": "debug", "@timestamp": "2025-08-13T18:42:20.704Z", "message": "HTTP request", "transaction.id": "JLSRFNTSCTDHG-1", "url.original": "http://svc-o365-cel:8080/test-grant-type-refresh-token-client-id/oauth2/v2.0/token", "url.scheme": "http", "url.path": "/test-grant-type-refresh-token-client-id/oauth2/v2.0/token", "url.domain": "svc-o365-cel", "url.port": "8080", "url.query": "", "http.request.method": "POST", "http.request.header": { "Authorization": [ "Basic dGVzdC1jZWwtY2xpZW50LWlkOnRlc3QtY2VsLWNsaWVudC1zZWNyZXQ=" ], "Content-Type": [ "application/x-www-form-urlencoded" ] }, "user_agent.original": "", "http.request.body.content": "grant_type=refresh_token&refresh_token=refresh_token_123&scope=https%3A%2F%2Fmanage.office.com%2F.default", "http.request.body.truncated": false, "http.request.body.bytes": 105, "http.request.mime_type": "application/x-www-form-urlencoded", "ecs.version": "1.6.0" }Agent policy:
Testing locally
o365-2.22.0-rc1.zip(cannot be used because the -rc1 is doesn't match a regex, see [Fleet] Package upload fails for pre-release semantic version (e.g. 2.22.0-rc1) due to regex mismatch kibana#231712)