Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canary Interface ERC #801

Merged
merged 3 commits into from Jan 2, 2018

Conversation

@ligi
Copy link
Member

ligi commented Dec 17, 2017

The canary can e.g. be used as a warrant canary.
A standard interface allows other applications to easily interface with canaries on Ethereum - e.g. for visualizing the state, automated alarms, apps to feed the canary or contracts (e.g. insurance) that use the data.

Solves the following problems with current (warrant) canaries:

In addition to a digital signature, it provides a recent news headline as proof that the warrant canary was recently posted as well as mirroring the posting internationally.

Source: https://en.wikipedia.org/wiki/Warrant_canary

Signing a news headline is more work and less secure than using Ethereum for this task. The effort it takes to sign a news headline also leads to organisations not going this route at all and e.g. just adding a signal to twitter or some other site - which is way less secure and brittle.

the fact that canaries are non-standard makes it difficult to automatically monitor them for changes or takedowns

Source: Quintin, Cooper (25 May 2016). "Canary Watch – One Year Later". Electronic Frontier Foundation. https://www.eff.org/deeplinks/2016/05/canary-watch-one-year-later

ERC-801 could be the standard to solve this problem

in the same post:

Yet, in our time working with Canary Watch we have seen many canaries go away and come back, fail to be updated, or disappear altogether along with the website that was hosting it.

The immutability of Ethereum can also help here.
As far as I see a lot of problems that are outlined in the post could be solved by leveraging Ethereum for this use-case - this gives me hope that it could even bring back https://canarywatch.org or lead to a similar service as there is no more need for an authority like the EFF to do the otherwise difficult task of interpreting the canary state.

Makes it also possible to keep the canaries alive with hardware wallets and improve security this way.

@ligi ligi force-pushed the ligi:add_canry_erc branch 3 times, most recently from 1fb11c3 to 6f89c92 Dec 17, 2017
@ligi ligi changed the title Introduce (warrant) Canary Interface ERC (warrant) Canary Interface ERC Dec 17, 2017
@ligi ligi force-pushed the ligi:add_canry_erc branch 3 times, most recently from 8021dae to bd4185f Dec 17, 2017
@ligi ligi force-pushed the ligi:add_canry_erc branch from bd4185f to 49cfee1 Dec 17, 2017
@ligi ligi changed the title (warrant) Canary Interface ERC Canary Interface ERC Dec 17, 2017
@AtLeastSignificant

This comment has been minimized.

Copy link

AtLeastSignificant commented Dec 17, 2017

I think there should be a uint256 "lifespan" variable rather than the TTL implementation, defined as a block number. If the lifespan block number is less than or equal to the current block number, the canary is dead.

feed() would take a duration parameter that is added to the current lifespan.

addFeeder() should have additional parameter maxLife that functions as a cap to the amount feeder's can add to the lifespan.

Valuable effects would include:

• large enough negative values to feed() potentially replace poison(), and other (smaller) negative values allow for reducing canary lifespan without killing it (useful if the canary user knows there is an impending warrant and wants to provide notice sooner, but is unable to update it themselves to immediately kill the canary)

