Skip to main content

Enterprise Plugin Security

Security specification of the Enterprise Plugin: what permissions the process needs, what firewall rules apply and what data it actually exchanges with Q247. A short version of this split is also on the Connectors page; this is the full, technical specification.

Process permissions

The plugin runs in a local directory and does not require administrator privileges. While working, it creates temporary subdirectories in the current directory, into which it fetches the code history and increments; once the effort and calorie analysis is finished, they are deleted automatically.

It also runs a local database, in which it stores configuration, connection parameters and the repository information needed for communication.

The plugin has no access to any directory outside its own home directory.

Firewall rules

Outbound traffic

SourceSource portDestinationDestination portPurpose
plugin hostanyaddress of the Client's Git repository443The plugin connects over HTTPS to fetch data from the Git repository.
plugin hostanyQ247 backend443The plugin sends increment "fingerprints" over HTTPS to the central panel and fetches connector configuration and the list of repositories to scan. Destination addresses are provided by the Q247 deployment team.
plugin hostanythe Client's Jira or Confluence instance443The plugin reads tickets, statuses and pages when the Jira and Confluence integrations are enabled.

Inbound traffic

By default, all inbound traffic to the plugin host must be blocked.

The only exception concerns deployments where the plugin receives webhooks from a Jira or Confluence Data Center instance. In that case, traffic from those instances must be allowed on the port on which the plugin listens for webhooks; the port number for a given deployment is provided by the Q247 deployment team. The traffic stays inside the Client's network and does not require access from the internet.

Cloud versions of Jira and Confluence do not need any inbound rule, because their events reach a receiver on the Q247 side.

TLS inspection at the firewall

If the Client's firewall terminates TLS connections and re-signs them with its own certificate, the plugin will not recognize the Q247 backend's certificate and the connection will fail. The solution is to hand the deployment team a PEM file with the corporate CA certificate, as described in Installation. Certificate verification is disabled only as an emergency measure.

Data exchange

All communication between the Enterprise Plugin and the Q247 Management Portal is secured with HTTPS:

  • Minimum TLS version: 1.2
  • HTTPS only: yes

The content of code changes, as well as the content of tickets and pages, stays on the plugin host. The analysis runs locally, and only its result, together with the metadata needed for the metrics, goes to Q247. The tables below list this metadata exhaustively.

Events from code repositories

CategoryWhat exactly
Change identificationcommit identifier, remote repository address, repository type, authorship timestamp
Authorcommitter's first name, last name and e-mail address, in the form recorded by Git
Commit messagethe full message content, without truncation. It is needed to recognize the ticket key and AI tool trailers, so it goes to Q247 in full
List of changed filesfile paths and names, together with the number of inserted and deleted lines and the calorie score of each of them
Change summarynumber of files, number of inserted and deleted lines
Branchesnames of the branches the commit was on at the moment of scanning
Analysis resultcalorie score, effort vector, name and version of the model that calculated it
Q247 contextorganization and project identifier
Ticket keythe identifier recognized in the commit message, together with its prefix
Diagnostic datainformation on whether the file list or the change content was trimmed due to size, together with numbers describing the scale of the trimming
File paths and commit messages are passed in full

File paths are necessary for File Pattern Exclusions to work and for recognizing duplicate commits, so they are passed along with every event and stored. The commit message is passed in full, because the ticket key and the AI tool trailer are read from it; at the same time it is text written freely by a person, so its content depends entirely on the team's practice.

The actual content of the files, that is the diff between code versions, is removed before sending and never leaves the plugin host.

Events from pull requests

The plugin recognizes pull and merge requests as a separate kind of event. It passes: title, full description, URL, identifier and number, target branch together with information about its protection, status, draft flag, list of commit identifiers included in the request, merge commit identifier, timestamps (opening, ready for review, first and last review, merge, close) and the list of reviewers with their e-mail addresses and review result.

Repository information

DirectionWhat is passed
Q247 → pluginGit server address, connector access data and the list of repositories to scan
Plugin → Q247repository name, URL, group name, synchronization and scan status together with the date

