Skip to content

Initial release of Spycloud - #10608

Merged
kcreddy merged 7 commits into
elastic:mainfrom
VukaHeavyIndustries:spycloud-0.1.0-1
Aug 16, 2024
Merged

kcreddy merged 7 commits into
elastic:mainfrom
VukaHeavyIndustries:spycloud-0.1.0-1

Conversation

@muskan-crest

Copy link
Copy Markdown
Contributor

Proposed commit message

  • Added three data streams - breach_catalog, breach_record and compass.
  • Added data collection logic for all the three data streams.
  • Added the ingest pipeline for all the three data streams.
  • Mapped fields according to the ECS schema and added Fields metadata in the appropriate yml files.
  • Added dashboards and visualizations.
  • Added test for pipeline for all the three data streams.
  • Added system test cases for all the three data streams.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.

How to test this PR locally

  • Clone integrations repo.
  • Install elastic package locally.
  • Start elastic stack using elastic-package.
  • Move to integrations/packages/spycloud directory.
  • Run the following command to run tests.

elastic-package test

Test-verbose.txt

Screenshots

spycloud-1
spycloud-2

@cla-checker-service

cla-checker-service Bot commented Jul 26, 2024 •

Copy link
Copy Markdown

💚 CLA has been signed

@kcreddy kcreddy added Crest Contributions from Crest developement team. New Integration Issue or pull request for creating a new integration package. Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] labels Jul 26, 2024
@elasticmachine

Copy link
Copy Markdown

Pinging @elastic/security-service-integrations (Team:Security-Service Integrations)