• allowing feeders to extend lifespan by varying amounts (useful for when somebody knows they will be unable to feed for a period of time greater than the TTL, but doesn't expect a warrant to be served in the mean time)

• disallowing certain feeders from being able to increase the lifespan (kill only if maxLife is a large enough negative value assigned to a certain feeder, one reason why lifespan should be defined as a block numer)

@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Dec 17, 2017

Thanks for the feedback! Like the ideas and will most likely change the proposal to address most of them - just not sure about timespan per feeder yet - have to think about this a bit. But am glad I did not yet implement as otherwise I would have to throw away code to fit the new API

@veox

This comment has been minimized.

Copy link
Contributor

veox commented Dec 18, 2017

I would urge not to include a permission management interface (the feeder methods), and if including then certainly not optionally.

Consider a Canary whose only feeder account has been compromised. If it is possible to transfer its permissions to another account, that is in full control of the attacker; then revoking or destroying the initial compromised feeder (disbanding a multisig, deleting a proxy contract, whatever other additional means might have been used) would do nothing for the Canary. It can still be fed by an attacker.

Including an interface is proposing people use it; and suggesting that it is sufficient.

Making an interface optional for concrete implementations - or for people to use - is asking for a systemic edge case, where interpretation of the result isn't binary.

Copy link
Member

pirapira left a comment

I think some of the ambiguity can be left open, but it's better to do so explicitly, like,

"implementations can choose the authentication method of this function freely."


EIP: 801
Title: ERC-801 Canary Standard
Author: ligi<ligi@ligi.de>

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

A space before < would look more normal.


#### isAlive()

Returns if the canary was feed properly to signal e.g. that no warrant was received.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Grammar: I think it should be the canary was fed. I'm not a native speaker and so might be mistaken.

#### timeToLive()
The time in seconds that can elapse between feed() calls without starving the canary dead.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Is an implementation allowed to change the return value of timeToLive() from time to time? Or is that intentionally left open?

#### feed()
Extend the life of the canary by timeToLive() seconds.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

I guess not anyone is allowed to do this, so, something like: "throws when the caller is not one of the feeders."

Extend the life of the canary by timeToLive() seconds.
**NOTE**: this should trigger the event listed below

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Is it the case, even when needsAllFeeders() is true, each time feed() is called, the event should fire?

``` js
function poison()
```

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

I think Poisoned() is an interesting event to watch.

#### (optional) addFeeder(address feeder)
Add address that is allowed to feed (and therefore also poison) the canary.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Who can successfully call this method?

#### (optional) removeFeeder(address feeder)
Remove address that is allowed to feed the canary.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Who can successfully call this method?

``` js
event Feed(address feeder)
```

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 18, 2017

Member

Maybe there should be an event for new/deleted feeders.

@AtLeastSignificant

This comment has been minimized.

Copy link

AtLeastSignificant commented Dec 18, 2017

I agree with Yoichi that this contract doesn't need to have super tight security measures since there's little at risk in terms of user's funds or service infrastructure. Those measures can certainly be optional.

It's when you want to give limited abilities (kill only), or have tighter control over the lifespan of the canary (reduce time until it expires, extend the time in varying amounts), that adding additional feeders becomes useful.

The worst-case scenario should be that the canary contract owner PK is compromised, and the owner must redeploy another contract and push some updates to their website or other platforms that display info on the canary to make the original one irrelevant. I don't think this would cause significant harm if it were to happen.

I don't think it's the contract's responsibility to protect the owner's private key. That should be assumed.

@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Dec 19, 2017

@pirapira thanks so much for the comments - will adapt them soon

@pirapira

This comment has been minimized.

Copy link
Member

pirapira commented Dec 19, 2017

@ligi my pleasure. Since the feeder itself can be an Ethereum contract, maybe it's possible to avoid specifying authentications. They can be implemented in feeder contracts.

@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Dec 19, 2017

@pirapira Was also thinking yesterday there is already too much implementation detail in here and split things up. And already a lot of new ideas came up in the comments here. So I was thinking what really defines the Canary? And in the end it might be just:

isAlive()

and maybe:

getBlockOfDeath()

Then other ERC might specify different types of canaries (getType()?) - like SimpleCanary, MultipleFeedersCanary, AutomaticContractTriggerCanary, NegativeFoodCanary, ..

@ligi ligi force-pushed the ligi:add_canry_erc branch 4 times, most recently from c36de76 to 46b7dcc Dec 19, 2017
@ligi ligi force-pushed the ligi:add_canry_erc branch from 46b7dcc to 37cfc31 Dec 19, 2017
@veox

This comment has been minimized.

Copy link
Contributor

veox commented Dec 20, 2017

Guess my thoughts match with the previous two comments, except arriving at a similar conclusion by different path.

Below tangent to the PR; sorry.


The worst-case scenario should be that the canary contract owner PK is compromised, and the owner must redeploy another contract and push some updates to their website or other platforms that display info on the canary to make the original one irrelevant. I don't think this would cause significant harm if it were to happen.

I beg to differ!

If we consider "push some updates to their website" as a valid escape from a "feeder PKs compromised" scenario, then the purpose of using a blockchain is moot.

From summary:

A standard interface allows other applications to easily interface with canaries on Ethereum - e.g. for visualizing the state, automated alarms, apps to feed the canary or contracts (e.g. insurance) that use the data.

My concern is not for a human being browsing a website (even an IPFS/Swarm one), where an update can be pushed without warning.

My concern is for an automated agent, for whom the canary may be the only source of truth.

The only acceptable outcome on "feeder PK compromise" - or any other failure that is likely to lead to disaster - should be death of the original canary. It must not be allowed to linger!

This brings in the question of how exactly was the key compromised - and there are many scenarios for this one. My first comment briefly describes one where, even if the original feeder's keys are destroyed, the canary stays alive.

This is made possible by including an interface that's not essential for the basic purpose of the contract. It might as well be implemented elsewhere (and I argued that it should).

Which brings up the second point:

I agree with Yoichi that this contract doesn't need to have super tight security measures since there's little at risk in terms of user's funds or service infrastructure. Those measures can certainly be optional.

Let's not assume a particular use, e.g. "I haven't been served a subpoena".

For example, EAC used a canary to indicate service availability. So, although the canaries themselves did not hold funds for anyone but the service operator, it was certainly not safe to use the service if the canary was dead.

In short: when speaking of the canary's security, it is not (only) the canary itself that is being protected, but (also) what the canary represents.

Copy link
Member

pirapira left a comment

Please move the file to EIPS/eip-801.md.

* `5` = Multiple mandatory feeders (as defined in ERC-TBD)
* `6` = IOT (as defined in ERC-TBD)
`1` might also be used for a special purpose contract that does not need a special type but still want to expose the functions and provide events as defined in this ERC.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 21, 2017

Member

still want to->still wants to.

#### RIP
MUST trigger when the canary died.

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 21, 2017

Member

I don't think this is implementable. When the canary contract is never called, it cannot produce events, even though the canary dies after a while.

I think "MUST trigger when the contract is called the first time after the canary died" is implementable

Copy link
Member

pirapira left a comment

Looks good to merge as a draft.

@pirapira pirapira merged commit 211a436 into ethereum:master Jan 2, 2018
@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Jan 2, 2018

@pirapira thanks a lot for review and merge - much appreciated!

@AtLeastSignificant

This comment has been minimized.

Copy link

AtLeastSignificant commented Jan 3, 2018

Something that occurred to me - this contract probably wouldn't require much modification to be used as a way to release funds in the case of losing control of a private key (loss/death/capture).

If the contract isn't pinged with a feed()-like transaction regularly, it automatically releases stored funds to a specific address or ENS name. Personally, I would use something like this and set the interval to be something like 1 year between feed() calls.

Would this be a new ERC or something integrated into this contract?

@superphly

This comment has been minimized.

Copy link

superphly commented Jan 4, 2018

Is there a chance to integrate a "Dead Man's Switch"? Or would that be a different interface?

@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Jan 4, 2018

@AtLeastSignificant should work - but I would see the funds-release/management in another contract that consumes/uses this interface

@superphly I think this should be directly usable as a Dead Man's Switch

@hyperfekt

This comment has been minimized.

Copy link

hyperfekt commented Jan 23, 2018

Have you given thought to integrating with Ethereum Alarm Clock for the RIP event / the Dead Man's Switch?
In general it might be useful to have contracts be able to register and be notified when the canary dies. I can imagine something similar to how Ethereum Alarm Clock works for tracking & funding these transactions. Alternatively it might be better to try and get a form of event notifications in general added to Ethereum Alarm Clock. /cc @pipermerriam

@ligi

This comment has been minimized.

Copy link
Member Author

ligi commented Jan 24, 2018

@hyperfekt sounds reasonable - but I like KISS in the beginning and getting complicated later
That said feel free to explore this path on your own - you can just implement this interface. For the use-cases I have in mind the KISS approach might even be enough and I do not think I get deep into the woods of in this area.

@lsaether

This comment has been minimized.

Copy link
Contributor

lsaether commented Jan 26, 2018

@hyperfekt I just wrote an updated canary contract for the ethereum alarm clock that is similar to what I think you're proposing. It schedules a transaction to itself every two hours and if one of the transactions fails it dies. It implements the isAlive() interface so that contracts can query it before sending an EAC transaction to make sure that the service is up.

As to your point about event notifications in the alarm clock I'm not really sure what you mean. If you'd like to join us on the Gitter chat , we are currently making some changes to the contracts and are open to ideas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.