Download stats and logs – now with deep user insights

Ever wondered who exactly downloaded your software? I don’t mean just “someone from the United States.” I’m talking about getting down to the organization level in terms of “someone from Acme Corp. NY office”.

Now you can get this information, from Bintray:
Bintray Live Download Feed

This information is available for any package type for Bintray Premium users, but that’s not all. It is also available, for free, for every OSS package in JCenter!!! This means that if you own a package that is linked to JCenter you already have this information available today!

And not only can you get rich live logs of your downloads, you can retrieve fully parsable logs in CSV or Apache common format! Just use the REST API, or click the preferred log format link:
Bintray Download Logs

Log format options include the Apache-style logs, which can be analyzed by dozens of tools out there, or you can download the logs as CSV files. CSV files are usually easier to understand, and actually contain more data, such as ZIP code, geolocation etc. Download the CSV log and hack on! Or, you can even open it in Excel and show it to your boss:
Bintray Logs in CSV Format
Excel jokes aside, that’s the most powerful downloads analytics one can get and it’s there at your fingertips.

With Live Logs and Download Logs you get much more detail about activity within your repositories. This can be very helpful in analyzing peaks as it provides immediate feedback on the popularity of your software, and how this popularity is distributed by version, geo-location and organization. Naturally, it can also be used to direct you to where you should be focusing your marketing efforts.

It’s time to learn about your users!

Another one bites the Maven Central dust (and saved by Bintray)

Today, I encountered another very detailed blog post on the woes of publishing on Maven Central. Jose Maria Arranz (@jmarranz) explains why he doesn’t like Maven in general and publishing to Maven Central in particular (I am with him on a lot of valid points).

I can’t help quoting:

Fortunately when searching for how-to articles and commenting in Twitter, @jbaruch an employee of JFrog contacts with me offering Bintray.com alternative to publish to Maven Central, the people behind JCenter, I read the article “The easy way to maven central” and I was sold. Bintray provides a GUI to upload and self sign your artifacts if you provides your public and private GnuPG keys, and with a simple UI action you are published in JCenter repository, and providing the Sontaype user and password you can finally easily publish in Maven Central.

Bintray helped me to break the wall of Sonatype process. I’m saved!!

Currently I’ve released RelProxy on JCenter and Maven Central. For releasing I use Ant calling to Maven tasks to generate the required Maven artifacts and to generate a distribution zip with everything. Everything could be automated, I could add signing and uploading from Ant (or maybe by the POM) without Bintray, but Bintray auto-signing and uploading UI is enough for me, releasing is done from time to time and most of releasing process is already automated, and releasing in JCenter is a plus.

Note: Don’t forget JCenter, for instance Maven Central is no longer pre-configured in Google Android environment.

That’s what I call “success”!

Thanks for the kind words, Jose Maria! I am happy that we managed to help :)

Android Studio – Migration from Maven Central to JCenter

This post was originally published in Techno Talkative blog by Paresh Mayani. Feel free to comment here or there.

 

During the android workshop, in the office and in the chat with some of the android developers, I have received some questions around build script and repository:

  • Why earlier versions of android studio were using maven central?
  • Why android project, getting created using android studio, is using jcenter?
  • What are the reasons/benefits/purpose that android studio has gone with JCenter repository?
  • JCenter Vs. Maven Central

I had shared some of the points at that time, but I tried to go into the deep to know more about the migration made from maven central to jcenter. I have found interesting details from the couple of links:

Before going ahead and we discuss about the migration made from maven central to jcenter, here is brief about the repository (in case if you really don’t know!)

What is repository?

In Maven terminology, a repository is a place i.e. directory where all the project jars, library jar, plugins or any other project specific artifacts are stored and can be used by Maven easily.

In build.gradle file, you need to specify which repository to use when resolving dependencies for building your project, so you need to put something like the following in your build.gradle file:

repositories {
    jcenter()
}    

