diff --git a/Cargo.lock b/Cargo.lock
index 30b7b7f..b727216 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -61,6 +61,21 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "anstream"
 version = "0.3.2"
@@ -659,6 +674,21 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "chrono"
+version = "0.4.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "serde",
+ "wasm-bindgen",
+ "windows-targets 0.48.1",
+]
+
 [[package]]
 name = "cipher"
 version = "0.4.4"
@@ -1296,6 +1326,29 @@ dependencies = [
  "tokio-native-tls",
 ]
 
+[[package]]
+name = "iana-time-zone"
+version = "0.1.59"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "idna"
 version = "0.4.0"
@@ -1677,7 +1730,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-targets",
+ "windows-targets 0.48.1",
 ]
 
 [[package]]
@@ -2993,6 +3046,7 @@ dependencies = [
  "async-trait",
  "aws-config",
  "aws-sdk-s3",
+ "chrono",
  "clap",
  "env_logger",
  "etcd-client",
@@ -3182,7 +3236,16 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.1",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets 0.52.0",
 ]
 
 [[package]]
@@ -3191,7 +3254,7 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.1",
 ]
 
 [[package]]
@@ -3200,13 +3263,28 @@ version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
 ]
 
 [[package]]
@@ -3215,42 +3293,84 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
 
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
 
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+
 [[package]]
 name = "winnow"
 version = "0.5.15"
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8e9e2a3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,88 @@
+# Vicky
+
+Vicky consists of three services:
+- Vicky itself
+- Dashboard (The frontend)
+- Vicky runner
+
+## Dev Environment
+
+### Requirements
+
+For a dev environment we need the following services:
+- S3 endpoint
+- OIDC endpoint
+- etcd
+
+There is a Dockerfile and a nix based devenv supplied to run those.
+
+For vicky itself we ship a nix flake that provides all the dependencies.
+
+### Dashboard
+
+```
+cd dashboard
+npm start
+```
+
+Now the frontend listens at `http://localhost:1234/tasks`
+
+### Vicky
+
+Example Rocket.toml for **dev environments**:
+```toml
+[default]
+
+machines = [
+    "abc1234"
+]
+
+[default.etcd_config]
+endpoints = [ "http://localhost:2379" ]
+
+[default.s3_config]
+endpoint = "http://localhost:9000"
+access_key_id = "minio"
+secret_access_key = "aichudiKohr6aithi4ahh3aeng2eL7xo"
+region = "us-east-1"
+log_bucket = "vicky-logs"
+
+[default.oauth.github]
+provider = "GitHub"
+client_id = "CHANGEME"
+client_secret = "CHANGEME"
+redirect_uri = "http://localhost:1234/api/auth/callback/github"
+
+
+[default.users.sdinkleberg]
+full_name = "Sheldon Dinkleberg"
+role = "admin"
+```
+
+Now you can start the service running:
+```
+cargo run --bin vicky 
+```
+
+## Create a task
+
+Tasks always have a display name and a `flake_ref`.
+The `flake_ref` is a reference to a Nix flake that runs the code.
+
+Example request:
+```
+      curl -s --request POST \
+        --url http://127.0.0.1:1234/api/tasks/ \
+        --header "Authorization: abc1234" \
+        --header 'Content-Type: application/json' \
+        --data '{
+          "display_name": "ExampleTask Turn on coffee machine",
+          "locks": [],
+          "flake_ref": {
+              "flake": "github:wobcom/cosmo#generate-certs",
+              "args": []
+          }
+      }'
+```
+
+
diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json
index 060c8f3..3175518 100644
--- a/dashboard/package-lock.json
+++ b/dashboard/package-lock.json
@@ -9,6 +9,9 @@
       "version": "0.0.0",
       "license": "MIT",
       "dependencies": {
+        "@fortawesome/free-regular-svg-icons": "^6.5.1",
+        "@fortawesome/free-solid-svg-icons": "^6.5.1",
+        "@rsuite/icons": "^1.0.3",
         "@uidotdev/usehooks": "^2.4.1",
         "axios": "^1.5.0",
         "parcel": "^2.9.3",
@@ -186,6 +189,39 @@
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
       "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
     },
