question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support S3 provider with AWS request signing in auto-updater

See original GitHub issue
  • Version: 22.3.2
  • electron-updater: 4.2.0
  • Target: macOS and Windows

First of all, thanks a ton for making electron-builder. Much appreciated!

The issue I came across is with using non-public AWS S3 bucket for releases. The scenario is as follows:

  1. Create a non-public AWS S3 bucket for releases.
  2. Create IAM credentials and policies around that bucket to only allow read access via signed requests to AWS S3.
  3. Embed read-access credentials in the Electron app and use them to sign requests: example.
  4. Upload a release via electron-builder using other credentials with write permissions to the bucket.
  5. Upload newer release.
  6. Run Electron app with auto-updater enabled. It correctly identifies there is a newer version, however it falls back to full release download, since it cannot access release blockmap (403: Forbidden). This happens because there is no way of properly signing fetch request for blockmap – the S3 provider reuses headers set it checking-for-update/download-update handler.

To resolve this issue, the S3 provider would have to optionally allow signing each outgoing request to S3 (checking for update, downloading blockmap, downloading full release as fallback) or, least invasive, allow setting request headers per each request, including the one for blockmap.

I might be missing something, so feel free to correct me if there is already a solution to this issue. In any case, any hopes of having this implemented in the near future?

Alternatively, any tips on how to contribute this feature to the project? Where would I have to start?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:16 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
mmaiettacommented, Mar 12, 2021

Hiya, new maintainer here. 🙂
I’m happy to review. I like the idea, I just don’t have a way to test it on my own…

I saw in your PR that you have MacUpdater and NsisUpdater duplicate logic, and AppImageUpdater isn’t covered. It seems like we could condense the logic to within AppUpdater.


It looks like everything is piped through here: https://github.com/electron-userland/electron-builder/blob/8df250b4645924942883ba6ad1418da994116521/packages/electron-updater/src/AppUpdater.ts#L429-L433

The headers passed into doDownloadUpdate are generated in https://github.com/electron-userland/electron-builder/blob/8df250b4645924942883ba6ad1418da994116521/packages/electron-updater/src/AppUpdater.ts#L470

A potential route to go is to extract fileInfo out of doDownloadUpdate, then you can generate the headers from within AppUpdater since the provider is present Every doDownloadUpdate has this line anyhow with only the extension changing (‘AppImage’ in this case) https://github.com/electron-userland/electron-builder/blob/8df250b4645924942883ba6ad1418da994116521/packages/electron-updater/src/AppImageUpdater.ts#L33 updateInfoAndProvider isn’t used much either, just for the version and resolving the file. Thus we can extract those to the AppUpdater too so that the request headers become simple when integrating your createRequestOptions approach

private computeRequestHeaders(url: URL, provider: Provider<any>): OutgoingHttpHeaders {
    const fileExtraDownloadHeaders = provider.fileExtraDownloadHeaders
    const headers = fileExtraDownloadHeaders ? {
    	...fileExtraDownloadHeaders,
    	...this.requestHeaders
    } : this.computeFinalHeaders({ accept: "*/*" })
    return provider.createRequestOptions(url, headers)
}

And eventually, we could get to something like this:

const { provider, info } = updateInfoAndProvider
const fileInfo = findFile(provider.resolveFiles(info), this.anAbstractPropertyForExpectedArtifactExtension)!!
return this.doDownloadUpdate({
	fileInfo,
	version: info.version
	requestHeaders: this.computeRequestHeaders(fileInfo.url, provider),
	cancellationToken,
})

I don’t have a way to test that though

2reactions
christarnowskicommented, Jul 13, 2020

@Nightbr I finally found some time to prepare a PR addressing this issue. It’s still rough and will probably require more work to meet the standards for EB, but we’re using the code in production with good results. Try it yourself: #5138.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Signing and authenticating REST requests
This topic explains authenticating requests using Signature Version 2. Amazon S3 now supports the latest Signature Version 4. This latest signature version ...
Read more >
Automatic updates in Electron using Amazon S3 - Brainio Blog
It works with the electron-builder package and uses Amazon S3 as an auto update server. The post also shows how to code sign...
Read more >
Publish - electron-builder
The publish key contains a set of options instructing electron-builder on how it should publish artifacts and build update info files for auto...
Read more >
Configure the Amazon AWS Config service to auto-update the ...
Events that are not associated to a service account are visible to all domains. Procedure. Log in to your AWS account. On the...
Read more >
QRadar: Amazon AWS protocols temporarily removed ... - IBM
IBM temporarily removed the Amazon Web Services and Amazon AWS S3 REST API ... issue that can occur during the auto update of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found