Yes, you need to specify at least one repository before you use any external dependency. Read more about Dependency Management Basics and repositories.

Maven central to jcenter migration

Now, here are the details and interesting points about the jcenter and the transition made from maven central to jcenter:

  • As said earlier, jcenter is the new default repository used with Android’s gradle plugin.
  • jcenter is a Java repository in Bintray, which is the largest repo in the world for Java and Android OSS libraries, packages and components.
  • All the content in jcenter is served over a CDN, with a secure https connection. Back in the time of the migration (Android Studio 0.8) The central maven 2 repository was HTTP only and HTTPS wasn’t supported. Reference: 51.6.2. Maven central repository. (This might be one of the reasons as Google is a fan of HTTPs!).
  • jcenter() is a superset of mavenCentral(), that encompasses many additional repositories and artifacts. Reference: Blog @ Bintray.
  • The jcenter guys claim, that they have a better performance than maven central.
  • Bintray has a different approach to package identification than the legacy Maven Central.
  • If you really need to get your package to Maven Central (for supporting legacy tools) you can do it from Bintray as well, in a click of a button or even automatically.

Regarding performance improvements, couple of android developer advocates had faced/noticed the issue of huge indexing with maven central.

In the words of Tor Norbye:

I ran AndroidStudio with a brand new settings directory, so it went and connected maven central and downloaded an index of the available artifacts.

Then I happened to look at the size of my directory.

My ~/Library/Cache/AndroidStudioPreview is 1.5G, and 1.2G of those are taken by the “Maven” subdirectory.

That’s ridiculous. We barely use the index at all. The primary use for it is the Dependency editor in the Project Structure Dialog, but we really don’t need to have a precomputed index for it. MavenCentral has a fast online JSON search we can use on demand when somebody searches for artifacts. In https://android-review.googlesource.com/#/c/94843/ we added a lint check which checks whether the dependencies are up to date, and the search for a handful of artifacts is near instant.

In short, we really don’t need the cache; it may help with code completion in .gradle and maven .pom files, but that’s not a super important usecase, and certainly not something *all* users should have to sacrifice 1.5G of download speed and diskspace to have the possibility of one day doing.

Read more on: The Maven index is *huge*!

I must say, after this migration from maven cetnral to jcenter, performance of the android studio is noticeable. Earlier loading android studio in even 4GB RAM configuration laptop, was all like:

code-21

Any way, this is not the ending of this study here, I still want to know more about the improvements or strong points (if any). If you know or have played enough with jcenter and maven central, please share your inputs. And also, as this is almost an undocumented point, I am really looking forward to hear about this migration, from the android developers advocates or engineers working in android tools team.

Sign me up!

Bintray Premium gives you cool new features such as private repositories, permission management, more storage and so much more. One of the biggest benefits of using a Premium account is the ability to create expirable, signed URLs for your repositories’ content.

Signed URLs you said? What’s that?

A signed URL is an obscure URL with a (potentially) limited lifetime. When your artifacts are published in a private repository, each artifact is hidden from unauthorized Bintray users. If you want to allow any Bintray user, or even or a non-Bintray user to download your package, you can generate a one-time unique URL with an option to limit its validity so that is expires after a certain amount of time. You can also revoke any outstanding URLs at any time.

How does it work?

When you become a premium user in Bintray, your account holds unique, internal, private and public keys. The URL you decide to sign, will be encrypted and decrypted with those keys.

Let’s say user “srubin” has a private repository called “artifactory”.

This private repo contains a file, “artifactory.rar”, that protected from public access. Only authorized users can download it using the standard download link, which is:
https://dl.bintray.com/srubin/artifactory/com/jfrog/artifactorypro/artifactory.rar

Bintray Premium Link Signing

Bintray Premium Link Signing


To allow a one-off download of this file we will generate a signed URL for it using a simple REST call:

