Signing git commits using Keybase
Signing git commits has been a great idea since forever. A great unpopular idea. Luckily, that changes with the recent Github announcement. This is a quick guide on how to set it up with your keybase.io account.
Keybase
Create keybase.io account
Keybase is still not publicly available, but you can ask me or anyone on Keybase for an invite.
Add a PGP key
After you create the account, you’ll have an option to either generate the key via the online interface or just add your already existing key. If you choose the former make sure to add at least one of the emails you have confirmed on your Github account. It will save you time later.
Add identities (optional)
The more of your online identities you add the more trustworthy your profile becomes. I suggest adding as many as possible, but you can also add them later and/or via the app or terminal client.
Track people (optional)
Tracking people makes their profiles more trustworthy, by providing an auditable authenticity proof of their identity. To understand more how it works, head here.
“But whom should I track?”, you might ask puzzled. And if you do, scroll down to the handy list that can get you started.
Keybase app
Keybase really shines only when you also utilize its command line interface. GUI app is still in works.
Install mac, linux & other.
# OSX
$ brew install keybase
# 64-bit Debian:
$ curl -O https://dist.keybase.io/linux/deb/keybase-latest-amd64.deb && \
sudo dpkg -i keybase-latest-amd64.deb
# Other
## All contributions welcome ;)
Login
$ keybase login
Follow the steps and make sure to save your paper wallet somewhere safe.
Keys
To make any of it possible you need your Keybase keys locally.
Public
To import your public key just run:
# replace with your username where appropriate
$ curl https://keybase.io/<your-username>/key.asc | gpg --import
Private
Now it’s time for the private key. Open your Keybase profile, and…
Confirm password, copy everything from the popup and save it as ex. keybase-private.key
.
Then:
$ gpg --allow-secret-key-import --import keybase-private.key
Git
Once you’re all set with your Keybase stuff, you need to teach your git how to crypto.
Get your key ID
Go to https://keybase.io/<your-username>
and copy 8 last characters of your key fingerprint from there.
Alternatively, run gpg --list-keys
, and locate your keybase key on the list there, ex:
$ gpg --list-keys
[…]
pub 4096R/A809CB18 2014-05-09
uid [ultimate] Damian Mee (https://meedamian.com) <mee.damian@gmail.com>
uid [ultimate] keybase.io/meedamian <meedamian@keybase.io>
sub 2048R/6560B337 2014-05-09 [expires: 2022-05-07]
sub 2048R/15276EF8 2014-05-09 [expires: 2022-05-07]
[…]
From there, copy your key ID (in the example above, it’s A809CB18
).
Add email to your key (optional)
If your key, for any reason¹, doesn’t have any overlapping email addresses with your Github account, this step is necessary.
¹ - Ex. you forgot to add it during key generation, or you have an old key that has <your-username>@keybase.io
as an email
First, run:
$ gpg --edit-key <your-username>@keybase.io
You’ll be presented with an interactive prompt, there:
- type
adduid
followed by enter, - provide your publicly recognizable name,
- input any of the email addresses you have on Github,
- a “Comment” field can hold your website address,
- press
o
(as in “okay”), followed by enter, - type
trust
, select5
and confirm withy
to grant ultimate trust to your identity, - Finally type
save
and confirm with enter.
Once you’re done, re-sync your key with Keybase, with:
# for newer keybase cli
$ keybase pgp select --multi
# for older keybase cli
$ keybase push --update
You might be asked to choose the key to be synced. Make sure to select the Keybase one.
When it finishes you might want to wait a short while, before proceeding to the next step.
Add public key to Github
Copy everything from https://keybase.io/<your-username>/key.asc
and paste it as a new “GPG key” in here.
Set git defaults
# Use `git commit -S` by default for all commits
$ git config --global commit.gpgsign true
# Set default key
$ git config --global user.signingkey <key-id>
Go on the committing spree
All you commit now should be automagically signed with your Keybase key. If everything went well, you should see a “Verified” badge by all your new commits on Github.
People worth stalking
koush | Brilliant Android engineer, who blocked his mom’s number | |
chris & max | They’re to blame for Keybase and OkCupid | |
vitalik | The founder of Ethereum | |
moot | All 4chan posts are by him | |
codinghorror | Has a cool blog and founded Stack Exchange | |
aikordek | Bitcoin & Startup girl | |
mpj | Shares great tweets and videos | |
authy | The 2FA app you should be using instead of Google Authenticator | |
robpike | Co-creator of Go | |
sindresorhus | The guy who wrote all npm packages | |
jakewharton | Cool Android dev | |
matthewdgreen | He knows a lot of security thingies | |
oleganza | Shares good UX and security content | |
meedamian | The original creator of this list |
KeyBase File System
This one is quite off-topic, but I think it’s amazing and worth including here. Keybase is working on a seamless, fully encrypted and synced /keybase/{public,private}/
folder. Make sure to check it out. If you need an invite hit me up.
Rapid Guide on Two-Way Data Binding in Android
This post is not a comprehensive introduction to data binding in Android, it’s a required minimum to get two-way data binding to work, that assumes your project to be configured for data binding already (if it’s not, start here).
Complete source code available here or here.
Structure:
role | file |
---|---|
Activity: | MainActivity.java |
Model: | not relevant here |
View: | activity_main.xml |
ViewModel: | MainState.java |
Activity
This one just glues stuff together:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding amb = DataBindingUtil.setContentView(this,
R.layout.activity_main);
final MainState ms = new MainState();
amb.setState(ms);
// Enable interface only after 2s for some reason
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
ms.fieldsEnabled.set(true);
}
}, 2000);
}
}
View
Simple UI, with two EditText
s and one CheckBox
:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="state"
type="com.meedamian.twoWayBinding.MainState" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<!-- Basic example -->
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Basic Field"
android:text="@{state.basic}"
android:enabled="@{state.fieldsEnabled}"
android:addTextChangedListener="@{state.onBasicChanged}" />
<!-- Basic + do sth on blur -->
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Blurable Field"
android:text="@{state.blurable}"
android:enabled="@{state.fieldsEnabled}"
android:addTextChangedListener="@{state.onBlurableChanged}"
android:onFocusChange="@{state.onBlurableFocusChange}" />
<!-- Toggles UI availability -->
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Toggle interface"
android:checked="@{state.fieldsEnabled}"
android:onClick="@{state.onCheckedChanged}" />
</LinearLayout>
</layout>
State
I hope the code speaks better than any comment I could put here, but if you have any doubts, ask in comments below.
public class MainState extends BaseObservable {
public final ObservableBoolean fieldsEnabled = new ObservableBoolean();
// Basic EditText boilerplate
private String basic;
@Bindable
public String getBasic() {
return basic;
}
private void setBasicAtomic(String basic) {
this.basic = basic;
}
public void setBasic(String basic) {
setBasicAtomic(basic);
notifyPropertyChanged(BR.basic);
}
public TextWatcher onBasicChanged = new SimpleTextWatcher() {
@Override
public void onTextChanged(String newBasic) {
setBasicAtomic(newBasic);
}
};
// Blurable EditText Boilerplate
private String blurable;
@Bindable
public String getBlurable() {
return blurable;
}
private void setBlurableAtomic(String blurable) {
this.blurable = blurable;
}
public void setBlurable(String blurable) {
setBlurableAtomic(blurable);
notifyPropertyChanged(BR.blurable);
}
public TextWatcher onBlurableChanged = new SimpleTextWatcher() {
@Override
public void onTextChanged(String newBlurable) {
setBlurableAtomic(newBlurable);
}
};
public void onBlurableFocusChange(View v, boolean hasFocus) {
if (!hasFocus)
Toast.makeText(v.getContext(), "Field blurred", Toast.LENGTH_SHORT).show();
}
// CheckBox change listener
public void onCheckedChanged(View v) {
fieldsEnabled.set(((CheckBox) v).isChecked());
}
}
Complete source code available here or here.
Unlocalize Google Chrome Omnibar
If you travel a lot or use a VPN, then at some point, Google might start to, wrongfully, think that you’d rather use some outdated local domain.
Steps to fix it:
- Go to
chrome://settings/searchEngines
(copy-paste it into your address bar) - In the
Default search settings
section find “Google”- Rename
Google
to ex.Google (Annoying)
in the 1st field - Change
google.com
to ex.Google.annoying
in the 2nd field - Copy URL¹ from the 3rd field
- Rename
- Scroll to the bottom of the
Other search engines
section - Add a new search engine:
- Put
Google
into the 1st field - Put
google.com
into the 2nd field - Paste the ¹URL from your clipboard into the 3rd field
- In the pasted URL replace
{google:baseURL}
withhttps://google.com/
- Put
- Set this search engine as a default
- Close & Enjoy
Redirect examples:
Thailand | Taiwan |
---|---|
![]() |
![]() |
China |
---|
![]() |