{"id":20511295,"url":"https://github.com/intility/off_broadway_defender365","last_synced_at":"2025-04-13T22:42:07.343Z","repository":{"id":62204603,"uuid":"558738790","full_name":"intility/off_broadway_defender365","owner":"intility","description":"Broadway producer for Microsoft 365 Defender Incident API","archived":false,"fork":false,"pushed_at":"2024-08-26T11:09:19.000Z","size":77,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-27T13:01:53.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/intility.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-28T07:25:23.000Z","updated_at":"2024-09-27T16:34:50.000Z","dependencies_parsed_at":"2023-12-06T13:30:58.671Z","dependency_job_id":"8882a077-d862-4aa9-ad28-7cc16e679b9c","html_url":"https://github.com/intility/off_broadway_defender365","commit_stats":{"total_commits":29,"total_committers":1,"mean_commits":29.0,"dds":0.0,"last_synced_commit":"1f97caf2af66914a2dddc18324619b7abba3499d"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intility%2Foff_broadway_defender365","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intility%2Foff_broadway_defender365/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intility%2Foff_broadway_defender365/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intility%2Foff_broadway_defender365/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/intility","download_url":"https://codeload.github.com/intility/off_broadway_defender365/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248794565,"owners_count":21162613,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T20:35:26.966Z","updated_at":"2025-04-13T22:42:07.306Z","avatar_url":"https://github.com/intility.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OffBroadway.Defender365\n\n![pipeline status](https://github.com/Intility/off_broadway_defender365/actions/workflows/elixir.yaml/badge.svg?event=push)\n\n[Broadway](https://github.com/dashbitco/broadway) producer acts as a consumer for incidents reported by the\n[Microsoft 365 Defender](https://www.microsoft.com/en-us/security/business/siem-and-xdr/microsoft-365-defender) APIs.\n\nRead the full documentation [here](https://hexdocs.pm/off_broadway_defender365/readme.html).\n\n## Installation\n\nThis package is [available in Hex](https://hex.pm/packages/off_broadway_defender365), and can be installed\nby adding `off_broadway_defender365` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:off_broadway_defender365, \"~\u003e 1.0.0\"}\n  ]\nend\n```\n\n## Usage\n\nThe `OffBroadway.Defender365.IncidentClient` tries to read the following configuration from `config.exs`.\n\n```elixir\n# config.exs\n\nconfig :off_broadway_defender365, :incident_client,\n  base_url: System.get_env(\"365DEFENDER_BASE_URL\", \"https://api.security.microsoft.com\"),\n  tenant_id: System.get_env(\"365DEFENDER_TENANT_ID\", \"your-tenant-id-here\"),\n  client_id: System.get_env(\"365DEFENDER_CLIENT_ID\", \"your-client-id-here\"),\n  client_secret: System.get_env(\"365DEFENDER_CLIENT_SECRET\", \"your-client-secret-here\")\n```\n\nOptions for the `OffBroadway.Defender365.IncidentClient` can be configured either in `config.exs` or passed as\noptions directly to the `OffBroadway.Defender365.Producer` module. Options are merged, with the passed options\ntaking precedence over those configured in `config.exs`.\n\n```elixir\n# my_broadway.ex\n\ndefmodule MyBroadway do\n  use Broadway\n\n  alias Broadway.Message\n\n  def start_link(_opts) do\n    Broadway.start_link(__MODULE__,\n      name: __MODULE__,\n      producer: [\n        module:\n          {OffBroadway.Defender365.Producer,\n           config: [\n             client_id: \"your-client-id-here\",\n             client_secret: \"your-client-secret-here\",\n           ]}\n      ],\n      processors: [\n        default: []\n      ],\n      batchers: [\n        default: [\n          batch_size: 500,\n          batch_timeout: 5000\n        ]\n      ]\n    )\n  end\n\n  ...callbacks...\nend\n```\n\n### Processing messages\n\nIn order to process incoming messages, we need to implement some callback functions.\n\n```elixir\ndefmodule MyBroadway do\n  use Broadway\n\n  alias Broadway.Message\n\n  ...start_link...\n\n  @impl true\n  def handle_message(_, %Message{data: data} ,_) do\n    message\n    |\u003e Message.update_data(fn -\u003e ...whatever... end)\n  end\n\n  @impl true\n  def handle_batch(_batcher, messages, _batch_info, _context) do\n    IO.puts(\"Received a batch of #{length(messages)} messages!\")\n    messages\n  end\nend\n```\n\nFor the sake of the example, we're not really doing anything here. Whenever we're receiving a batch of messages, we just prints out a\nmessage saying \"Received a batch of messages!\", and for each message we run `Message.update_data/2` passing a function that can\nprocess that message ie. by doing some calculations on the data or something else.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintility%2Foff_broadway_defender365","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fintility%2Foff_broadway_defender365","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintility%2Foff_broadway_defender365/lists"}