RelayShield
RelayShield real-time identity-compromise and agent-security threat intelligence. Implements the generic `domain`/`ip`/`email` reputation commands (auto-invoked by existing enrichment playbooks) plus RelayShield-specific commands for MCP server registry risk, certificate expiry, and supply-chain vendor risk. "No known finding" from any command means nothing was flagged in the sources RelayShield actually queried. It is deliberately never mapped to a "Good" DBotScore, since that would claim more certainty than the data supports. See the README's DBotScore section for the exact mapping.
Data Enrichment & Threat Intelligence · RelayShield
Details
| ID | RelayShield |
|---|---|
| Provider | RelayShield |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.8.0 |
| Docker Image | demisto/python3:3.12.14.12343672 |
README
RelayShield real-time identity-compromise and agent-security threat intelligence.
This integration implements the generic domain, ip, and email reputation commands,
which are automatically invoked by any existing enrichment playbook that calls generic
reputation commands, with no playbook changes needed. It adds three RelayShield-specific
commands for MCP server registry risk, certificate expiry, and supply-chain vendor risk.
This integration was integrated and tested with version 1.0 of the RelayShield API.
Configure RelayShield in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | The RelayShield API base URL. | True |
| API Key | The RelayShield API key, sent as the X-RS-API-KEY header. |
True |
| Trust any certificate (not secure) | Whether to trust any TLS certificate. | False |
| Use system proxy settings | Whether to route requests through the system proxy. | False |
| Source Reliability | Reliability of the source providing the intelligence data. | False |
DBotScore mapping
A clean result (“no known finding”) maps to DBotScore Unknown (0), never Good (1).
“No known finding” means nothing was flagged in the sources RelayShield actually queried,
which is not a verified-safe guarantee.
| RelayShield verdict | DBotScore |
|---|---|
| CRITICAL | 3 (Bad) |
| HIGH | 3 (Bad) |
| MEDIUM | 2 (Suspicious) |
| LOW | 2 (Suspicious) |
| No known finding | 0 (Unknown) |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the
command details.
domain
Check a domain for phishing-lookalike/typosquat risk, presence in RelayShield’s criminal IOC corpus, and set a DBotScore.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | A comma-separated list of domains to check. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.Domain.queried | String | The domain queried. |
| RelayShield.Domain.verdict | String | The RelayShield verdict (CRITICAL/HIGH/MEDIUM/LOW), absent if no known finding. |
| RelayShield.Domain.findings | Unknown | The list of findings, if any. |
| Domain.Name | String | The domain name. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
ip
Check an IP address for reputation, malicious/suspicious votes, and set a DBotScore.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | A comma-separated list of IP addresses to check. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.IP.queried | String | The IP address queried. |
| RelayShield.IP.reputation | Number | The community reputation score. |
| RelayShield.IP.malicious_votes | Number | The malicious vote count. |
| IP.Address | String | The IP address. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
Check an email address for breach exposure and active stolen-session risk, and set a DBotScore.
Base Command
email
Input
| Argument Name | Description | Required |
|---|---|---|
| A comma-separated list of email addresses to check. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.Email.queried | String | The email address queried. |
| RelayShield.Email.breach_found | Boolean | Whether the email address appears in a known breach. |
| RelayShield.Email.breach_sources | Unknown | The list of breach sources the email address was found in. |
| RelayShield.Email.session_risk_found | Boolean | Whether an active stolen session was found. |
| RelayShield.Email.sessions | Unknown | The list of stolen sessions found, if any. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
relayshield-mcp-registry-risk
Assess an MCP server URL or package name for typosquat/supply-chain/registry risk before an agent connects to it.
Base Command
relayshield-mcp-registry-risk
Input
| Argument Name | Description | Required |
|---|---|---|
| server_url | The full URL of the MCP server to check. Provide this or package_name. | Optional |
| package_name | The package name of the MCP server if no server_url is available. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.MCPRegistryRisk.queried | String | The server URL or package name queried. |
| RelayShield.MCPRegistryRisk.verdict | String | The RelayShield verdict, absent if no known finding. |
| RelayShield.MCPRegistryRisk.findings | Unknown | The list of findings, if any. |
relayshield-cert-expiry
Check a domain’s TLS certificate expiry risk.
Base Command
relayshield-cert-expiry
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The domain to check. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.CertExpiry.domain | String | The domain checked. |
| RelayShield.CertExpiry.days_remaining | Number | The days until certificate expiry. |
| RelayShield.CertExpiry.risk_level | String | The risk level (CRITICAL/HIGH/MEDIUM/LOW). |
relayshield-supply-chain
Check up to 10 vendor domains (or emails) for combined breach/infostealer risk.
Base Command
relayshield-supply-chain
Input
| Argument Name | Description | Required |
|---|---|---|
| vendor_domains | A comma-separated list of up to 10 vendor domains to check. Provide this or vendor_emails. | Optional |
| vendor_emails | A comma-separated list of vendor email addresses. The domain portion is extracted automatically. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RelayShield.SupplyChain.domains_checked | Number | The number of vendor domains checked. |
| RelayShield.SupplyChain.highest_risk | String | The highest risk level found across all vendors checked. |
| RelayShield.SupplyChain.critical_vendors | Unknown | The list of vendors flagged as critical risk. |
Configuration parameters
url— Server URL (required)credentials— API Key (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsintegrationReliability— Source Reliability
Commands (6)
-
domainCheck a domain for phishing-lookalike/typosquat risk, presence in RelayShield's criminal IOC corpus, and set a DBotScore.
-
emailCheck an email address for breach exposure and active stolen-session risk, and set a DBotScore.
-
ipCheck an IP address for reputation, malicious/suspicious votes, and set a DBotScore.
-
relayshield-cert-expiryCheck a domain's TLS certificate expiry risk.
-
relayshield-mcp-registry-riskAssess an MCP server URL or package name for typosquat/supply-chain/registry risk before an agent connects to it.
-
relayshield-supply-chainCheck up to 10 vendor domains (or emails) for combined breach/infostealer risk.
from unittest.mock import patch import pytest import RelayShield RELIABILITY = "B - Usually reliable" def _client(): return RelayShield.Client(base_url="https://api.relayshield.net", api_key="rs_live_testkey", verify=True, proxy=False) def test_domain_command_finding(): client = _client() with patch.object( client, "call", return_value={ "queried": "evil.com", "verdict": "CRITICAL", "findings": [{"type": "typosquat_suspected"}], "checked_at": "2026-07-22T00:00:00Z", }, ): results = RelayShield.domain_command(client, {"domain": "evil.com"}, RELIABILITY) assert len(results) == 1 r = results[0] assert r.indicator.dbot_score.score == 3 assert r.indicator.dbot_score.reliability == RELIABILITY assert r.indicator.domain == "evil.com" def test_domain_command_clean_maps_to_unknown_not_good(): """A clean result must map to DBotScore Unknown (0), never Good (1) -- "no known finding" is not the same claim as "verified safe".""" client = _client() with patch.object(client, "call", return_value={"queried": "clean.com", "verdict": None, "findings": []}): results = RelayShield.domain_command(client, {"domain": "clean.com"}, RELIABILITY) assert results[0].indicator.dbot_score.score == 0 def test_ip_command(): client = _client() with patch.object( client, "call", return_value={ "queried": "1.2.3.4", "reputation": 50, "malicious_votes": 2, "as_owner": "Evil Corp", "country": "US", }, ): results = RelayShield.ip_command(client, {"ip": "1.2.3.4"}, RELIABILITY) assert results[0].indicator.dbot_score.score == 3 assert results[0].indicator.asn == "Evil Corp" def test_email_command_combines_breach_and_session(): client = _client() with patch.object( client, "call", side_effect=[ {"found": True, "sources": ["breach1"]}, {"found": True, "sessions": [{"severity": "CRITICAL", "service_category": "email"}]}, ], ): results = RelayShield.email_command(client, {"email": "victim@example.com"}, RELIABILITY) r = results[0] assert r.indicator.dbot_score.score == 3 assert r.outputs["breach_found"] is True assert r.outputs["session_risk_found"] is True def test_mcp_registry_risk_command_requires_input(): client = _client() try: RelayShield.mcp_registry_risk_command(client, {}) pytest.fail("should have raised") except ValueError: pass def test_mcp_registry_risk_command(): client = _client() with patch.object( client, "call", return_value={ "queried": "https://evil-mcp.test", "verdict": "HIGH", "findings": [{"type": "typosquat_suspected"}], }, ): result = RelayShield.mcp_registry_risk_command(client, {"server_url": "https://evil-mcp.test"}) # Assert on the structured outputs with an equality check rather than a # substring search over the rendered markdown. A `"..." in <url string>` # test is what CodeQL flags as incomplete URL substring sanitization, and # the exact-match form is a stricter assertion anyway. assert result.outputs["queried"] == "https://evil-mcp.test" assert result.outputs["verdict"] == "HIGH" def test_cert_expiry_command(): client = _client() with patch.object(client, "call", return_value={"days_remaining": 3, "risk_level": "CRITICAL"}): result = RelayShield.cert_expiry_command(client, {"domain": "example.com"}) assert result.outputs["days_remaining"] == 3 def test_supply_chain_command_requires_input(): client = _client() try: RelayShield.supply_chain_command(client, {}) pytest.fail("should have raised") except ValueError: pass def test_supply_chain_command(): client = _client() with patch.object( client, "call", return_value={ "domains_checked": 2, "highest_risk": "HIGH", "critical_vendors": [], }, ): result = RelayShield.supply_chain_command(client, {"vendor_domains": ["a.com", "b.com"]}) assert result.outputs["domains_checked"] == 2 def test_client_call_raises_on_error_envelope(): client = _client() with patch.object(RelayShield.BaseClient, "_http_request", return_value={"ok": False, "error": "bad request"}): try: client.call("/v1/metered/domain", {"domain": "x.com"}) pytest.fail("should have raised") except RelayShield.DemistoException as e: assert "bad request" in str(e) @pytest.mark.parametrize( "params", [ {"credentials": None, "api_key": None}, {"credentials": {}, "api_key": None}, {}, ], ) def test_main_missing_api_key_does_not_raise_attributeerror(mocker, params): """XSOAR stores an unset encrypted parameter as an explicit None, so params.get("api_key", {}) returns None rather than the default and chaining .get() on it used to raise AttributeError. main() must surface a readable configuration error instead.""" mocker.patch.object(RelayShield.demisto, "params", return_value=params) mocker.patch.object(RelayShield.demisto, "args", return_value={}) mocker.patch.object(RelayShield.demisto, "command", return_value="test-module") return_error = mocker.patch.object(RelayShield, "return_error") RelayShield.main() message = return_error.call_args[0][0] assert "AttributeError" not in message assert "API Key is required" in message