+    "node_modules/@fortawesome/fontawesome-common-types": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
+      "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
+      "hasInstallScript": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@fortawesome/free-regular-svg-icons": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
+      "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@fortawesome/fontawesome-common-types": "6.5.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@fortawesome/free-solid-svg-icons": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
+      "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@fortawesome/fontawesome-common-types": "6.5.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/@juggle/resize-observer": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
diff --git a/dashboard/package.json b/dashboard/package.json
index ac04f68..b9dd97d 100644
--- a/dashboard/package.json
+++ b/dashboard/package.json
@@ -15,6 +15,9 @@
   "author": "Johann Wagner <johann.wagner@wobcom>",
   "license": "MIT",
   "dependencies": {
+    "@fortawesome/free-regular-svg-icons": "^6.5.1",
+    "@fortawesome/free-solid-svg-icons": "^6.5.1",
+    "@rsuite/icons": "^1.0.3",
     "@uidotdev/usehooks": "^2.4.1",
     "axios": "^1.5.0",
     "parcel": "^2.9.3",
diff --git a/dashboard/src/components/icons.tsx b/dashboard/src/components/icons.tsx
new file mode 100644
index 0000000..43990f5
--- /dev/null
+++ b/dashboard/src/components/icons.tsx
@@ -0,0 +1,12 @@
+const FaSvgIcon = ({ faIcon, ...rest }) => {
+    const { width, height, svgPathData } = faIcon;
+    return (
+        <svg {...rest} viewBox={`0 0 ${width} ${height}`} fill="currentColor">
+            <path d={svgPathData}></path>
+        </svg>
+    );
+};
+
+export {
+    FaSvgIcon
+}
diff --git a/dashboard/src/components/menu.tsx b/dashboard/src/components/menu.tsx
index 6f2b9b8..0129edb 100644
--- a/dashboard/src/components/menu.tsx
+++ b/dashboard/src/components/menu.tsx
@@ -52,4 +52,4 @@ const Menu = () => {
 
 export {
     Menu
-}
\ No newline at end of file
+}
diff --git a/dashboard/src/components/tag.tsx b/dashboard/src/components/tag.tsx
index 80f50a5..4107ce7 100644
--- a/dashboard/src/components/tag.tsx
+++ b/dashboard/src/components/tag.tsx
@@ -58,4 +58,4 @@ const TaskTag = (props: TaskTagProps) => {
 
 export {
     TaskTag,
-}
\ No newline at end of file
+}
diff --git a/dashboard/src/components/task.tsx b/dashboard/src/components/task.tsx
index 5a728dd..be7835e 100644
--- a/dashboard/src/components/task.tsx
+++ b/dashboard/src/components/task.tsx
@@ -1,11 +1,21 @@
-import { Badge, Panel, Stack, Tag } from "rsuite";
-import { ITask } from "../services/api"
+import { Badge, Panel, Stack, Tag, Grid, Col, IconButton, Timeline } from "rsuite";
+import { ITask } from "../services/api";
 import { Terminal } from "./xterm";
 
 import * as s from "./task.module.css";
 import { useMemo } from "react";
 import { TaskTag } from "./tag";
 
+import { Icon } from '@rsuite/icons';
+import { FaSvgIcon } from "./icons";
+import * as faPen from '@fortawesome/free-solid-svg-icons/faPen';
+import * as faCalendarPlus from '@fortawesome/free-solid-svg-icons/faCalendarPlus';
+import * as faCalendarCheck from '@fortawesome/free-solid-svg-icons/faCalendarCheck';
+import * as faBusinessTime from '@fortawesome/free-solid-svg-icons/faBusinessTime';
+import * as faCarBurst from '@fortawesome/free-solid-svg-icons/faCarBurst';
+import * as faStop from '@fortawesome/free-solid-svg-icons/faStop';
+import * as faAnglesUp from '@fortawesome/free-solid-svg-icons/faAnglesUp';
+
 type TaskProps = {
     task: ITask
 }
@@ -16,9 +26,13 @@ const Task = (props: TaskProps) => {
     return (
         <Panel shaded bordered className={s.Panel}>
             <Stack justifyContent="space-between" spacing={20} className={s.TitleStack}>
-                <h4>{task.display_name}</h4>
+                { task.parent ? (
+                    <Timeline>
+                        <Timeline.Item><h4>{task.display_name}</h4></Timeline.Item>
+                    </Timeline>
+		) : <h4>{task.display_name}</h4> }
 
-                <Stack spacing={30}>
+                <Stack spacing={8}>
                     {
                         task.locks.map(lock => {
                             return (
@@ -31,6 +45,24 @@ const Task = (props: TaskProps) => {
                     <TaskTag size="lg" task={task}/>
                 </Stack>
             </Stack>
+	    <Stack spacing={8}>
+		{task.author ? <Tag color="grey"><Icon as={FaSvgIcon} faIcon={faPen} /> {task.author}{ task.creator ? " via " + task.creator : null }</Tag> : null}
+		{task.created ? <Tag color="grey"><Icon as={FaSvgIcon} faIcon={faCalendarPlus} /> Created {new Date(task.created).toLocaleString()}</Tag> : null }
+		{task.started ? <Tag color="grey"><Icon as={FaSvgIcon} faIcon={faBusinessTime} /> Started {new Date(task.started).toLocaleString()}</Tag> : null }
+		{task.closed ? <Tag color="grey">
+		    { task.status == "SUCCESS" ?
+			<Icon as={FaSvgIcon} faIcon={faCalendarCheck} />+" Finished"
+		    : task.status == "FAILED" ?
+			<Icon as={FaSvgIcon} faIcon={faCarBurst} />+" Failed"
+		    :
+			<Icon as={FaSvgIcon} faIcon={faStop} />+" Closed"
+		    }
+		    {new Date(task.created).toLocaleString()
+		}</Tag> : null }
+	    </Stack>
+	    <Stack spacing={8} style={{ marginTop: ".5em" }}>
+                {task.parent ? <IconButton color="green" appearance="primary" size="xs" key={task.parent} href={`/tasks/${task.parent}`} placement="left" icon={<Icon as={FaSvgIcon} faIcon={faAnglesUp} />}>View Parent</IconButton> : null}
+	    </Stack>
             <Terminal key={task.id} taskId={task.id} />
         </Panel>
     )
@@ -38,4 +70,5 @@ const Task = (props: TaskProps) => {
 
 export {
     Task
-}
\ No newline at end of file
+}
+
diff --git a/dashboard/src/components/tasks.tsx b/dashboard/src/components/tasks.tsx
index 02ae0e8..0c56089 100644
--- a/dashboard/src/components/tasks.tsx
+++ b/dashboard/src/components/tasks.tsx
@@ -1,6 +1,6 @@
 import { useEffect, useMemo, useState } from "react";
 import { Link, useParams } from "react-router-dom"
-import { Col, Grid, List, Panel, Row, Stack, Tag } from "rsuite"
+import { Col, Grid, List, Panel, Row, Stack, Tag, IconButton } from "rsuite"
 import { ITask, useAPI } from "../services/api";
 import { TaskTag } from "./tag";
 import { Task } from "./task";
@@ -9,6 +9,10 @@ import { Terminal } from "./xterm"
 import * as s from "./tasks.module.css";
 import { useTask, useTasks } from "../hooks/useTasks";
 
+import { Icon } from '@rsuite/icons';
+import { FaSvgIcon } from "./icons";
+import * as faPlus from '@fortawesome/free-solid-svg-icons/faPlus';
+
 const Tasks = () => {
 
     const { taskId } = useParams();
@@ -32,7 +36,14 @@ const Tasks = () => {
                                     <List.Item key={t.id} className={isSelected ? s.ListItemSelected : ""}>
                                         <Stack direction="row" justifyContent="space-between" spacing={8}>
                                             <span>{t.display_name}</span>
-                                            <TaskTag size="sm" task={t}></TaskTag>
+                                            <Stack spacing={8}>
+                                                {
+                                                    t.creator ? (
+						        <Tag color="grey">{t.creator}</Tag>
+                                                    ): null
+                                                }
+                                                <TaskTag size="sm" task={t}></TaskTag>
+                                            </Stack>
                                         </Stack>
                                     </List.Item>
                                     </Link>
diff --git a/dashboard/src/components/xterm.tsx b/dashboard/src/components/xterm.tsx
index cc6a2f4..6775a34 100644
--- a/dashboard/src/components/xterm.tsx
+++ b/dashboard/src/components/xterm.tsx
@@ -55,11 +55,11 @@ const Terminal = (props: TerminalProps) => {
 
 
     return (
-        <div style={{width: "100%", height: "calc( 100% - 48px )"}} id={name} ref={(ref) => setRef(ref)}></div>
+        <div style={{width: "100%", height: "calc( 100% - 78px )", marginTop: "1em"}} id={name} ref={(ref) => setRef(ref)}></div>
     )
 
 }
 
 export {
     Terminal
-}
\ No newline at end of file
+}
diff --git a/vicky/Cargo.toml b/vicky/Cargo.toml
index c952e82..27184b5 100644
--- a/vicky/Cargo.toml
+++ b/vicky/Cargo.toml
@@ -24,6 +24,7 @@ uuid = { version="1.4.1", features = ["fast-rng", "v4", "serde"] }
 rocket = { version="=0.5.0-rc.3", features = ["json", "secrets"] } 
 rocket_oauth2 = "0.5.0-rc.2"
 reqwest = { version="0.11.20", features = ["json"]}
+chrono = { version="0.4.31", features = ["serde"]}
 
 [[bin]]
 name = "vicky"
diff --git a/vicky/src/bin/vicky/auth.rs b/vicky/src/bin/vicky/auth.rs
index 0fa16f3..99588f4 100644
--- a/vicky/src/bin/vicky/auth.rs
+++ b/vicky/src/bin/vicky/auth.rs
@@ -23,7 +23,7 @@ pub struct User {
 }
 
 pub struct Machine {
-    
+    pub name: String
 }
 
 #[rocket::async_trait]
@@ -76,11 +76,16 @@ impl<'r> request::FromRequest<'r> for Machine {
             .expect("request Config");
 
         if let Some(auth_header) = request.headers().get_one("Authorization") {
-            let cfg_user = config.machines.iter().find(|x| *x == auth_header);
+            let cfg_user = config.machines.iter().find_map(|(name, key)| match key == auth_header {
+                true => Some(name),
+                _ => None
+            });
 
             match cfg_user {
                 Some(_) => {
-                    return request::Outcome::Success(Machine {})
+                    return request::Outcome::Success(Machine {
+                        name: cfg_user.unwrap().to_string(),
+                    })
                 },
                 None => {
                     return request::Outcome::Failure((Status::Forbidden, ()))
diff --git a/vicky/src/bin/vicky/main.rs b/vicky/src/bin/vicky/main.rs
index f8a6213..48f8e9b 100644
--- a/vicky/src/bin/vicky/main.rs
+++ b/vicky/src/bin/vicky/main.rs
@@ -55,7 +55,7 @@ pub struct S3Config {
 #[derive(Deserialize)]
 pub struct Config {
     users: HashMap<String, User>,
-    machines: Vec<String>,
+    machines: HashMap<String, String>,
 
     etcd_config: EtcdConfig,
     s3_config: S3Config,
diff --git a/vicky/src/bin/vicky/tasks.rs b/vicky/src/bin/vicky/tasks.rs
index 9e37708..114141b 100644
--- a/vicky/src/bin/vicky/tasks.rs
+++ b/vicky/src/bin/vicky/tasks.rs
@@ -1,3 +1,4 @@
+use chrono::offset::Utc;
 use etcd_client::{Client};
 use rocket::{get, post, State, serde::json::Json};
 use serde::{Deserialize, Serialize};
@@ -8,7 +9,6 @@ use std::time;
 use tokio::sync::broadcast::{error::{TryRecvError}, self};
 use rocket::{http::Status};
 
-
 use crate::{auth::{User, Machine}, errors::AppError, events::GlobalEvent};
 
 
@@ -16,6 +16,10 @@ use crate::{auth::{User, Machine}, errors::AppError, events::GlobalEvent};
 #[derive(Debug, PartialEq, Serialize, Deserialize)]
 pub struct RoTaskNew {
     display_name: String,
+    #[serde(default)]
+    author: String,
+    #[serde(default)]
+    parent: String,
     flake_ref: FlakeRef,
     locks: Vec<Lock>,
 }
@@ -142,6 +146,7 @@ pub async fn tasks_claim(etcd: &State<Client>, global_events: &State<broadcast::
         Some(next_task) => {
             let mut task = etcd.get_task(next_task.id).await?.ok_or(AppError::HttpError(Status::NotFound))?; 
             task.status = TaskStatus::RUNNING;
+            task.started = Some(Utc::now());
             etcd.put_task(&task).await?;
             global_events.send(GlobalEvent::TaskUpdate { uuid: task.id })?;
             Ok(Json(Some(task)))
@@ -158,6 +163,7 @@ pub async fn tasks_finish(id: String, finish: Json<RoTaskFinish>, etcd: &State<C
     log_drain.finish_logs(&id).await?;
 
     task.status = TaskStatus::FINISHED(finish.result.clone());
+    task.closed = Some(Utc::now());
     etcd.put_task(&task).await?;
     global_events.send(GlobalEvent::TaskUpdate { uuid: task.id })?;
 
@@ -171,6 +177,12 @@ pub async fn tasks_add(task: Json<RoTaskNew>, etcd: &State<Client>, global_event
     let task_manifest = Task { 
         id: task_uuid,
         status: TaskStatus::NEW,
+        created: Some(Utc::now()),
+        started: None,
+        closed: None,
+        author: task.author.clone(),
+        parent: task.parent.clone(),
+        creator: _machine.name,
         locks: task.locks.clone(),
         display_name: task.display_name.clone(),
         flake_ref: FlakeRef { flake: task.flake_ref.flake.clone(), args: task.flake_ref.args.clone() },
diff --git a/vicky/src/lib/documents/mod.rs b/vicky/src/lib/documents/mod.rs
index 1f2401b..dddc1a3 100644
--- a/vicky/src/lib/documents/mod.rs
+++ b/vicky/src/lib/documents/mod.rs
@@ -2,6 +2,8 @@
 use async_trait::async_trait;
 use etcd_client::GetOptions;
 use serde::{Serialize, Deserialize};
+use chrono::DateTime;
+use chrono::offset::Utc;
 
 use uuid::Uuid;
 
@@ -50,6 +52,18 @@ pub struct Task {
     pub id: Uuid,
     pub display_name: String,
     pub status: TaskStatus,
+    #[serde(default)]
+    pub created: Option<DateTime<Utc>>,
+    #[serde(default)]
+    pub started: Option<DateTime<Utc>>,
+    #[serde(default)]
+    pub closed: Option<DateTime<Utc>>,
+    #[serde(default)]
+    pub author: String,
+    #[serde(default)]
+    pub creator: String,
+    #[serde(default)]
+    pub parent: String,
     pub locks: Vec<Lock>,
     pub flake_ref: FlakeRef,
 }
@@ -84,4 +98,4 @@ impl DocumentClient for etcd_client::Client {
         kv.put_yaml(key, &task, None).await?;
         Ok(())
     }
-}
\ No newline at end of file
+}