The access token to the repositories travels only in the first direction, together with the connector configuration. The plugin does not send the token to Q247. The exception is the Generic GIT connector, in which the credentials are part of the repository address and reach Q247 together with that address. If the connector uses an environment variable, the token does not pass even in that direction: only the variable name is stored in Q247.

AI tool telemetry

If the organization uses AI Tool Logs, the plugin passes daily summaries per user: the e-mail address identifying the person in the AI tool, the day, the tool name, the number of tokens broken down into input, output and cache, the cost, the number of generated and deleted lines, the number of commits and pull requests, the number of sessions and the active working time.

Prompts and model responses are not passed. Only counters are passed.

Retention results

Code persistence is calculated locally, by comparing the state of the repository after 1, 7, 30 and 90 days. The following reach Q247: commit identifier, the share of lines that survived at each of the four points, the number of added lines, whether the commit ended up on the main branch, the names of the branches used as the reference point, and the timestamp of the calculation.

Events from Jira and Confluence

The same mechanism, local content analysis and sending only the result, applies to Jira and Confluence, which the Enterprise Plugin handles through webhooks, not scanning:

Ticket information (Jira):

  • ticket key and type, URL,
  • assignee, together with their first name, last name and e-mail address, and the previous assignee,
  • status change history: the status name before and after the change, the category of each of them and the moment of the change, needed for Lead Time and Cycle Time,
  • calorie score,
  • number of inserted and deleted characters and the number of files in the change, without their content,
  • list of identifiers of the changed fields.

From the status history, Q247 builds a summary of the ticket's lifecycle, covering the moment of first entering work, the moment of completion, the number of returns and the time ranges assigned to particular people.

Page information (Confluence):

  • page identifier and space key, URL, and for a wiki also the page path,
  • author, together with e-mail address,
  • calorie score,
  • list of identifiers of the changed fields.

Diagnostic data and plugin version

Besides data about the work, the plugin passes information needed to maintain the integration: its version number with every connection, and error reports, containing the error message content, the repository address and the project identifier where the error occurred. These serve diagnostics on the Q247 side and do not contain the content of the analyzed data.

List of changed fields

The event carries information about which fields were changed, without their new values. The dictionary is closed and shared for Jira, Confluence and Azure DevOps:

IdentifierWhat it concerns
titletitle, corresponds to the summary field in Jira
descriptiondescription
bodycontent of the page or wiki document
messageversion comment, that is the comment on the change record
statusstatus change
assigneechange of the assigned person
commentadding or changing a comment
acceptanceCriteriaacceptance criteria
reproStepsreproduction steps
deleteddeletion

The dictionary is closed: a change to a field outside this list is not reported. The change content, stored locally for the purposes of the analysis, is removed before sending, so only the information that a given field was changed is passed.

Clarifying the scope of content

The content of tickets, pages and comments is not passed to Q247. There is, however, one exception.

Q247 recognizes the link between a Confluence page and a ticket by searching for its identifier in the page content, its title and the version comment. The recognized identifier is passed as metadata, so a fragment of the page content reaches the backend when it contains a reference to a ticket.

A value longer than 64 characters is skipped entirely, not truncated. The limit operates on the Q247 side, when moving the event to the analytics layer, so within the event itself the value is stored in the form in which it was recognized.

Webhook receiver authentication

The webhook receiver is authenticated with a separate, random API key generated for each organization and embedded in the webhook URL. A request with an unknown or incorrect key is rejected with an unauthorized response.

Because the secret is part of the address, the webhook address itself must be treated like a password: do not put it in tickets, internal documentation or chat channels.

Access to code repositories

Access to the source repositories is handled by the appropriate access tokens, with which the plugin connects to the repository. Only read access is required; the token must be configured that way on the SCM side.

The plugin reads all repositories it has access to (any restrictions are set in the SCM system itself or through the token's permission scope), and it also locally reads the increment history from these repositories.

See also

  • Connectors: what stays local at the Client and what reaches Q247, described from the administrator's perspective
  • Installation: Cloud Plugin versus Private Plugin