Skip to content

Commit 42cd560

Browse files
committed
refactor(resolver): remove unused trustedAccountMappings extension point
- Remove speculative trustedAccountMappings plumbing from identity resolver and orchestrator - Keep noreply commit authors strictly unresolved for award recipients while preserving DCO attribution - Update noreply tests to verify unresolvable recipient without dead mapping code Signed-off-by: Parth Gartan <parthgartan26feb@gmail.com>
1 parent 976862f commit 42cd560

3 files changed

Lines changed: 9 additions & 59 deletions

File tree

‎utils/award-orchestrator.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,9 @@ function getSanitizedReport(internalResult) {
265265
* @param {Object} options.prMetadata PR metadata object or file content
266266
* @param {Array<string|{name: string}>} [options.existingLabels] Existing labels on PR
267267
* @param {string} [options.repoOverride] Explicit repository override
268-
* @param {Object|Map|Function} [options.trustedAccountMappings] Trusted account mappings for noreply authors
269268
* @returns {Object} Structured evaluation result
270269
*/
271-
function orchestrateAwards({ prMetadata = {}, existingLabels = [], repoOverride = '', trustedAccountMappings = null }) {
270+
function orchestrateAwards({ prMetadata = {}, existingLabels = [], repoOverride = '' }) {
272271
// Extract repository
273272
const repo = (
274273
repoOverride ||
@@ -350,7 +349,7 @@ function orchestrateAwards({ prMetadata = {}, existingLabels = [], repoOverride
350349
});
351350

352351
// Resolve identity and DCO strictly to PR author
353-
const identity = resolveIdentity(prAuthor, dedupedCommits, { trustedAccountMappings });
352+
const identity = resolveIdentity(prAuthor, dedupedCommits);
354353
const maskedRecipientEmail = maskEmail(identity.resolvedEmail);
355354

356355
// Extract existing tracking labels with deduplication

‎utils/identity-resolver.js‎

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -98,29 +98,6 @@ function isTrailerAttributableToAuthor(trailer, gitAuthor) {
9898
return false;
9999
}
100100

101-
function getTrustedRecipientEmail(prAuthor, options) {
102-
if (!options || !prAuthor) return null;
103-
const mappings = options.trustedAccountMappings || (
104-
typeof options.get === 'function' || typeof options === 'function' || (typeof options === 'object' && !options.prMetadata) ? options : null
105-
);
106-
if (!mappings) return null;
107-
108-
const normalized = prAuthor.trim().toLowerCase();
109-
let val = null;
110-
if (typeof mappings.get === 'function') {
111-
val = mappings.get(normalized) || mappings.get(prAuthor);
112-
} else if (typeof mappings === 'function') {
113-
val = mappings(normalized) || mappings(prAuthor);
114-
} else if (typeof mappings === 'object') {
115-
val = mappings[normalized] || mappings[prAuthor];
116-
}
117-
118-
if (val && typeof val === 'string' && isValidEmail(val)) {
119-
return val.trim().toLowerCase();
120-
}
121-
return null;
122-
}
123-
124101
/**
125102
* Resolves contributor identity and strictly verifies DCO compliance against commit history.
126103
*
@@ -134,18 +111,16 @@ function getTrustedRecipientEmail(prAuthor, options) {
134111
* When a commit author uses a GitHub noreply email (@users.noreply.github.com),
135112
* a real recipient email is NEVER resolved solely from matching contributor-controlled names.
136113
* Exact noreply DCO attribution is preserved (dcoVerified: true), but resolvedEmail
137-
* remains null unless an authoritative trustedAccountMapping is provided.
114+
* remains null.
138115
*
139116
* Privacy Invariant:
140117
* The returned reason string NEVER contains plaintext contributor email addresses.
141118
*
142119
* @param {string} prAuthor PR author's GitHub login handle
143120
* @param {Array<Object>} commits List of commit objects (from GitHub API pulls/commits)
144-
* @param {Object} [options] Optional configuration or trusted mappings
145-
* @param {Object|Map|Function} [options.trustedAccountMappings] Trusted account mapping from login to verified email
146121
* @returns {{ resolvedEmail: string|null, dcoVerified: boolean, reason: string }}
147122
*/
148-
function resolveIdentity(prAuthor, commits, options = {}) {
123+
function resolveIdentity(prAuthor, commits) {
149124
if (!prAuthor || typeof prAuthor !== 'string') {
150125
return {
151126
resolvedEmail: null,
@@ -239,21 +214,12 @@ function resolveIdentity(prAuthor, commits, options = {}) {
239214
}
240215

241216
const verifiedEmail = distinctEmails[0];
242-
const trustedEmail = getTrustedRecipientEmail(prAuthor, options);
243217

244218
// If the commit author used a GitHub noreply address (@users.noreply.github.com),
245219
// never resolve a real recipient email solely from contributor-controlled names.
246220
// Exact noreply DCO attribution is preserved (dcoVerified: true), but recipient
247-
// remains unresolved (resolvedEmail: null) unless a trusted account mapping exists.
221+
// remains unresolved (resolvedEmail: null).
248222
if (hasNoreplyAuthor || verifiedEmail.endsWith('@users.noreply.github.com')) {
249-
if (trustedEmail) {
250-
return {
251-
resolvedEmail: trustedEmail,
252-
dcoVerified: true,
253-
reason: `Verified ${authorCommits.length} commit(s) by @${prAuthor} with DCO Signed-off-by trailer; recipient resolved via trusted account mapping`
254-
};
255-
}
256-
257223
if (verifiedEmail.endsWith('@users.noreply.github.com')) {
258224
return {
259225
resolvedEmail: null,
@@ -265,7 +231,7 @@ function resolveIdentity(prAuthor, commits, options = {}) {
265231
return {
266232
resolvedEmail: null,
267233
dcoVerified: true,
268-
reason: `Verified ${authorCommits.length} commit(s) by @${prAuthor} with DCO Signed-off-by trailer, but commit author uses a GitHub noreply address (@users.noreply.github.com); recipient cannot be resolved from contributor-controlled name without a trusted account mapping`
234+
reason: `Verified ${authorCommits.length} commit(s) by @${prAuthor} with DCO Signed-off-by trailer, but commit author uses a GitHub noreply address (@users.noreply.github.com); recipient cannot be resolved from contributor-controlled names`
269235
};
270236
}
271237

‎utils/identity-resolver.test.js‎

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ test('resolveIdentity: normal author + matching sign-off', () => {
144144
assert.equal(result.resolvedEmail, 'lee@layer5.io');
145145
});
146146

147-
test('resolveIdentity: GitHub noreply commit author with matching trailer name preserves DCO but keeps recipient unresolved without trusted mapping', () => {
147+
test('resolveIdentity: GitHub noreply commit author with matching trailer name preserves DCO but keeps recipient unresolved', () => {
148148
const commits = [
149149
{
150150
sha: 'noreply12345678',
@@ -156,18 +156,10 @@ test('resolveIdentity: GitHub noreply commit author with matching trailer name p
156156
}
157157
];
158158

159-
// Without trusted account mapping: DCO is verified, but recipient cannot be resolved from contributor-controlled names
160159
const result = resolveIdentity('octocat', commits);
161160
assert.equal(result.dcoVerified, true, 'DCO attribution is preserved for matching trailer name');
162161
assert.equal(result.resolvedEmail, null, 'Must never resolve recipient email solely from matching contributor-controlled name on noreply author');
163-
assert.ok(result.reason.includes('cannot be resolved from contributor-controlled name without a trusted account mapping'));
164-
165-
// With trusted account mapping: recipient resolves to the authoritative mapped email
166-
const mappedResult = resolveIdentity('octocat', commits, {
167-
trustedAccountMappings: { octocat: 'trusted-octocat@example.com' }
168-
});
169-
assert.equal(mappedResult.dcoVerified, true);
170-
assert.equal(mappedResult.resolvedEmail, 'trusted-octocat@example.com');
162+
assert.ok(result.reason.includes('cannot be resolved from contributor-controlled names'));
171163
});
172164

173165
test('resolveIdentity: spoofing regression - attacker using noreply author cannot claim victim email via matching trailer name', () => {
@@ -187,15 +179,8 @@ test('resolveIdentity: spoofing regression - attacker using noreply author canno
187179
const result = resolveIdentity('attacker', commits);
188180
assert.equal(result.resolvedEmail, null, 'Must never resolve spoofed victim email from noreply commit author');
189181
assert.equal(result.dcoVerified, true, 'DCO trailer name match preserves DCO attribution');
190-
assert.ok(result.reason.includes('cannot be resolved from contributor-controlled name without a trusted account mapping'));
182+
assert.ok(result.reason.includes('cannot be resolved from contributor-controlled names'));
191183
assert.equal(result.reason.includes(victimEmail), false, 'Reason must not leak victim email');
192-
193-
// Even with attacker account mapping, recipient resolves to attacker trusted email, NEVER the spoofed victim email
194-
const mappedResult = resolveIdentity('attacker', commits, {
195-
trustedAccountMappings: { attacker: 'attacker-verified@domain.com' }
196-
});
197-
assert.equal(mappedResult.resolvedEmail, 'attacker-verified@domain.com');
198-
assert.notEqual(mappedResult.resolvedEmail, victimEmail);
199184
});
200185

201186
test('resolveIdentity: GitHub noreply commit author who signs off with noreply address (CASE B)', () => {

0 commit comments

Comments
 (0)