curl -XPOST -usrubin:APIKEY "https://api.bintray.com/signed_url/srubin/artifactory/com/jfrog/artifactorypro/artifactory.rar"

Response:

{
"url":"http://dl.bintray.com/srubin/artifactory/com/jfrog/artiafctorypro/artifactory.rar?expiry=1415101346415&signature=BfRaL2HDbCDsPyPThAnlI%2B0TG26NcH4i0ugyKZ%2FjevLiNfEdHXyUh0Q1NNGc1Pz7V1nZkeh9RAafrUyUE%2FMOFQ%3D%3D"
}

By default, this URL will be valid for 24 hours, but we can change that by specifying an expiry time in a simple JSON configuration document:

curl -XPOST -usrubin:APIKEY  -H "Content-Type: application/json"  -d "{\"expiry\":7956915742000}" https://api.bintray.com/signed_url/srubin/artifactory/com/jfrog/artiactorypro/artifactory.rar"

Response:

{
"url":"http://dl.bintray.com/srubin/artifactory/com/jfrog/artiactorypro/artifactory.rar?expiry=7956915742000&signature=g5OC3RXkFhnnFYfsgqFXw9J%2FfmwCzeIsd%2FHCRgm5VjCAhrzij1GPuAv0JwZPhGD0mEqs1y2WcQ77LMrDzp9%3D%3D"
}

More details about this API can be found in our documentation.

Summary

Signed, expirable URLs is a cool new feature of Bintray. It allows you to automate the generation of one-off download URLs and distribute them to any end user.

We will soon extend this feature to make it even cooler. Keep following to see what we have in store for you!

Feel secure with SSL? Think again.

Recently, we’ve heard a lot of discussion about the trust we place in public binary repositories. For example, Maven Central, a popular legacy repository maintained by Sonatype, was recently compromised by a successful MITM attack. In response, Sonatype set up an https access to central (removing the demand for a $10 donation to the Apache Foundation for using SSL). This has no impact on millions of maven installations in the world, which will continue access Maven Central via http unless manually reconfigured, but the interesting question is – is that enough?

While SSL is important in guaranteeing the integrity of downloaded files, it doesn’t say anything about the integrity of the files in the repository itself. The only(!) verification mechanism in the repository itself that Maven Central and other legacy repositories suggest you blindly trust, is the set of signature files uploaded with the files. Interestingly enough, modern repositories such as RubyGems.org, npm-registry and Bintray don’t force you to sign your files at all. Let’s try to understand why.

Here’s tl;dr if you need one.

Is SSL access enough for us to feel secure?

To answer this question, let’s consider Maven Central. This is a repository that works with SSL and “secures” the files with PGP signatures. In theory, these signature files strongly identify the signer (assuming that both the jar files and the signatures are served over SSL). But do they really?

Let’s see how it works:

  • The author uses a gpg tool to generate a keypair for identification.
  • The author then uploads the public key to a trusted key server (one of MIT, SKS OpenPGP Public Key Server or PGP Global Directory).
  • Anyone who wants to download a package and verify its integrity runs a signature check against one of the servers, and gets the unique and verified identity of the author.

Is it so?

Let’s run a couple of experiments, and see how securely the “secured” Maven Central is really maintained.

Here’s one of Sonatype’s latests jars: nexus-core-2.8.1-01.

Let’s download it see what’s the signature says, after importing the signer’s public key:

>gpg nexus-core-2.8.1-01.jar.asc
 gpg: Signature made 05/27/14 18:00:54 Central Daylight Time using DSA key ID 8DD1BDFD
 gpg: Good signature from "Sonatype, Inc. (Sonatype release key) <dev@sonatype.com>"
 gpg: WARNING: This key is not certified with a trusted signature!
 gpg:          There is no indication that the signature belongs to the owner.
 Primary key fingerprint: 2BCB DD0F 23EA 1CAF CC11  D486 0374 CF2E 8DD1 BDFD

Whoa! What happened?! “There is no indication that the signature belongs to the owner”?!

Wait a second. Does that mean that anyone can generate a keypair for Sonatype, Inc. “(Sonatype release key) <dev@sonatype.com>” pretending to be the Sonatype release team?

Here’s an amazing picture for you:

heinrichh@uni-duesseldorf.de

Click to see

Hiene writes code

 

According to the “trusted” key server, all those signatures belong to the German poet Heinrich Heine. Well, I would say that’s quite unlikely since he passed away quite some time ago1.

Let’s run a couple of more tests (go figure, maybe it’s only Sonatype who can’t generate a “truly trusted” signature):

Here’s a signed Eclipse artifact:

>gpg aether-1.0.0.v20140518-source-release.zip.asc
 gpg: Signature made 05/18/14 12:54:52 Central Daylight Time using DSA key ID A7FF4A41
 gpg: Good signature from "Benjamin Bentmann (CODE SIGNING KEY) <bentmann@apache.org>"
 gpg: WARNING: This key is not certified with a trusted signature!
 gpg:          There is no indication that the signature belongs to the owner.
 Primary key fingerprint: BA92 6F64 CA64 7B6D 853A  3867 2E20 10F8 A7FF 4A41

Same again!

Here’s Oracle’s OpenJDK tool:

>gpg jmh-core-0.9.5.jar.asc
 gpg: Signature made 07/24/14 13:53:36 Central Daylight Time using RSA key ID 060CF9FA
 gpg: Good signature from "Evgeny Mandrikov (CODE SIGNING KEY) <mandrikov@gmail.com>"
 gpg: WARNING: This key is not certified with a trusted signature!
 gpg:          There is no indication that the signature belongs to the owner.
 Primary key fingerprint: A413 F67D 71BE EC23 ADD0  CE0A CB43 338E 060C F9FA

Whoa, who’s Evgeny Mandrikov? An Oracle employee? Nope. Why does he use gmail? Let’s see, maybe Sonatype pre-verified him when they gave him access to Maven Central? Did he establish a relationship with Oracle or something? Nothing, not a single question. “I have nothing to do with Oracle, but still want to publish OpenJDK artifacts!” “OK, go ahead”. Can you trust him to provide you with authentic OpenJDK artifacts? Not sure2.

You get the picture. You can’t trust those self-generated key-pairs. And the Trusted Key Servers themselves acknowledge it! Here’s a quote from the Key Verification Policy of PGP Global Directory:

…there is always a risk that the verified key in the PGP Global Directory is not actually owned by the person who appears to own it. While the verification mechanisms in the directory are suitable for many purposes, you should endeavor to use additional mechanisms…

That’s exactly what modern repositories, like Bintray and GitHub do. But we’ll get to that shortly.

But what about WoT?

Ah,” one can say, “that’s because you don’t have a clue about how pgp signatures work! You need to establish a Web of Trust with the signer and voila, the message is gone!

While technically correct, this makes very little sense in our context.

WoT works for the original usage of pgp signatures – authenticating content from people that you know directly, or indirectly through your contacts. For example, it works great for signing emails. You are likely to get email from people in your first, second or third circle of connections, but almost never from complete strangers. With packages from an Internet repository, this concept breaks completely. Chances that a developer personally knows the creator of a package, even if its indirectly to one or two levels, are close to zero. Same works for the creators of a package. As an author, you have no idea who is going to use your package. You can only hope that they’ll be a bunch of strangers that you don’t know :-D.

I am intrigued. Show me how can I maliciously upload a forged artifact to Maven Central without even using MITM!

Tedious, but straight forward:

  1. Invent a fake identity (with a fake, but functional email address).
  2. Generate a keypair for it.
  3. Upload to a public key server (that’s where your email is needed).
  4. Follow the guide. The trickiest part is faking a story about your artifact to get your account set up in oss.sonatype.org through the Sonatype JIRA. Well, be creative!
  5. Within a couple of hours (or days) your artifact will get to Maven Central. If the description you invented  looks realistic enough, no questions will be asked. Somewhere during  the process of uploading and releasing files, Sonatype will check that the signatures with which you signed your artifacts match the email you used for your oss.sonatype.org account. But of course, they match.
  6. Mazal Tov! Your fake artifacts are now in Maven Central. From there they will be securely(!) downloaded over SSL to your victim computers by Maven.

Easy? Well, not really. Looks like the MITM attack was easier. But that’s what it takes to add a jar to Maven Central.
Doable? Absolutely.

But how is Bintray different?

Well, we realize that in the modern world, where identity theft is one of the more popular crimes, you can’t blindly trust an online identity. So, like many other services, we recommend that you assess how trustable any particular content is (a jar in our case), based on the credit the community gives to the Internet identity of the author.

Here’s what I mean:

Let’s say you want to download Groovy. Here it is. Let’s see how can you establish trust in Groovy binaries:

  • You can see the links to a website and GitHub.
  • You can see that this package belongs to an organization: Groovy. You can clearly see the list of members, and check each and every one of them.
  • Here’s Guillaume Laforge.
  • Check out his twitter account – almost 8.5K followers.
  • Here’s his blog, all around Groovy.
  • LinkedIn? Looks good.

So, can you trust him? Probably. He’s an admin of the Groovy organization, so his reputation is the guarantee that the organization and the files in it are authentic. You’re good to go. Or not?

That’s up to you! We give you the information. You decide if you can trust it or not.

 But Maven just goes out there and brings stuff!

To create a safe build you must use an in-house binary repository manager:

  1. Install it.
  2. Configure a “dirty” and a “clean” repository.
    1. The dirty repository should be able to proxy a remote source of artifacts that gives you a good insight on artifact producers’ identities (not just a pile of files with self-generated signatures).
      Consider proxying Bintray’s JCenter instead of Maven Central. JCenter is a superset of Maven Central, so finding packages won’t be a problem.
    2. The clean repository is a local repository with no Internet access.
  3. Configure your build tool (Maven?) to be able to build against either of them.
  4. Use a “sandbox” (e.g. a vm) to run a “dirty” build against the dirty repository. Its cache will be populated with all the artifacts needed for the build.
  5. Examine the identities of the publishers of those artifacts (remember to select a binary repository that can generate a list of dependencies used for every build) against the information you have about them (as you understood, it’d better be more than self-signed signatures).
  6. Promote the artifacts that you trust to the clean repository (remember to select a binary repository with deduplicated storage that gives you free and immediate “move” operations).
  7. Now you can safely build against the clean repository!

Here’s the summary (a.k.a. tl;dr):

  1. SSL is an important way to verify that the files you trust get safely from a server to your machine.
  2. Don’t let SSL give you a false sense of trust in the origin or author of the files.
  3. Don’t blindly trust self -issued signatures. One can generate a signature for any identity, sign any file with it and upload it to Maven Central.
  4. Go with a platform that enables and encourages web identity verification. Check the author and decide for yourself.
  5. Use a binary repository manager to discover and control the artifacts needed (and select it wisely).

1A gpg tool to work with pgp signatures was developed in Heinrich Heine University of Dusseldorf. In honor of the late poet after which the university was named, all defaults in the tool were initialized to Heinrich Heine, with the expectation that people would replace them their own details. Apparently, that didn’t work. People just enter-enter-enter through the settings generating dozens of key-pairs for the poor German, illustrating the absurdity of  “authentic”, self generated key-pairs.
Thank you, Heinrich!

2Actually, you can. Oracle do not distribute binaries of OpenJDK, and Evgeny volunteered, and was empowered by OpenJDK committers to do it for them.
But can you know without being personally familiar with Evgeny?! No, you can’t.