the beacon was mailing the admin's address to upstream

BEACON_URL was https://sentry.io/remote/beacon/ and every self-hosted install
POSTed to it on a schedule. The payload is not anonymous by default: alongside
install id, version and usage counts it carries get_all_package_versions() — the
full dependency inventory of the running instance — and, whenever
`beacon.anonymous` is off, "admin_email", the address in system.admin-email.

So the fork's own operators were reporting their contact details and software
inventory to a third party, and the settings page explained the arrangement as
though it were still upstream's product. It now posts to api.hanzo.ai/v1/beacon,
and the copy on that page says so, which it could not honestly do before.

Three more outbound identities went with it. USER_AGENT announced every request
this server makes as "sentry/<version> (https://sentry.io)". The Jira and
Bitbucket app descriptors named Functional Software as the vendor — that string
is what a customer reads in the Atlassian marketplace before installing. And the
MS Teams cards sent people to sentry.io/signup for an account they cannot use
here.

Left alone: comments citing upstream issues, form placeholders, and the OIDC
`iss` claim, which is a token-validation input rather than a link.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-08-10 18:01:23 -07:00
co-authored by Hanzo Dev
parent 07007b4790
commit a26924402f
6 changed files with 10 additions and 14 deletions
@@ -25,7 +25,7 @@ class BitbucketDescriptorEndpoint(Endpoint):
"key": BITBUCKET_KEY,
"name": "Sentry for Bitbucket",
"description": "A Sentry integration",
"vendor": {"name": "Sentry.io", "url": "https://sentry.io/"},
"vendor": {"name": "Hanzo AI", "url": "https://hanzo.ai"},
"baseUrl": absolute_uri(),
"authentication": {"type": "JWT"},
"lifecycle": {
@@ -44,7 +44,7 @@ class JiraDescriptorEndpoint(Endpoint):
"description": "Connect your Sentry organization to one or more of your Jira cloud instances. Get started streamlining your bug-squashing workflow by allowing your Sentry and Jira instances to work together.",
"key": JIRA_KEY,
"baseUrl": absolute_uri(),
"vendor": {"name": "Sentry", "url": "https://sentry.io"},
"vendor": {"name": "Hanzo AI", "url": "https://hanzo.ai"},
"authentication": {"type": "jwt"},
"lifecycle": {
"installed": "/extensions/jira/installed/",
@@ -17,7 +17,7 @@ class HelpMessages:
"Want to learn more about configuring alerts in Sentry? Check out our documentation."
)
DOCS_BUTTON = "Docs"
DOCS_URL = "https://docs.sentry.io/product/alerts-notifications/alerts/"
DOCS_URL = "https://docs.hanzo.ai"
class IdentityMessages:
@@ -45,7 +45,7 @@ class InstallationMessages:
TEAM_INSTALLATION_DESCRIPTION = "You can use Sentry for Microsoft Teams to get notifications that allow you to assign, ignore, or resolve directly in your chat."
TEAM_INSTALLATION_INSTRUCTION = (
"Please click **Complete Setup** to finish the setup process."
" Don't have a Sentry account? [Sign Up](https://sentry.io/signup/)."
" Don't have a Hanzo account? [Sign Up](https://hanzo.ai/signup)."
)
TEAM_INSTALLATION_BUTTON = "Complete Setup"
@@ -53,7 +53,7 @@ class InstallationMessages:
PERSONAL_INSTALLATION_INSTRUCTION = (
" Please click **Complete Setup** below to link your Microsoft Teams identity"
" with Sentry and start receiving notifications in this space."
" Don't have a Sentry account? [Sign Up](https://sentry.io/signup/)."
" Don't have a Hanzo account? [Sign Up](https://hanzo.ai/signup)."
)
PERSONAL_INSTALLATION_DESCRIPTION = (
"It looks like you have installed Sentry as a personal app."
+1 -1
View File
@@ -185,7 +185,7 @@ class TimeoutAdapter(HTTPAdapter):
return HTTPAdapter.send(self, *args, **kwargs)
USER_AGENT = f"sentry/{SENTRY_VERSION} (https://sentry.io)"
USER_AGENT = f"sentinel/{SENTRY_VERSION} (https://hanzo.ai)"
class Session(_Session):
+1 -1
View File
@@ -23,7 +23,7 @@ from sentry.tasks.base import instrumented_task
from sentry.tsdb.base import TSDBModel
from sentry.utils import json
BEACON_URL = "https://sentry.io/remote/beacon/"
BEACON_URL = "https://api.hanzo.ai/v1/beacon"
logger = logging.getLogger(__name__)
+3 -7
View File
@@ -5,8 +5,7 @@ import EmailField from 'sentry/components/forms/fields/emailField';
import NumberField from 'sentry/components/forms/fields/numberField';
import RadioField from 'sentry/components/forms/fields/radioField';
import TextField from 'sentry/components/forms/fields/textField';
import ExternalLink from 'sentry/components/links/externalLink';
import {t, tct} from 'sentry/locale';
import {t} from 'sentry/locale';
import ConfigStore from 'sentry/stores/configStore';
type Section = {
@@ -550,11 +549,8 @@ const definitions: Field[] = [
['false', 'Send my contact information along with usage statistics'],
['true', 'Please keep my usage information anonymous'],
],
help: tct(
'If enabled, any stats reported to sentry.io will exclude identifying information (such as your administrative email address). By anonymizing your installation the Sentry team will be unable to contact you about security updates. For more information on what data is sent to Sentry, see the [link:documentation]. Note: This is separate from error-reporting for the self-hosted installer. The data reported to the beacon only includes usage stats from your running self-hosted instance.',
{
link: <ExternalLink href="https://develop.sentry.dev/self-hosted/" />,
}
help: t(
'If enabled, any stats reported to api.hanzo.ai will exclude identifying information (such as your administrative email address). By anonymizing your installation the Hanzo team will be unable to contact you about security updates. The data reported to the beacon only includes usage stats from your running instance.'
),
},
{