@jamiehynds
jamiehynds requested a review from a team July 26, 2024 09:51
Comment thread packages/spycloud/_dev/build/docs/README.md Outdated
Comment thread packages/spycloud/_dev/build/docs/README.md Outdated
Comment thread packages/spycloud/_dev/deploy/docker/files/config.yml Outdated
Comment on lines +23 to +94
request("GET", state.url + "/breach/catalog?since=" + (
!state.?want_more.orValue(false) ?
(
has(state.?cursor.last_published_date) && state.cursor.last_published_date != null ?
string((timestamp(state.cursor.last_published_date) - duration("24h"))).split("T")[0]
:
"1970-01-01"
)
:
(
has(state.?cursor.first_published_date) && state.cursor.first_published_date != null ?
string((timestamp(state.cursor.first_published_date) - duration("24h"))).split("T")[0]
:
""
) + "&cursor=" + state.pagination_token
)).with({
"Header":{
"x-api-key": [state.api_key],
"User-Agent": ["ElasticSearch/0.1.0"],
}
}).do_request().as(resp,
resp.StatusCode == 200 ?
bytes(resp.Body).decode_json().as(body, {
"events": (has(body.results) && body.results.size() > 0 ?
(
body.results.map(e,{
"message": e.encode_json()
})
)
:
(
[{"message": body.encode_json()}]
)
),
"cursor": {
"last_published_date": (
has(body.results) && body.results.size() > 0 ?
(
has(state.?cursor.last_published_date) && body.results.map(e, e.spycloud_publish_date).max() < state.cursor.last_published_date ?
state.cursor.last_published_date
:
body.results.map(e, e.spycloud_publish_date).max()
)
:
state.?cursor.last_published_date.orValue("1970-01-02T00:00:00Z")
),
"first_published_date": (
has(state.?cursor.first_published_date) && has(body.results) && body.results.size() > 0 ?
(
has(body.cursor) && body.cursor != "" && state.want_more ? state.cursor.first_published_date : state.cursor.last_published_date
)
:
"1970-01-02T00:00:00Z"
),
},
"pagination_token": has(body.cursor) && body.cursor != "" ? body.cursor : "",
"want_more": has(body.cursor) && body.cursor != "",
"api_key": state.api_key
})
:
{
"events": {
"error": {
"code": string(resp.StatusCode),
"id": string(resp.Status),
"message": string(resp.Body)
}
},
"want_more": false,
"api_key": state.api_key
}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested

request(
  "GET",
  state.url + "/breach/catalog?" + {
    ?"since": (state.?want_more.orValue(false) ? state.?cursor.first_published_date : state.?cursor.last_published_date).as(date,
      date.hasValue() ?
        optional.of([(timestamp(date.Value()) - duration("24h")).format(time_layout.DateTime)])
      :
        optional.none()
    ),
    ?"cursor": state.?want_more.orValue(false) ? [state.pagination_token] : optional.none(),
  }.format_query()
).with({
    "Header": {
      "x-api-key": [state.api_key],
      "User-Agent": ["ElasticSearch/0.1.0"],
    },
}).do_request().as(resp, resp.StatusCode == 200 ?
  bytes(resp.Body).decode_json().as(body,
    {
      "events": (has(body.results) && body.results.size() > 0) ?
        body.results.map(e, {"message": e.encode_json()})
      :
        [{"message": body.encode_json()}],
      "cursor": {
        ?"last_published_date": (has(body.results) && body.results.size() > 0) ?
          optional.of(([?state.?cursor.last_published_date] + body.results.map(e, e.spycloud_publish_date)).max())
        :
          state.?cursor.last_published_date,
        ?"first_published_date": (has(state.?cursor.first_published_date) && has(body.results) && body.results.size() > 0) ?
          (
            (has(body.cursor) && body.cursor != "" && state.want_more) ?
              state.cursor.first_published_date
            :
              state.cursor.last_published_date
          )
        :
          optional.none(),
      },
      "pagination_token": body.?cursor.orValue(""),
      "want_more": body.?cursor.orValue("") != "",
      "api_key": state.api_key,
    }
  )
:
  {
    "events": {
      "error": {
        "code": string(resp.StatusCode),
        "id": string(resp.Status),
        "message": string(resp.Body),
      },
    },
    "want_more": false,
    "api_key": state.api_key,
  }
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try the code above and find that it does not work? If so, what was the error?

Comment thread packages/spycloud/data_stream/compass/_dev/test/pipeline/test-compass.log Outdated
fields:
- api_key
program: |
request("GET", state.url + "/compass/data?since=" + (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comments here.

1. Implemented Readme changes.
2. Applied minify_json in config.yml.
3. Implemented all the suggested data-collection changes.
@muskan-crest
muskan-crest requested a review from efd6 July 31, 2024 11:26
@efd6

efd6 commented Jul 31, 2024

Copy link
Copy Markdown
Contributor

/test

@elasticmachine

Copy link
Copy Markdown

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

Comment thread packages/spycloud/data_stream/breach_catalog/agent/stream/cel.yml.hbs Outdated
)).with({
"Header":{
"x-api-key": [state.api_key],
"User-Agent": ["ElasticSearch/0.1.0"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't think this is a good idea; it gives the wrong indication to the server who we are (we are not an Elasticsearch instance). Also the "S" should be lowercase.

Comment thread packages/spycloud/data_stream/breach_catalog/agent/stream/cel.yml.hbs Outdated
Comment thread packages/spycloud/data_stream/breach_catalog/agent/stream/cel.yml.hbs Outdated
fields:
- api_key
program: |
state.?since_data.orValue(false) ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://pkg.go.dev/github.com/elastic/mito/lib#hdr-Global_Variables and https://pkg.go.dev/time#pkg-constants. But the constants are just strings and work the same way that Go time formats work, so if one does not exist, you can just use the literal, "2006-01-02".

"first_modified_date": state.?cursor.first_modified_date.orValue((now - duration(state.initial_interval)).format(time_layout.RFC3339)),
"last_modified_date": state.?cursor.last_modified_date.orValue((now - duration(state.initial_interval)).format(time_layout.RFC3339)),
},
"pagination_token_since": first_body.?cursor.orValue(""),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"pagination_token_since": first_body.?cursor.orValue(""),
?"pagination_token_since": first_body.?cursor,

?

"since_modified_data": true,
}
)
:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comments below.

redact:
fields:
- api_key
program: |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comments apply here.

has(state.?cursor.last_published_date) && state.cursor.last_published_date != null ?
string((timestamp(state.cursor.last_published_date) - duration("24h"))).split("T")[0]
:
"1970-01-01"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this documented as being a required parameter? i.e. if the parameter were not present would we get the same behaviour?

Comment on lines +23 to +94
request("GET", state.url + "/breach/catalog?since=" + (
!state.?want_more.orValue(false) ?
(
has(state.?cursor.last_published_date) && state.cursor.last_published_date != null ?
string((timestamp(state.cursor.last_published_date) - duration("24h"))).split("T")[0]
:
"1970-01-01"
)
:
(
has(state.?cursor.first_published_date) && state.cursor.first_published_date != null ?
string((timestamp(state.cursor.first_published_date) - duration("24h"))).split("T")[0]
:
""
) + "&cursor=" + state.pagination_token
)).with({
"Header":{
"x-api-key": [state.api_key],
"User-Agent": ["ElasticSearch/0.1.0"],
}
}).do_request().as(resp,
resp.StatusCode == 200 ?
bytes(resp.Body).decode_json().as(body, {
"events": (has(body.results) && body.results.size() > 0 ?
(
body.results.map(e,{
"message": e.encode_json()
})
)
:
(
[{"message": body.encode_json()}]
)
),
"cursor": {
"last_published_date": (
has(body.results) && body.results.size() > 0 ?
(
has(state.?cursor.last_published_date) && body.results.map(e, e.spycloud_publish_date).max() < state.cursor.last_published_date ?
state.cursor.last_published_date
:
body.results.map(e, e.spycloud_publish_date).max()
)
:
state.?cursor.last_published_date.orValue("1970-01-02T00:00:00Z")
),
"first_published_date": (
has(state.?cursor.first_published_date) && has(body.results) && body.results.size() > 0 ?
(
has(body.cursor) && body.cursor != "" && state.want_more ? state.cursor.first_published_date : state.cursor.last_published_date
)
:
"1970-01-02T00:00:00Z"
),
},
"pagination_token": has(body.cursor) && body.cursor != "" ? body.cursor : "",
"want_more": has(body.cursor) && body.cursor != "",
"api_key": state.api_key
})
:
{
"events": {
"error": {
"code": string(resp.StatusCode),
"id": string(resp.Status),
"message": string(resp.Body)
}
},
"want_more": false,
"api_key": state.api_key
}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try the code above and find that it does not work? If so, what was the error?

Comment thread packages/spycloud/data_stream/compass/sample_event.json
1. Replace the time format with the string literal.
2. Added dynamic mappings for the url.*.
3. Removed the first_published cursor as not required.
4. Implemented the suggested data-collection changes
@muskan-crest
muskan-crest requested review from efd6 and kcreddy August 5, 2024 09:06
Comment on lines +25 to +32
state.url + "/breach/catalog?" + {
?"since": (state.?want_more.orValue(false) ? optional.none()
:
has(state.?cursor.last_published_date) ?
optional.of([(timestamp(state.cursor.last_published_date) - duration("24h")).format("2006-01-02")])
:
optional.none()
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
state.url + "/breach/catalog?" + {
?"since": (state.?want_more.orValue(false) ? optional.none()
:
has(state.?cursor.last_published_date) ?
optional.of([(timestamp(state.cursor.last_published_date) - duration("24h")).format("2006-01-02")])
:
optional.none()
),
state.url + "/breach/catalog?" + {
?"since": (state.?want_more.orValue(false) || !has(state.?cursor.last_published_date)) ?
optional.none()
:
optional.of([(timestamp(state.cursor.last_published_date) - duration("24h")).format("2006-01-02")]),

[{"message": body.encode_json()}],
"cursor": {
?"last_published_date": (has(body.results) && body.results.size() > 0) ?
optional.of(([?state.?cursor.last_published_date] + body.results.map(e, e.spycloud_publish_date)).max())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the format of spycloud_publish_date? I assume this is a date format. "2006-01-02"? While this is not strictly a timestamp (it's a string), it does always sort the same way as the corresponding timestamp, so it should be ok to leave as a string. Is this a correct assessment?

Comment on lines +53 to +55
(
first_body.results.map(e, {"message": e.encode_json()})
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(
first_body.results.map(e, {"message": e.encode_json()})
)
first_body.results.map(e, {"message": e.encode_json()})

Comment on lines +62 to +63
?"last_published_date": (has(first_body.results) && first_body.results.size() > 0) ?
optional.of(([?state.?cursor.last_published_date] + first_body.results.map(e, e.spycloud_publish_date)).max())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What format are the timestamps here? If they are not lexically sortable with the same ordering as the chronological sort this is not correct. See #10608 (comment).

[{"message": body.encode_json()}],
"cursor": {
?"last_published_date": (has(body.results) && body.results.size() > 0) ?
optional.of(([?state.?cursor.last_published_date] + body.results.map(e, e.spycloud_publish_date)).max())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@kcreddy kcreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many PII and PCI information in these datasets. like passport, dob, age, address, postal_code, bank_number, credit card, ssn, etc.

@jamiehynds, do we have any policies to mask or delete such information before ingesting them?

Comment thread packages/spycloud/_dev/build/docs/README.md Outdated
Comment on lines +81 to +83
"device": {
"model": 890123,
"name": 456721

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to device ecs

@kcreddy kcreddy Aug 9, 2024 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per developer (confirmed with Spycloud team), the values for the breach_catalog datastream are numeric, representing the actual count. Hence ECS mapping is not possible. Same for comments #10608 (comment) and #10608 (comment)

cc: @muskan-crest

Comment thread packages/spycloud/data_stream/breach_record/sample_event.json Outdated
1. Syntactical change in cel code.
2. Added ecs mapping in breach record and compass.
3. Masked the user sensitive details.
@muskan-crest
muskan-crest requested review from efd6 and kcreddy August 8, 2024 12:18
@efd6

efd6 commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

/test

?"since": (state.?want_more.orValue(false) || !has(state.?cursor.last_published_date)) ?
optional.none()
:
optional.of([(timestamp(state.cursor.last_published_date) - duration("24h")).format("2006-01-02")]),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this 24h look-back offset to prevent loss of data due to the low temporal resolution of the query parameter?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data is generated daily at 12:00 AM in SpyCloud. For example, on July 31st, data will be created at 12:00 AM. If the API is accessed on August 1st at 3:00 PM, the operation labeled "now - 24h" will retrieve data starting from 3:00 PM on July 31st. Consequently, data from 12:00 AM to 2:59 PM on July 31st will be excluded and not retrieved. To prevent data loss, we implement a 24-hour look-back offset.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the API is accessed on August 1st at 3:00 PM, the operation labeled "now - 24h" will retrieve data starting from 3:00 PM on July 31st.

Why? The "since" value does not get anything about the time of day; the format is "2006-01-02" which means that the query would be 2024-08-01. If you offset backwards by 24 hours, you will get 2024-07-31. If the query indicates to the API that it should be from the start of the day, then this offset is not needed, if it means from the end of the day, then it is.

optional.of(string(([?state.?cursor.last_modified_date] + second_body.results.map(e, e.record_modification_date)).map(t, timestamp(t)).max()))
:
state.?cursor.last_modified_date,
"last_published_date": state.?cursor.last_published_date.orValue(null),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using a fallback of null here? If it is to indicate that it should not be used, let's use an optional field.

Suggested change
"last_published_date": state.?cursor.last_published_date.orValue(null),
?"last_published_date": state.?cursor.last_published_date,

Why does this differ from the case in the other main conditional branch where the fallback is to now - duration(state.initial_interval)? Note that putting that look-back deep in the program makes me queazy; I have been working on another integration that was doing this and I think that it was the cause of needless duplicate queries. Why is the look-back there?

Comment on lines +29 to +35
(state.?cursor.last_published_date).as(date,
optional.of([(date.hasValue() ?
timestamp(state.cursor.last_published_date) - duration("24h")
:
now - (duration(state.initial_interval) + duration("24h"))
).format("2006-01-02")])
)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation here.

field: spycloud.compass.cc.bin
tag: mask_cc_bin
value: '******'
if: ctx.tags != null && ctx.tags.contains('hide_sensitive_true') && ctx.spycloud?.compass?.cc?.bin != null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if: ctx.tags != null && ctx.tags.contains('hide_sensitive_true') && ctx.spycloud?.compass?.cc?.bin != null
if: ctx.tags != null && ctx.tags.contains('hide_sensitive') && ctx.spycloud?.compass?.cc?.bin != null

?
/cc @kcreddy

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with hide_sensitive as the parameter name instead of hide_sensitive_true.

- set:
field: spycloud.compass.cc.bin
tag: mask_cc_bin
value: '******'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to use a more searchable value?

1. Changed the mask value to REDACT.
2. Rename hide_sensitive_true to hide_sensitive.
3. Changed the cursor in breach_record, and indented the code.
@kcreddy

kcreddy commented Aug 9, 2024

Copy link
Copy Markdown
Contributor

/test

@kcreddy kcreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following are fields I can identify (only based on sample logs) that could be masked, if we want to proceed with masking sensitive PII and PCI data:

breach_catalog: None (See #10608 (comment))

breach_record:

  • password.plaintext
  • password.value

compass:

  • bank_number
  • cc.bin
  • cc.expiration
  • cc.last_four
  • cc.number
  • drivers.license.number
  • drivers.license.state_code
  • national_id
  • passport_number
  • password.plaintext
  • password.value
  • postal_code
  • social_security_number
  • ssn_last_four

@muskan-crest please check if all fields from above are accounted for into hide_sensitive option.

@andrewkroh, we are adding a user-configurable toggle hide_sensitive (default: true) to allow users to mask above sensitive content (with value REDACTED).
Do you have any concerns with this approach?

@andrewkroh

Copy link
Copy Markdown
Contributor

we are adding a user-configurable toggle hide_sensitive (default: true) to allow users to mask above sensitive content (with value REDACTED). Do you have any concerns with this approach?

One concern is that the redaction happens in Elasticsearch instead of Elastic Agent. Could we do the redaction inside of the Elastic Agent? It looks like we have a finite set of fields and the data is JSON so this seems feasible.

The other concern is usability. I don't know the exact use case for this data, but with similar datasets a question you may want to ask is was my password/CC#/etc value exposed? If you just do a string replacement you can no longer answer this question with certainty. But if do an HMAC on the value you can still answer this question if you are privileged enough to know the HMAC secret.

This is how the audit logs from Hashicorp Vault operate. When a secret is returned in a response, then it writes

"social_security_number": "hmac-sha256:0571ce2ab802e6f2e12552b09e783097a961b1c83ea50f47fba9cd0a2bc84b0a"

in the event. When the original secret value and the HMAC secret are known then this can be used to search the logs to determine if a value was accessed (or exposed in this case). So if you can pass a secret to the Agent and then run an HMAC on the list of sensitive field values we would have a better design IMO.

@muskan-crest
muskan-crest requested a review from efd6 August 12, 2024 00:28
?"since": (state.?want_more.orValue(false) || !has(state.?cursor.last_published_date)) ?
optional.none()
:
optional.of([(timestamp(state.cursor.last_published_date) - duration("24h")).format("2006-01-02")]),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the API is accessed on August 1st at 3:00 PM, the operation labeled "now - 24h" will retrieve data starting from 3:00 PM on July 31st.

Why? The "since" value does not get anything about the time of day; the format is "2006-01-02" which means that the query would be 2024-08-01. If you offset backwards by 24 hours, you will get 2024-07-31. If the query indicates to the API that it should be from the start of the day, then this offset is not needed, if it means from the end of the day, then it is.

:
(state.?cursor.last_published_date).as(date,
optional.of([(date.hasValue() ?
timestamp(state.cursor.last_published_date) - duration("24h")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here. I am not convinced that this is correct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation is a requirement from the customer rather than from us. Since it has already been confirmed and tested by the customer, we cannot make any changes.

optional.of([(date.hasValue() ?
timestamp(state.cursor.last_published_date) - duration("24h")
:
now - (duration(state.initial_interval) + duration("24h"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is less of a concern, but I'm still dubious about it.

Comment on lines +51 to +56
(
first_body.results.size() > 0 ?
first_body.results.map(e, {"message": e.encode_json()})
:
[{"message":"No hits for Breach Catalog using since filter"}]
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation of this block.

Comment on lines +76 to +90
{
"events": {
"error": {
"code": string(resp.StatusCode),
"id": string(resp.Status),
"message": string(resp.Body),
}
},
"api_key": state.api_key,
"want_more": false,
"initial_interval": state.initial_interval,
"severity": state.severity,
"since_data": true,
"since_modified_data": true,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation of this block.

Also, the resp.Body may be empty, so we synthesise a message in that case. Example here. This applies to the other cases here as well.

@kcreddy kcreddy mentioned this pull request Aug 12, 2024
4 tasks done
1. Remove the -24h logic in data collection.
2. Add hide sensitive mask to few more fields.
@muskan-crest
muskan-crest requested review from efd6 and kcreddy August 16, 2024 06:37

@efd6 efd6 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but waiting for @kcreddy

@efd6

efd6 commented Aug 16, 2024

Copy link
Copy Markdown
Contributor

/test

@elasticmachine

Copy link
Copy Markdown

💚 Build Succeeded

History

@elastic-sonarqube

Copy link
Copy Markdown

@kcreddy
kcreddy merged commit abda64a into elastic:main Aug 16, 2024
@elasticmachine

Copy link
Copy Markdown

Package spycloud - 0.1.0 containing this change is available at https://epr.elastic.co/search?package=spycloud

@andrewkroh andrewkroh added the Integration:spycloud SpyCloud Enterprise Protection (Partner supported) label Aug 19, 2024
mick-lue pushed a commit to mick-lue/integrations that referenced this pull request Aug 27, 2024
Initial release of Spycloud

Added three data streams - breach_catalog, breach_record and compass.
Added data collection logic for all the three data streams.
Added the ingest pipeline for all the three data streams.
Mapped fields according to the ECS schema and added Fields metadata in the appropriate yml files.
Added dashboards and visualizations.
Added test for pipeline for all the three data streams.
Added system test cases for all the three data streams.
harnish-crest-data pushed a commit to chavdaharnish/integrations that referenced this pull request Feb 4, 2025
Initial release of Spycloud

Added three data streams - breach_catalog, breach_record and compass.
Added data collection logic for all the three data streams.
Added the ingest pipeline for all the three data streams.
Mapped fields according to the ECS schema and added Fields metadata in the appropriate yml files.
Added dashboards and visualizations.
Added test for pipeline for all the three data streams.
Added system test cases for all the three data streams.
harnish-crest-data pushed a commit to chavdaharnish/integrations that referenced this pull request Feb 5, 2025
Initial release of Spycloud

Added three data streams - breach_catalog, breach_record and compass.
Added data collection logic for all the three data streams.
Added the ingest pipeline for all the three data streams.
Mapped fields according to the ECS schema and added Fields metadata in the appropriate yml files.
Added dashboards and visualizations.
Added test for pipeline for all the three data streams.
Added system test cases for all the three data streams.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Crest Contributions from Crest developement team. Integration:spycloud SpyCloud Enterprise Protection (Partner supported) New Integration Issue or pull request for creating a new integration package. Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants