IP Restriction with White CIDR and Black CIDR

IP restrictionImagine this scenario. Your flagship product is doing OK; you’re getting downloads. Nevertheless, increasing sales is always a top priority, so you decide to create a free OSS version to boost usage and generate more awareness in the market. It’s also a great product, free to download, and is a great teaser for the upsell to your commercial version. So you upload the OSS version to your organization’s public repository on Bintray. After a while, you check its stats and are delighted to see thousands of downloads, and yet, there’s no buzz. If so many people are downloading your package, why is nobody talking about it? After checking your logs, you discover that most of those downloads you were so happy about are from the same set of IP addresses.

Someone is reverse-spamming you, and you need to block them.

Geo-Restriction could do the job, but then you don’t want to restrict whole countries at a time. You need something more targeted. Bintray’s new capability for IP restriction will do the job.

IP restriction is very similar to geo-restriction, only instead of defining your whitelist and blacklist as countries, you define them as a range of IP addresses using CIDRs. This gives you much more control letting you allow or block download at any level of granularity down to a single specific IP address. Whatever IP those bots are operating from can now be easily blocked so you can get the real download statistics you were interested in.

You can define your CIDR whitelist and blacklist through Bintray’s REST API or in the Edit Repository page.

IP restriction

Note that if there are any overlapping IPs, (i.e. IP addresses that are included in CIDRs that are in both the whitelist and the blacklist), then blacklisting them takes precedence. And if you accidentally list the exact same CIDR in both the whitelist AND the blacklist, Bintray will catch that and issue an error.

Ready to use IP restrictions? Get a quote for an enterprise account and ask for a free trial.

Automated EULA-protected Downloads

BINTRAY EULA280x215One of the great features of a Bintray Enterprise account is the ability to present a EULA when a user downloads one of your Products. That works well for the general case when the downloading user is a real person who can go through the Bintray UI and physically accept the EULA for publicly available content. This is something we discussed in a previous post. But what if you want to be more selective about who can download your content, and you want to limit it to a defined set of people? And what if those people want to download your content using automated scripts? And what if they don’t even have an account on Bintray? Those are a lot of hoops to jump through, but Bintray now offers a solution to this common circus of circumstances.

You can now offer automated EULA-protected downloads through the REST API to any pre-defined set of users, whether they have a Bintray account or not.

Here’s how it works.

  • You create an entitlement which gives access to your product and then you provide the corresponding access key to your user.
  • Your user browses to a specially constructed Bintray URL
  • Bintray displays a login screen where your user enters the access key as the username, and its password
  • Bintray then displays the EULA for your user to accept.

AcceptEULA

From now on, any REST API call that includes the access key you provided to your user will succeed unhindered by the EULA, since the EULA has already been accepted using that key. In other words – automated EULA-protected download. And who gets this privileged access? Not everyone. Only those who are privileged enough to receive the access key you created to protect your content. In other words private, automated EULA-protected download.

Protecting your products with a EULA has never been easier, whether you are offering something for public download, or whether you want to expose private content to a defined set of users.

 

 

Keep Your Secrets Safe by Serving Encrypted Files

encrypted_280x215aOnce you have uploaded your content into Bintray private repositories, it’s pretty safe through Bintray’s management of users, organizations, and teams. But what happens when you need to send a private file to someone else? Signed URLs give you an easy way to do that. Just generate your URL signing key and use the URL signing API call to create the URL. You can even make the URL valid for only a limited period of time. Now all you need to do is send the URL to the right person.

But what happens if the URL or the downloaded file gets into the wrong hands? Suddenly the file containing a license key/sensitive company information/anything-else-you-badly-wanted-to-keep-private is exposed..

Well, worry no more.  Bintray can now protect you from that kind of unwanted exposure.

On-the-fly file encryption

Bintray can now encrypt your file, on-the-fly, before it is downloaded through the signed URL. It works like this:

  • Upload your file (either manually through the website or using the REST API) into one of your private repositories.
  • Now you can generate the signed URL which will download the file.
    Nothing new yet, but here’s the thing.
    Now you can also attach a secret to the signed URL and tell Bintray to encrypt the file before it is downloaded. Bintray uses AES 256 CBC encryption for which you can provide your own secret key or ask Bintray to create one for you.
  • Now you can provide your customer with your secret through an alternative communications channel.
  • Once your customer has downloaded the file, they can use the secret key to decrypt the file using an OpenSSL command line. In other words, they need both the signed URL and the secret key.

Let’s See It In Action

Let’s assume we have a top secret “message.txt” file in a repo. We’ll use the REST API to create the signed URL:

curl -X POST -H "Content-Type: application/json" https://bintray.com/api/v1/signed_url/bintray/repo/message.txt?encrypt=true --data '{"valid_for_secs": 3600, "secret" : "my secret"}'

200 OK
{
"url": "https://dl.bintray.com/bintray/repo/message.txt?expiry=1461681694199&id=fHObRX27TU3EEpjQYIj9HFhbthU%2BPkkD4iXkRibKBYQvTFqlXP9tPUGlk5Xm3qE3&signature=nDt3t7Wj%2BP1B6chQ3AEt8iwaeowWuK66eQTP2tvgfa3AfmSAvR3IrPuVkP3tx90ihT2vMT9m1trJQ6IJZiVdSA%3D%3D"
}

If you don’t supply a secret, Bintray will create one for you and return it as an Http header: X-Bintray-Secret. Note that for that extra bit of security we limited the validity of the URL to 3600 seconds.

Your customer can now download the file from the returned URL:

curl -o message.txt "https://dl.bintray.com/bintray/repo/message.txt?expiry=1461681694199&id=fHObRX27TU3EEpjQYIj9HFhbthU%2BPkkD4iXkRibKBYQvTFqlXP9tPUGlk5Xm3qE3&signature=nDt3t7Wj%2BP1B6chQ3AEt8iwaeowWuK66eQTP2tvgfa3AfmSAvR3IrPuVkP3tx90ihT2vMT9m1trJQ6IJZiVdSA%3D%3D"

You can choose any secured way to send the user the secret. For example: phone or text message.

Now, to decrypt the file, your customer can use OpenSSL:

$ openssl enc -aes-256-cbc -d -in <encrypted file name> -out <decrypted file name output>

The tool will prompt your customer for the secret and then proceed to decrypt the file.

That’s how you keep your secrets safe. Enjoy!

 

 

 

 

 

 

6 Reasons to Distribute Commercial NuGet Packages through Bintray

Developing on .NET? Then, most likely, you are no stranger to NuGet Gallery. It’s a great place to find public NuGet packages. But is it the best place to host and distribute your own private packages? With the recent addition of native support for NuGet, you can now point your NuGet client to Bintray and transparently use it as your download source for NuGet packages. In this post, I’ll show how Bintray complements NuGet Gallery and the benefits it offers for the commercial distribution of private and public NuGet packages.

Privacy with fine-grained access control

With a professional account on Bintray, you can create private repositories and set up teams of users with different permissions according to the access you want to provide each team. Using keys and entitlements, you can provide external users who don’t have a Bintray account access at any level of granularity, from a whole repository down to a single artifact.

Metadata

On Bintray, every package is accompanied with a variety of metadata that can be used to search for and download packages. These include owner, open-source licenses used by the package, link to version control where the package’s sources can be found, even user-defined attributes and more.

Rapid downloads

Bintray is deployed on US, European, and Asian clusters and provides ultra-fast downloads over a rapid CDN (Akamai and Cloudfront).

Rich stats and logs

Rich stats provide detailed download information over any time period, and live logs provide detailed information about who is accessing your packages.

Integration with Artifactory

Bintray’s tight integration with Artifactory means that you can fully automate your .NET development pipeline from development to distribution.

A universal distribution hub

Bintray can serve your enterprise distribution needs for all package types. In addition to NuGet, Bintray also offers native level support for Docker, Debian, Maven, RPM, and Vagrant packages. This means that Bintray maintains metadata specific to these package types and can work transparently with the corresponding clients.

How does it work?

It’s pretty simple really.

First, create a repository and specify its type to be NuGet.

Create a NuGet repository

Now, all you need to do is point your NuGet client or Visual Studio at your new repository on Bintray. That’s just as easy, and Bintray even shows you how to do that. On your new repository page, just click Set Me Up. For the sake of readability, on this post, I’ll be using the NuGet client.

Set up a NuGet Repository

So, like the Set Me Up dialog shows us, to configure the NuGet client to work with Bintray, you need to add Bintray to the client’s list of sources:

nuget sources Add -Name Bintray -Source https://api.bintray.com/nuget/jaycroaker/MyNugetRepo -UserName <USERNAME> -Password <API KEY>

 

As you can see, you’ll need to include your Bintray username and API Key.

Then, you need to enable the use of your Bintray API key with the NuGet client:

nuget setapikey <USERNAME>:<APIKEY> -Source Bintray

 

Now you’re ready to deploy packages from the NuGet client directly to bintray. As an example, let’s say you want to upload a great logging utility you created called MyLogger (yes, I’m keeping things simple). Are you used to using nuget push? Well, nothing has changed:

nuget push MyLogger.1.0.0.0.nupkg -Source https://api.bintray.com/nuget/jaycroaker/MyNugetRepo

 

Now you should be able to see your package in your new NuGet repository, complete with the version you assigned.

Resolving NuGet package

And resolving the NuGet package from Bintray with the NuGet client is just as easy:

nuget install MyLogger -Source https://api.bintray.com/nuget/jaycroaker/MyNugetRepo

 

As you can see, once you have added Bintray as a source for your NuGet client, you can push and install transparently as if you were working with the NuGet Gallery. And since Bintray is a universal distribution hub, you can push to and pull from Bintray with the same ease when working with Docker, Debian, RPM, Maven, and Vagrant using the corresponding client for those package types. And with generic repositories on Bintray, you can host generic distributions such as installers or data files with the same ease of use. As we continue to add support for more and more package types, working with Bintray will just continue to get easier.

Catch that Millionth Download with Bintray’s New Statistics API

Want to know exactly how many times your packages have been downloaded? Bintray has always given you download statistics through its UI, but now you can also get them for professional repositories via REST API. Detailed statistics on downloads per version over any time frame give you deep insights into how your software releases are consumed.
If you have never used statistics in Bintray, go ahead and check it out in the user guide.

Let’s see an example
Say I want to get the daily number of downloads of ‘myCoolPackage’ from October 1st to October 8th, 2015. This is what the stats look like in the Bintray UI:

myCoolPackage Downloads UI Stats Per Week

According to the chart, ‘myCoolPackage’ was downloaded a total of 147,752 times in that period. We can clearly see that there were downloads every day; there were dips on October 4th (Sunday) and October 8th (the chart was generated on October 8th around midday), and the most popular versions were 1.1.0 and 1.2.0.

Now you can get all this information programmatically using the new REST API. Here’s the “daily downloads” API as it is described in the REST API documentation:

GET /packages/:subject/:repo/:package/stats/time_range_downloads

To get the statistics displayed in the chart above, I would use the following command:

curl -X GET "https://api.bintray.com/packages/tamarUser/Maven/myCoolPackage/stats/time_range_downloads" -u tamarUser:***my-top-secret-api-key*** -H "content-type:application/json" -d “{\"from\":\"2015-10-01T12:08:56.235z\",\"to\":\"2015-10-08T12:08:56.235z\"}"

I get the following response in JSON format:

{
  "from":"2015-10-01T00:00:00.000Z",
  "to":"2015-10-08T23:59:59.999Z",
  "records":[
      {"date":"2015-10-01","downloads":
        [{"version":"1.0.5","count":1939},
         {"version":"1.1.0","count":6950},
         {"version":"1.1.3","count":293},
         {"version":"1.1.7","count":116},
         {"version":"1.2.0","count":10111},
         {"version":"1.2.1","count":1329},
         {"version":"1.2.2","count":1706}]},
      {"date":"2015-10-02","downloads":
        [{"version":"1.0.5","count":315},
         {"version":"1.1.0","count":6975},
         {"version":"1.1.3","count":198},
         {"version":"1.1.7","count":121},
         {"version":"1.2.0","count":9967},
         {"version":"1.2.1","count":1290},
         {"version":"1.2.2","count":1759}]},
      {"date":"2015-10-03","downloads":
      ...]
}

The response provides all of the same data that Bintray uses to create the chart in the UI. For each day within the requested date range in which downloads occurred, it lists the number of downloads per version. As simple JSON output, you can easily parse the response and use it any way that helps you analyze your package downloads quickly and effectively. You are now able to identify trends in downloads, your popular versions and more.

Other statistics REST APIs include: total downloads and downloads by country. Keep an eye on this blog to hear about new APIs when we add them.

Good luck!

Publishing Your Maven Project to Bintray

Bintray gives you everything you need to share your Maven project, and much more: you will be able to monitor downloads and users with the statistics that Bintray keeps for you. You can also share your project via Bintray’s JCenter repository (which is the largest public Maven repository out there), and effortlessly sync it with Maven Central, if you wish.

Just follow these 5 simple steps to upload your Maven project to Bintray:

1. Have your Maven project ready

  • For this use case we will assume we have a maven project with the following groupId: org.jfrog.example.bintray.maven

2. Create a Maven package in Bintray

  • Open a Bintray account if you have not done so before.
  • Use the default Maven repository under your account or create a new one. The is where your Maven files will be hosted.

Create New Maven Repository

  • Under the Maven repository create a new package for your project. The package is merely a logical container that holds metadata about your project and annotates your files to allow Bintray to collect package and version level statistics.
    A good name for your package would be your main artifactId, but any name that logically identifies your project will do just as well.
    In our case, a good example would be: maven-example

3. Add the Bintray distribution URL

Next thing you need to do is to add a distribution section to your project’s pom.xml, and specify the URL from which to distribute your project. We will use our Bintray Maven repository and package as the target for deployment (remember? files in Bintray are always associated with a logical software package).

<distributionManagement>
  <repository>
      <id>bintray-repo-maven-example</id>
      <url>https://api.bintray.com/maven/tamarjfrog/maven-repo/maven-example/;publish=1</url>
  </repository>
</distributionManagement>

For your project to be visible to others, Bintray requires that you publish it. One way to do that is to add the publish directive to the distribution URL as a matrix parameter (;publish=1) as I did in the above example. You can also publish your projects at a later time using  the Bintray UI or via REST.

This block also includes an <id> tag. The id can be any string, but it should match the id in the settings.xml file described in the next step.

4. Provide your credentials to Bintray

In order to work with Bintray you need to provide your Bintray username and API Key as upload credentials in the username and password tags of your Maven settings.xml file. The API Key can be found when editing your Bintray profile page.

<server>
  <id>bintray-repo-maven-example</id>
  <username>tamarjfrog</username>
  <password>***my-top-secret-api-key***</password>
</server>

5. Time to deploy!

You are almost there. This is the time to run

mvn deploy

The project will be built, uploaded to the the Bintray repository target URL you provided, and published. You can now see your files in your Maven package in Bintray.

Maven Package Files List.
At this point, you can add your project to JCenter, the most comprehensive public Maven repository, so your project is well exposed. To read more about that, stay tuned for my next post.

A sample project similar to what I used in this post can be found in GitHub: bintray-examples/maven-examples.

Good Luck!

Enterprise Level Access Control with Keys and Entitlements

entitlements200x190

“Private repositories”, “Teams and Organizations”, “Permissions”…, sounds like that’s all you need to provide secure private downloads. Well, not quite. Those are great features that fit the bill if your consumer is a Bintray user. But what if she isn’t? Well, then there are signed URLs. Those should do the trick. Just sign your file and send your consumer the URL. But what if you want to share an entire repository, package or version with a group of people, but need to give each of them different privileges. Some can only view or download your files, but others should be able to delete your files or upload new ones. Signed URLs don’t cover that kind of control. They are great for single files, but for more fine-grained access control, you need a more sophisticated feature. That’s where entitlements and keys come in.

“Entitlements,” you said? What are those?

Entitlements are privileges you can give anyone…yes anyone, not only Bintray users, to entities in your private repositories. “Entities” means anything that can contain files – a whole repository, a path within the repository, a specific package or a specific version. “Privileges” means “rw”  – download, upload and delete, or “r” – download only. If you didn’t notice, the combination of entities and privileges gives you any level of granularity that you need for providing access.

But how do you unlock entitlements?

I guess you get the hint. Keys unlock entitlements. You generate a key along with its password (or Bintray can generate one for you automatically). Your user will have to provide the username and password to enable the key that unlocks the entitlement. That’s where the security lies. Only users who have both the username and the password of the key that you provide to them can access your repository entities according to the entitlements you created.

So how does it all work?

Two simple steps using Bintray’s REST API:

  1. Create keys. You can supply a password for each key you create, or Bintray can generate one for you.

  2. Create entitlements. When you create entitlements, you specify which keys to apply to them.

Now all you need to do is provide your user with the username and password for one of those keys. Your user now applies a REST API to access your private Bintray resource while including the key and password you provided as parameters to the API call. Bintray will check if there is an entitlement that allows access to that resource, and if that entitlement has the key that the user specified associated with it.

Let’s see an example at work

Let’s say user “ACMECorp” has a private repository called “acme”.

This private repo contains several versions of acprod under the “acmecorprod” directory that are protected from public access.

ACMECorp wants to authorize a “platinum customer” to download the different versions. Needless to say, “Ms. Platinum” does not have a Bintray account.

First, ACMECorp needs to create a key. Bintray offers two ways to maintain control over keys that are distributed to outside users. The easy way is to just put an expiry date on the key. A more advanced method is to set up an internal server that is used to validate and authenticate keys, and provide the server URL to Bintray when a key is created. Every time a user tries to access ACMECorp’s repositories, Bintray will validate the key using  the URL that ACMECorp provided when creating it. Since ACMECorp is very careful with its key, let’s assume they want to validate keys with their own systems:

curl -XPOST -uacmecorp:APIKEY “https://api.bintray.com/users/acmecorp/download_keys
{
“id”: “key1″,
“expiry”: 7956915742000
“existence_check”:{
      “url”: “http://callbacks.myci.org/username=:username,password=:password”,
      “cache_for_secs”: 60
      }
}

Bintray creates a key and its associated password

Status: 201 Created
{
"username": "key1@acmecorp",
"password": "8fdf84d2a814783f0fc2ce869b5e7f6ce9f286a0"
}

ACMECorp now creates an entitlement that provides download privileges to the acmecorprod directory, while assigning key1 that was just created

curl -XPOST -uacmecorp:APIKEY "https://api.bintray.com/packages/acmecorp/acme/acprod/entitlements
{
"access": "r",
"download_keys": ["key1"]
}

Bintray responds:

Status: 201 Created
{
"id": "7f8d57b16c1046e38062ea3db91838ff77758eca",
"access": "r",
"download_keys": ["key1"]
}

Basically, that’s it. ACMECorp can now just provide the username “key1@acmecorp” and its password to Ms. Platinum who can now use them to access the acmecorprod directory in ACMECorp’s repository.

For example, to download version 1.0 of acprod, Ms. Platinum would use:

curl -XGET “https://dl.bintray.com/acmecorp/acme/acmecorprod/1.0/acprod.exe” -ukey1@acmecorp -p”8fdf84d2a814783f0fc2ce869b5e7f6ce9f286a0”

But what happens now if ACMECorp and Ms. Platinum have a falling out. When that happens, ACMECorp can just delete the download key from their validation server and “Hey presto”, Ms. Platinum is now locked out of ACMECorp’s repositories.

Try doing that on Docker Hub, RubyGems.org, NuGet Gallery, Maven Central or any other repository or download center out there. Bintray is the only one that provides you with this level of control over access to your private resources.

Is Docker Hub really the best way to distribute your images?

Docker is definitely one of the biggest things to hit the software industry in the last few years. Everyone is using Docker, and Docker Hub is growing rapidly serving over 45,000 images by now. But did you ever ask yourself if Docker Hub is really the best platform to distribute your Docker images. It stands to reason, but reason be damned; We think Bintray has an edge over Docker Hub and here are the reasons why.

1. Fine-grained access control

Yes, Docker Hub recognizes organizations and teams. You can have all the relevant people open an account on Docker Hub and then organize them in whatever way serves your needs to expose or hide registries as you see fit.

But then you want to send your #1 strategic client an early release

How does Docker Hub handle that? Well, you can ask for your customer’s account, and then include him in the right organization or team. But then, you need to be really careful with what you put in the repository you have exposed to him. Or you need to add him to a team, and later remove him. Manageable so far… But now he also wants his boss to see it, and later the CTO, and two weeks later, you find that your guy has just changed jobs and is working for your competitor. Did you remember to remove him from that team or can he still access your private repository?

Bintray removes this pain-point with entitlements and download keys

Bintray lets you create entitlements which define, in minute detail, exactly what part of a repository can be accessed – from a whole repository down to the level of a single path within a repository. You can define who has access by name, geographic region, IP domain and pretty much anything else. You can also limit that access to a very specific period of time. Once you have defined your entitlements, you can then create keys which unlock the access the entitlements provide. Your user needs to provide the key and its associated password each time he accesses a resource which he is entitled to. You can even define what kind of access each entitlement provides. It can be for download only, or for download, upload and delete.

2. Image and Version Level Stats and Logs

Ever wondered how many times your image has been downloaded? Of course you have; it’s a measure of success. But going beyond self-flattery, it’s not enough to know that magic number of downloads. Wouldn’t it be helpful to be able to know who downloaded your images and from where? Bintray gives you that. The stats pages on Bintray give you total numbers, but download logs let you segment the downloads by region, country, IP address, and even down to the specific user and organization. For your public repositories this can be really useful, but for your private repositories it’s critical for you to know who is accessing your packages and what they are doing in your repositories. You can read more about stats and logs in this post the Bintray Blog.

3. There is more to the world than Docker

allforone4Docker may be the best container to have ever hit the software docks, but at the end of the day, you are only using Docker to create a virtual world in which to run your products. And your products are built with packages that are Java, Ruby, NuGet, Python, Debian … and new formats hit the news all the time. How are you going to distribute those? Not on Docker Hub. So should you use Docker Hub for Docker and something else for all the rest? Well, if you can use that something else, aka Bintray, for Docker images too, then why not simplify your life (and scripts) and distribute all packages through Bintray.

All for one and one download center for all.

3.5. For Bintray, distribution is a core competency

Docker is making huge waves in container technology. This is their core competency; not software distribution. You can use Docker Hub to distribute your images, but you must ask yourself, “Will Docker Hub receive the same level of attention from its makers as container technology does?” Bintray’s scalable infrastructure is deployed on clustered servers in multiple data centers around the world, and currently serves over 200 million downloads per month of 200 thousand packages that reside in 50 thousand repositories.

That’s what we call a core competency!

Like Docker Hub, Bintray offers a host of great features like fast CDN downloads, a rich REST API for automation, searchable metadata and more. But like Docker is redefining container technology, Bintray is redefining software distribution. The service tiers offered by Bintray make it the best choice for distribution of both free OSS images as well as for commercial organizations that need enterprise grade software distribution features. Bintray lives and breathes software distribution; that’s what it does, and that’s where it will continue to evolve to stay the best solution for a download center, for Docker images and indeed for all other software package formats.